-
Notifications
You must be signed in to change notification settings - Fork 41
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
Fix potential security vulnerability #260
Conversation
Please squash the commit and add appropriate commit message. If possible avoid adding pictures in PRs but instead describe in your own words the issue at hand and how the commit addresses it. Personally I am not worried about any security implications, since to trigger a specially crafted input file which is available in root-only location. |
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.
Adding sprintf
and a variable instead of fixed format string rises more red flags than an sscanf
for all these static code scanners. ;)
tools/static-nodes.c
Outdated
matches = | ||
sscanf(buf, "%s %s %c%u:%u", modname, devname, &type, &maj, &min); | ||
sscanf(buf, format, modname, devname, &type, &maj, &min); |
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.
The usage of sscanf(... "%s")
is not a general security issue. The input string must be long enough to overflow the target buffer. This means that buf
must be larger than modname
or devname
.
Realistically, all Linux systems these days have a PATH_MAX
of 4096. To make this code robust, it would be easiest to declare buf
with PATH_MAX
instead of 4096
. That would be an adjustment of exactly one line of code and no binary change.
Proof of Concept about sscanf safety:
#include <stdio.h>
#include <string.h>
int
main(int argc, char *argv[])
{
char buf[4096], buf2[4096];
memset(buf, 'A', sizeof(buf));
buf[sizeof(buf) - 1] = '\0';
sscanf(buf, "%s", &buf2);
return 0;
}
So I would prefer if we apply this patch instead:
diff --git a/tools/static-nodes.c b/tools/static-nodes.c
index cb8afd3..d7557f4 100644
--- a/tools/static-nodes.c
+++ b/tools/static-nodes.c
@@ -144,7 +144,7 @@ static void help(void)
static int do_static_nodes(int argc, char *argv[])
{
struct utsname kernel;
- char modules[PATH_MAX], buf[4096];
+ char modules[PATH_MAX], buf[PATH_MAX];
const char *output = "/dev/stdout";
FILE *in = NULL, *out = NULL;
const struct static_nodes_format *format = &static_nodes_format_human;
tools/static-nodes.c
Outdated
@@ -252,8 +252,10 @@ static int do_static_nodes(int argc, char *argv[]) | |||
if (buf[0] == '#') | |||
continue; | |||
|
|||
char format[22]; | |||
sprintf(format, "%%%ds %%%ds %%c%%u:%%u", PATH_MAX - 1, PATH_MAX - 1); |
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 this commit is about protecting us against a PATH_MAX
which is not 4096, then this sprintf
call is actually dangerous. You could overflow the format
buffer if PATH_MAX is sufficiently large.
Yet it's also just theoretical. A system with such a huge PATH_MAX
would probably not compile the code at all because the compiler can already figure out that the stack wouldn't be large enough for all these variables which are declared like char buf[PATH_MAX]
etc.
So let's go with the simple diff I've recommended. Avoids introduction of yet another sprintf
call.
7cd5fa6
to
13f9a5f
Compare
Hello, thank you for the replies @stoeckmann and @evelikov. I fully understand and agree with the concerns about the new |
@GraysonNocera cannot see a commit message which explains the problem and/or solution. Check through |
This fix adresses the issue described in the pull request. Using a CodeQL query, I discovered that the destination of a `sscanf` call could overflow. Thus, we bound the buffer size to be PATH_MAX, to ensure that it is not larger than `modname` or `devname`. Signed-off-by: Tobias Stoeckmann Link: kmod-project#260 Reviewed-by: Emil Velikov <[email protected]>
13f9a5f
to
998bace
Compare
Added a more descriptive commit message |
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.
Thanks, updated commit looks good IMHO.
Codecov ReportAttention: Patch coverage is
|
@GraysonNocera a few things:
|
Using a CodeQL query, I discovered that the destination of a `sscanf` call could overflow. Thus, we bound the buffer size to be PATH_MAX, to ensure that it is not larger than `modname` or `devname`. Signed-off-by: Grayson Nocera <[email protected]> Suggested-by: Tobias Stoeckmann <[email protected]> Link: kmod-project#260 Reviewed-by: Emil Velikov <[email protected]>
998bace
to
6b00f05
Compare
Updated commit message @lucasdemarchi |
Using a CodeQL query, I discovered that the destination of a `sscanf` call could overflow. Thus, we bound the buffer size to be PATH_MAX, to ensure that it is not larger than `modname` or `devname`. Signed-off-by: Grayson Nocera <[email protected]> Suggested-by: Tobias Stoeckmann <[email protected]> Link: #260 Reviewed-by: Emil Velikov <[email protected]> Signed-off-by: Lucas De Marchi <[email protected]>
Applied, thanks. |
Hello, I was running some CodeQL queries on this project when I came across a potential unbounded write that could cause buffer overflow. I have implemented the fix in this PR.