-
Notifications
You must be signed in to change notification settings - Fork 56
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
[RFC] [DON'T MERGE YET] Make crypt and crypt_gensalt use thread-local output buffers. #62
base: develop
Are you sure you want to change the base?
Conversation
Oh good, running valgrind on our test suite does detect the memory leak that this introduces. :-) |
Mhh… Is there any chance to abuse |
Codecov Report
@@ Coverage Diff @@
## develop #62 +/- ##
==========================================
- Coverage 96.46% 96.4% -0.06%
==========================================
Files 32 32
Lines 3109 3119 +10
==========================================
+ Hits 2999 3007 +8
- Misses 110 112 +2
Continue to review full report at Codecov.
|
@zackw I've just pushed a possible abuse of |
I am not sure that I understand the point of this change. Current situation:
After this patch:
So this change would force long-lived daemons to use a different API while providing no obvious real world benefits. |
@besser82 I was looking into just that this afternoon and I believe I know how to do it in a more universally supported way - the only wrinkle being that one file will need to be compiled as C++, which is enough of a wrinkle that I'm not gonna get to it this week, probably. (If I do it right, libcrypt.so will not require libstdc++.so at runtime.) @rfc1036 The primary motivation for this change is to match what Solaris already does, and what has been proposed to be done in glibc with all the other APIs that have static internal buffers. See the thread I linked to at the beginning. A secondary motivation is to reduce the size of libcrypt.so's BSS. That said, I'm certainly open to the possibility that it's not worth bothering with. |
@zackw Wouldn't that imply we need to link |
No. The short version is that the particular C++ feature needed for this (a
I feel like we may wind up going there eventually (for instance, I think I will need |
73c6aeb
to
c368077
Compare
Resolved merge conflicts. |
60aa1f5
to
d24e7ce
Compare
This change makes crypt and crypt_gensalt as thread-safe as they can be without changing their interfaces. Solaris already made this change, and it’s being discussed by glibc (with suggestion that it should be pushed upstream to the C and POSIX standards committees): https://sourceware.org/ml/libc-alpha/2018-10/msg00437.html Portable programs should still use the r-variants, though, because this is not a guaranteed feature, it doesn’t make them not clobber their output buffers on a second call, and the tradeoff is a sizeable memory leak (CRYPT_GENSALT_OUTPUT_SIZE or sizeof(crypt_data)) for each thread that calls either function. (Thanks ever so much, C committee, for adding thread-local variables without destructors for them.) (I’m still investigating whether there’s some GNU extension we could use to avoid the memory leak at least on Linux.) (We could use pthread_getspecific, but then we’d have to link libcrypt with libpthread, and this doesn’t seem like enough reason to do that.)
d24e7ce
to
ebfc697
Compare
Rebased on recent |
I think this is a questionable feature, primarily because portable programs must not rely on it anyway, and then there's risk of someone porting system-specific code e.g. from Fedora to another system and not realizing they need to revise the uses of crypt*(). There's already such risk with ports from Solaris, but I think that's a poor excuse for making the matter worse. I wouldn't merge this unless and until glibc actually makes similar changes across the board. |
I like the NEWS file's wording "This feature is a safety net against sloppy coding. Programs are still strongly encouraged to use the reentrant functions instead". I think the man page's wording should be similar. As currently proposed, I think the man page doesn't sufficiently discourage reliance on the thread-safety. I think we should discourage such reliance even in non-portable programs. |
Unfortunately Given this fact and the very likely need for |
Anyways, looking at the code from (Open)Solaris their implementation of thread-safety in the |
Here is an overview of what got changed by this pull request: Issues
======
+ Solved 7
- Added 4
See the complete overview on Codacy |
if (strlen (hash) + 1 > sizeof save_hash) | ||
{ | ||
printf ("ERROR: crypt output is too long (%zu > %zu)\n", | ||
strlen (hash) + 1, sizeof save_hash); |
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.
} | ||
else | ||
printf ("ok: parent: crypt_gensalt = %s\n", setting); | ||
if (strlen (setting) + 1 > sizeof save_setting) |
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.
if (strlen (setting) + 1 > sizeof save_setting) | ||
{ | ||
printf ("ERROR: crypt_gensalt output is too long (%zu > %zu)\n", | ||
strlen (setting) + 1, sizeof save_setting); |
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.
} | ||
else | ||
printf ("ok: parent: crypt = %s\n", hash); | ||
if (strlen (hash) + 1 > sizeof save_hash) |
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.
They do use |
This change makes crypt and crypt_gensalt as thread-safe as they can be without changing their interfaces. Solaris already made this change, and it’s being discussed by glibc (with suggestion that it
should be pushed upstream to the C and POSIX standards committees): https://sourceware.org/ml/libc-alpha/2018-10/msg00437.html
Portable programs should still use the r-variants, though, because this is not a guaranteed feature, it doesn’t make them not clobber their output buffers on a second call, and the tradeoff is a sizeable
memory leak (CRYPT_GENSALT_OUTPUT_SIZE or sizeof(crypt_data)) for each thread that calls either function. (Thanks ever so much, C committee, for adding thread-local variables without destructors for them.) (I’m still investigating whether there’s some GNU extension we could use to avoid the memory leak at least on Linux.) (We could use pthread_getspecific, but then we’d have to link libcrypt with libpthread, and this doesn’t seem like enough reason to do that.)
I'd like comments on this, but please don't merge it yet; the memory leak is a scary cost and I would like to be sure there's really no way to avoid it before merging this as-is.
(On the up side, this change shrinks libcrypt.so's .bss segment from 33160 to 192 bytes, which is a nice savings for programs that don't use these functions.)