-
Notifications
You must be signed in to change notification settings - Fork 1.1k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
SR-7112: Fixed access to memory out of range #1498
SR-7112: Fixed access to memory out of range #1498
Conversation
It seems that this is a fix for https://bugs.swift.org/browse/SR-7112, right? |
Exactly! This PR is a solution to that issue. |
3fc19a8
to
222eb37
Compare
@swift-ci please test |
1 similar comment
@swift-ci please test |
I'm trying to trace this through from the original bug report but I'm having trouble figuring out why we end up out of bounds here in the first place. The string is |
If this is a recent failure, it may be related to @milseman 's string changes... |
@parkera When I had a look at this issue it seemed to be triggered with 16 (ASCII) character strings, I wonder if its related to a short string optimisation? It can be triggered by running the TestFoundation tests under Xcode, so it might be the malloc checker looking at overflows of 16byte allocations - I guess on linux the minimum malloc size is > 16 so its not triggered in the tests. |
Note that small strings landed last week, but that bug report is from a month ago. |
Is it possible to re-create this failure without the JSON bit in particular? I tried a bit on Darwin to get it to happen but couldn't - which makes me wonder about the |
This is reproduced with this code. This problem occurs when giving an ASCII string of multiples of 16. _ = ("1234567890123456" as NSString).data(using: String.Encoding.utf8.rawValue) There is a problem reading the end of the character string pointed to by pointer Do you think there is another cause? |
Near as I can tell, corelibs-foundation's implementation of |
Ok, I see now. You're right that Therefore, unfortunately, the right fix to this bug is to do what you originally suggested and return |
@parkera I think Swift's String should always over-allocate to guarantee nul-termination for ASCII. Does the UTF-16 version, These of course won't work for slices, nor for Strings containing nul. Would Swift need to remember whether its ever stored an internal nul character? Do you know why they don't just return both a pointer and a length? I could imagine many uses might follow up with a strlen call anyways, and often the length is known. |
It looks like In
|
I see, and are you careful to track whether the string happened to store a NUL character in the middle? Or do you just return the pointer, leaving the behavior surrounding an interior NUL up to the caller? (Personally, I find the second option more tenable) |
@parkera You are absolutely right. However, I think that we should carefully change My main point is that I would like to quickly improve the situation where the test abnormally ends for those who want to contribute using macOS/Xcode. |
There is clearly a logical change in this code, otherwise it wouldn't fix the issue. The root cause is that Right now we have a signal that shows the true problem. Changing this code seems fine, but it papers over the underlying issue and will give us a false sense of confidence that we've fixed the issue. We can take the time to dig to the bottom of why the test is failing and fix it once. |
A cheap way to fix the |
…ithout null termination Changed _fastCStringContents (used in CFStringGetCStringPtr) to return NULL if required to return a string containing null termination. Since this fix, if you call CFStringGetCStringPtr with a Swift-based CFString, it returns NULL. Before the change: _fastCStringContents always returned a pointer to an ASCII string containing no NULL termination. This is because the code was using unsafeBitCast to get internal pointer of String of Swift. Swift's string does not guarantee null termination.
I understand. Ok, I've changed it so that it simply returns NULL if the argument is True. I was concerned about changing the behavior of the existing code, but it is better than leaving the root cause. Note that in this case I think that it is correct to return NULL, as it is written in the document (although it is Darwin's
Thanks |
222eb37
to
b56140a
Compare
Can you file a bug against String to over-allocate by 1 code unit for its storage? edit: hyperlinking |
@milseman Do you mean there is no null terminator in Swift's internal string storage? Unfortunately, I can not report about it. I think that there is no problem even if it does not exist, because It is not necessary for Swift. Also I think that |
It's generally useful in the ASCII case for things like |
The pointer obtained with |
Edit: Ignore my comment below :-) I have not analyzed this crash very deeply so I'm sorry for the noise... I'm just wondering if it is always safe to dereference ptr here? When the crash happens for me, rangeLen and uninterestingTailLen are both 0. while (rangeLen > uninterestingTailLen && *ptr < 0x80) { |
@nevil At first I was doing the same patch as you. However, I accepted and withdrew the opinion that the root cause should be fixed. Since there is a log, I will skip the details. |
Let's get this merged! |
@swift-ci please test and merge |
Fixed the code accessing outside the range of the character string.
When running the test in Xcode, Guard Malloc (libgmalloc) detected it and caused a runtime error.