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
[Windows] CFThreadSpecific implementation allows access to deallocated value #2764
Conversation
@@ -1416,8 +1434,15 @@ void _CFThreadSpecificSet(_CFThreadSpecificKey key, CFTypeRef _Nullable value) { | |||
#if TARGET_OS_WIN32 | |||
if (value != NULL) { | |||
swift_retain((void *)value); | |||
|
|||
_CFThreadSpecificData *data = malloc(sizeof(_CFThreadSpecificData)); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This can fail, please ensure that data is valid or abort.
|
||
FlsSetValue(key, data); | ||
} else { | ||
FlsSetValue(key, NULL); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This may cause a leak, and worse a crash - you may have had an entry and you lost it.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Oh, this is definitely a leak. Thanks!
I wonder how does it work for Swift value we store here? We are not doing swift_release
for previously stored object when overwriting it. But it not leaks, as far as I see.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This isn't resolved. The problem is that you are now injecting a value that you are de-referencing rather than previously which was passed to free
or swift_release
which accept and ignore NULL
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You're right, by bad :(
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done
27bd58d
to
62fd956
Compare
|
As for my question about missing
|
@@ -1415,9 +1433,23 @@ CFTypeRef _Nullable _CFThreadSpecificGet(_CFThreadSpecificKey key) { | |||
void _CFThreadSpecificSet(_CFThreadSpecificKey key, CFTypeRef _Nullable value) { | |||
#if TARGET_OS_WIN32 | |||
if (value != NULL) { | |||
_CFThreadSpecificData *oldData = (_CFThreadSpecificData *)FlsGetValue(key); | |||
if (oldData) { | |||
free(oldData); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Probably should add a comment explaining that the value should not be freed here.
|
||
FlsSetValue(key, data); | ||
} else { | ||
FlsSetValue(key, NULL); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This isn't resolved. The problem is that you are now injecting a value that you are de-referencing rather than previously which was passed to free
or swift_release
which accept and ignore NULL
.
…d value Unlike pthread-based implementation, TLS/FLS on Windows doesn't return NULL when reading value after destructor call. To avoid that we have to nullify value in destructor callback. The implementation needs to store key along with user data to perform proper cleanup.
62fd956
to
511f6c9
Compare
@swift-ci please test Linux platform |
@swift-ci please test Linux platform |
Please test with following PRs: |
Unlike pthread-based implementation, TLS/FLS on Windows doesn't return NULL when reading value after destructor call.
To avoid that we have to nullify value in destructor callback.
The implementation needs to store key along with user data to perform proper cleanup.
This fixes crashes in
NotificationQueue
andOperationQueue
on Windows.Also introduced small delay in helper func of
TestNotificationQueue
to avoid false positive/false negative results intest_defaultQueue
andtest_notificationQueueLifecycle
.