-
Notifications
You must be signed in to change notification settings - Fork 52
Reduce strerror and errno usage #346
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
Conversation
mod->file = kmod_file_open(mod->ctx, path); | ||
if (mod->file == NULL) { | ||
err = -errno; | ||
err = kmod_file_open(mod->ctx, path, &mod->file); |
Check failure
Code scanning / CodeQL
Uncontrolled data used in path expression High
user input (an environment variable)
This argument to a file access function is derived from
user input (string read by getdelim)
This argument to a file access function is derived from
user input (string read by getdelim)
((struct kmod_module *)mod)->file = kmod_file_open(mod->ctx, path); | ||
if (mod->file == NULL) | ||
return NULL; | ||
ret = kmod_file_open(mod->ctx, path, &((struct kmod_module *)mod)->file); |
Check failure
Code scanning / CodeQL
Uncontrolled data used in path expression High
user input (an environment variable)
This argument to a file access function is derived from
user input (string read by getdelim)
This argument to a file access function is derived from
user input (string read by getdelim)
The code-base is somewhat inconsistent - some places use "if (ret < 0)" others simply "if (ret)". I've tried to follow the surrounding pattern with the new patches, although I don't have a strong preference either way. |
libkmod/libkmod-file.c
Outdated
|
||
file->fd = open(filename, O_RDONLY | O_CLOEXEC); | ||
if (file->fd < 0) { | ||
free(file); | ||
return NULL; | ||
return -ENOMEM; |
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.
ENOMEM here doesn't feel right. However using the errno from open() after the free() is also invalid. Options: a) add a local saved_errno in the error path so you can return it; b) annotate file with cleanup_free, and assign it to NULL after setting *out_file. Approach (b) would allow to remove one more free() call in the error path.
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.
using the errno from open() after the free() is also invalid
Not sure I follow - why is it invalid? The free() call should never alter errno... does it?
Either way, option b) applied. Thanks for the review.
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.
Not sure I follow - why is it invalid? The free() call should never alter errno... does it?
humn.. true
Either way, option b) applied. Thanks for the review.
thanks
Currently, the function will report the exact same issue twice. Where the second DBG() and the error code returned, should highlight the (potential) stat(2) failure. Signed-off-by: Emil Velikov <emil.l.velikov@gmail.com>
The manual page of strerror() outlines a number of caveats wrt its usage. Swap for the GNU specific %m printf modifier (also supported on musl and bionic), which side-steps the issues as much as possible. Co-authored-by: Cristian Rodríguez <cristian@rodriguez.im> [emil: split from larger patch, convert more instances to %m] Signed-off-by: Emil Velikov <emil.l.velikov@gmail.com>
Currently we reset errno prior to calling strto{u,}l(). This is not needed, since a) we don't check errno to see if the function was successful and b) we explicitly propagate the error code by returning it directly to the caller. Reference: kmod-project#244 Signed-off-by: Emil Velikov <emil.l.velikov@gmail.com>
Currently we reset errno, shortly to be followed by an fcntl() and gzdopen() calls. Both of those should set errno on failure and preserve it on success. Just leave errno as-is, we shouldn't be changing it in this context. Reference: kmod-project#244 Signed-off-by: Emil Velikov <emil.l.velikov@gmail.com>
The single caller of add_param() does not need the struct param*, so we might as well return the error code directly. As a result we don't manually overwrite errno. Reference: kmod-project#244 Signed-off-by: Emil Velikov <emil.l.velikov@gmail.com>
Change the function signature (bool -> int) and directly return the error code. Thus we no longer need to overwrite errno. v2: - return false -> return -ENAMETOOLONG Reference: kmod-project#244 Signed-off-by: Emil Velikov <emil.l.velikov@gmail.com>
Currently our wrapper init_module() will happily return success whenever libkmod fails. While such failures are unlikely, our wrapper should also fail. In part so it doesn't mask a potentially deeper problem and in part because the kmod API used, will set errno... Something a normal syscall wouldn't do AFAICT. v2: - remove the respective comment Signed-off-by: Emil Velikov <emil.l.velikov@gmail.com>
The function does bounds checking, allocation and copying. In the first instance, we manually set errno (to ENOMEM?) on failure. The realloc() call does the same, implicitly. In practice we don't distinguish between the two failures, so we might as well stop manually setting errno and always assume ENOMEM in the caller. Reference: kmod-project#244 Signed-off-by: Emil Velikov <emil.l.velikov@gmail.com>
As per the manual getdelim(3): The buffer is null-terminated and ... Remove the local check and inline the function call. As a nice result, we no longer set the errno and the context of feof() is obvious. Reference: kmod-project#244 Signed-off-by: Emil Velikov <emil.l.velikov@gmail.com>
Rework the function signature and return the error code instead of the stripped module. Thus we no longer explicitly set errno. Reference: kmod-project#244 Signed-off-by: Emil Velikov <emil.l.velikov@gmail.com>
In practise none of our code-paths will use a NULL pointer so we might as well enforce that. To stay aligned with the kernel behaviour update our init_module() preload library to return EFAULT... Should we get confused and pass NULL in the future. Signed-off-by: Emil Velikov <emil.l.velikov@gmail.com>
The function returns what is considered constant data and all the callers handle it as such. Add the declaration to make things obvious. Signed-off-by: Emil Velikov <emil.l.velikov@gmail.com>
Rework the function signature and return the error code instead of the stripped module. Thus we no longer explicitly set errno. Reference: kmod-project#244 Signed-off-by: Emil Velikov <emil.l.velikov@gmail.com>
Rework the function signature and return the error code instead of the stripped module. Thus we no longer explicitly set errno. v2: - kmod_file_open() - use _cleanup_free_, return errno instead of ENOMEM Reference: kmod-project#244 Signed-off-by: Emil Velikov <emil.l.velikov@gmail.com>
Currently, the function will report the exact same issue twice. Where the second DBG() and the error code returned, should highlight the (potential) stat(2) failure. Signed-off-by: Emil Velikov <emil.l.velikov@gmail.com> Link: #346 Signed-off-by: Lucas De Marchi <lucas.de.marchi@gmail.com>
The manual page of strerror() outlines a number of caveats wrt its usage. Swap for the GNU specific %m printf modifier (also supported on musl and bionic), which side-steps the issues as much as possible. Co-authored-by: Cristian Rodríguez <cristian@rodriguez.im> [emil: split from larger patch, convert more instances to %m] Signed-off-by: Emil Velikov <emil.l.velikov@gmail.com> Link: #346 Signed-off-by: Lucas De Marchi <lucas.de.marchi@gmail.com>
Currently we reset errno prior to calling strto{u,}l(). This is not needed, since a) we don't check errno to see if the function was successful and b) we explicitly propagate the error code by returning it directly to the caller. Reference: #244 Signed-off-by: Emil Velikov <emil.l.velikov@gmail.com> Link: #346 Signed-off-by: Lucas De Marchi <lucas.de.marchi@gmail.com>
Currently we reset errno, shortly to be followed by an fcntl() and gzdopen() calls. Both of those should set errno on failure and preserve it on success. Just leave errno as-is, we shouldn't be changing it in this context. Reference: #244 Signed-off-by: Emil Velikov <emil.l.velikov@gmail.com> Link: #346 Signed-off-by: Lucas De Marchi <lucas.de.marchi@gmail.com>
The single caller of add_param() does not need the struct param*, so we might as well return the error code directly. As a result we don't manually overwrite errno. Reference: #244 Signed-off-by: Emil Velikov <emil.l.velikov@gmail.com> Link: #346 Signed-off-by: Lucas De Marchi <lucas.de.marchi@gmail.com>
Change the function signature (bool -> int) and directly return the error code. Thus we no longer need to overwrite errno. v2: - return false -> return -ENAMETOOLONG Reference: #244 Signed-off-by: Emil Velikov <emil.l.velikov@gmail.com> Link: #346 Signed-off-by: Lucas De Marchi <lucas.de.marchi@gmail.com>
Currently our wrapper init_module() will happily return success whenever libkmod fails. While such failures are unlikely, our wrapper should also fail. In part so it doesn't mask a potentially deeper problem and in part because the kmod API used, will set errno... Something a normal syscall wouldn't do AFAICT. v2: - remove the respective comment Signed-off-by: Emil Velikov <emil.l.velikov@gmail.com> Link: #346 Signed-off-by: Lucas De Marchi <lucas.de.marchi@gmail.com>
The function does bounds checking, allocation and copying. In the first instance, we manually set errno (to ENOMEM?) on failure. The realloc() call does the same, implicitly. In practice we don't distinguish between the two failures, so we might as well stop manually setting errno and always assume ENOMEM in the caller. Reference: #244 Signed-off-by: Emil Velikov <emil.l.velikov@gmail.com> Link: #346 Signed-off-by: Lucas De Marchi <lucas.de.marchi@gmail.com>
As per the manual getdelim(3): The buffer is null-terminated and ... Remove the local check and inline the function call. As a nice result, we no longer set the errno and the context of feof() is obvious. Reference: #244 Signed-off-by: Emil Velikov <emil.l.velikov@gmail.com> Link: #346 Signed-off-by: Lucas De Marchi <lucas.de.marchi@gmail.com>
In practise none of our code-paths will use a NULL pointer so we might as well enforce that. To stay aligned with the kernel behaviour update our init_module() preload library to return EFAULT... Should we get confused and pass NULL in the future. Signed-off-by: Emil Velikov <emil.l.velikov@gmail.com> Link: #346 Signed-off-by: Lucas De Marchi <lucas.de.marchi@gmail.com>
The function returns what is considered constant data and all the callers handle it as such. Add the declaration to make things obvious. Signed-off-by: Emil Velikov <emil.l.velikov@gmail.com> Link: #346 Signed-off-by: Lucas De Marchi <lucas.de.marchi@gmail.com>
Rework the function signature and return the error code instead of the stripped module. Thus we no longer explicitly set errno. v2: - kmod_file_open() - use _cleanup_free_, return errno instead of ENOMEM Reference: #244 Signed-off-by: Emil Velikov <emil.l.velikov@gmail.com> Link: #346 Signed-off-by: Lucas De Marchi <lucas.de.marchi@gmail.com>
Applied, thanks. |
Originally inspired by #244, with some commit (fragments) from #336 and #343
Tl:Dr: we no longer manually set
errno
but propagate the error code manually, iff needed. In addition most (but not all) of ourstrerror()
usage is replaced by%m
.As a nice side-effect the size of libkmod.so (should also be applicable for the tools) has decreased:
text data bss dec hex filename
116099 2224 8 118331 1ce3b before//libkmod.so
115685 2224 8 117917 1cc9d after/libkmod.so
NOTE: the PR also includes a few related bug fixes of varying severity. Happy to flesh them out into separate PR/PRs if that helps.