[redis-oss] Avoid using unsafe C functions#10932
Conversation
replace use of: sprintf --> snprintf strcpy/strncpy --> strlcpy strcat/strncat --> strlcat why are we making this change? Much of the code uses some unsafe variants or deprecated buffer handling functions. While most cases are probably not presenting any issue on the known path programming errors and unterminated strings might lead to potential buffer overflows which are not covered by tests.
|
I'll add one other piece of context, which is that AFAIK Redis never uses any of these "unsafe" functions unsafely, however we are constantly contacted by folks from our internal security teams about using the unsafe functions, so I'm fairly confident other folks do as well. I know we've also had past individuals have used static analysis tools to try to find issues in Redis, and I know these are often flagged and end up being false positives. The main benefit I see is that in the future people will be nudged towards the correct functions. |
oranagra
left a comment
There was a problem hiding this comment.
just to note again (what was already note in some way):
many of these changes are to test code that's not really part of the normal redis build.
and the ones that are in real redis code seem bug free to me too.
i do agree we wanna do this step towards eliminating static analysis warnings.
1. some limits for strlcpy were not modified to copy length 2. revert use of snprintf and use strlcat in rdbRemoveTempFile since it is called on signal handler
@oranagra I agree there is no bug in the current use of these functions. the main Idea with this PR (while it was initiated by a static analyzer warning) is to also make sure no future use will be done using these functions, since there is no visible reason to do so. |
|
we do already have one static analyzer running as part of the CI, maybe we can extend that and add others. |
1. fix some spaces in command arguments 2. place all strl* implementations in separate c file strl.c 3. remove handling of theoretical pid 2 string error
oranagra
left a comment
There was a problem hiding this comment.
other than some minor changes, LGTM.
Co-authored-by: sundb <[email protected]>
Co-authored-by: sundb <[email protected]>
oranagra
left a comment
There was a problem hiding this comment.
LGTM.
@ranshid please mention the changes we did to ll2string etc in the PR top comment.
i.e. explain that we added a null term in the error case just in case some caller (like rdbRemoveTempFile) doesn't check the error and assumes the string has some null term.
please go over all the changes and see if there's anything else worth mentioning.
@yossigo i'd like you to take a quick look (mainly at the copied code, makefile, and pragmas)
@oranagra I updated the PR top comment. take a look if you like and tell me if that is O.K now. |
replace use of: sprintf --> snprintf strcpy/strncpy --> redis_strlcpy strcat/strncat --> redis_strlcat **why are we making this change?** Much of the code uses some unsafe variants or deprecated buffer handling functions. While most cases are probably not presenting any issue on the known path programming errors and unterminated strings might lead to potential buffer overflows which are not covered by tests. **As part of this PR we change** 1. added implementation for redis_strlcpy and redis_strlcat based on the strl implementation: https://linux.die.net/man/3/strl 2. change all occurrences of use of sprintf with use of snprintf 3. change occurrences of use of strcpy/strncpy with redis_strlcpy 4. change occurrences of use of strcat/strncat with redis_strlcat 5. change the behavior of ll2string/ull2string/ld2string so that it will always place null termination ('\0') on the output buffer in the first index. this was done in order to make the use of these functions more safe in cases were the user will not check the output returned by them (for example in rdbRemoveTempFile) 6. we added a compiler directive to issue a deprecation error in case a use of sprintf/strcpy/strcat is found during compilation which will result in error during compile time. However keep in mind that since the deprecation attribute is not supported on all compilers, this is expected to fail during push workflows. **NOTE:** while this is only an initial milestone. We might also consider using the *_s implementation provided by the C11 Extensions (however not yet widly supported). I would also suggest to start looking at static code analyzers to track unsafe use cases. For example LLVM clang checker supports security.insecureAPI.DeprecatedOrUnsafeBufferHandling which can help locate unsafe function usage. https://clang.llvm.org/docs/analyzer/checkers.html#security-insecureapi-deprecatedorunsafebufferhandling-c The main reason not to onboard it at this stage is that the alternative excepted by clang is to use the C11 extensions which are not always supported by stdlib.
replace use of:
sprintf --> snprintf
strcpy/strncpy --> redis_strlcpy
strcat/strncat --> redis_strlcat
why are we making this change?
Much of the code uses some unsafe variants or deprecated buffer handling
functions.
While most cases are probably not presenting any issue on the known path
programming errors and unterminated strings might lead to potential
buffer overflows which are not covered by tests.
As part of this PR we change
NOTE: while this is only an initial milestone. We might also consider
using the *_s implementation provided by the C11 Extensions (however not
yet widly supported). I would also suggest to start
looking at static code analyzers to track unsafe use cases.
For example LLVM clang checker supports security.insecureAPI.DeprecatedOrUnsafeBufferHandling
which can help locate unsafe function usage.
https://clang.llvm.org/docs/analyzer/checkers.html#security-insecureapi-deprecatedorunsafebufferhandling-c
The main reason not to onboard it at this stage is that the alternative
excepted by clang is to use the C11 extensions which are not always
supported by stdlib.