Skip to content
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

Closed
wants to merge 1 commit into from

Conversation

GraysonNocera
Copy link
Contributor

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.

Screenshot 2024-11-23 at 3 09 23 PM

@evelikov
Copy link
Collaborator

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.

Copy link
Contributor

@stoeckmann stoeckmann left a 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. ;)

matches =
sscanf(buf, "%s %s %c%u:%u", modname, devname, &type, &maj, &min);
sscanf(buf, format, modname, devname, &type, &maj, &min);
Copy link
Contributor

@stoeckmann stoeckmann Nov 25, 2024

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;

@@ -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);
Copy link
Contributor

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.

@GraysonNocera
Copy link
Contributor Author

Hello, thank you for the replies @stoeckmann and @evelikov. I fully understand and agree with the concerns about the new sprintf. I have squashed the commits and implemented the one-line fix.

@evelikov
Copy link
Collaborator

@GraysonNocera cannot see a commit message which explains the problem and/or solution. Check through git log for examples.

GraysonNocera added a commit to GraysonNocera/kmod that referenced this pull request Nov 30, 2024
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]>
@GraysonNocera
Copy link
Contributor Author

@GraysonNocera cannot see a commit message which explains the problem and/or solution. Check through git log for examples.

Added a more descriptive commit message

Copy link
Collaborator

@evelikov evelikov left a 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.

Copy link

codecov bot commented Dec 5, 2024

Codecov Report

Attention: Patch coverage is 0% with 1 line in your changes missing coverage. Please review.

Files with missing lines Patch % Lines
tools/static-nodes.c 0.00% 1 Missing ⚠️
Files with missing lines Coverage Δ
tools/static-nodes.c 0.00% <0.00%> (ø)

@lucasdemarchi
Copy link
Contributor

@GraysonNocera a few things:

  • It's not appropriate to add a Signed-off-by from someone else. The first Signed-off-by should match the author of the patch. So I think what you want is:
Signed-off-by: Grayson Nocera <[email protected]>
Suggested-by: Tobias Stoeckmann <[email protected]>
  • "This fix adresses the issue described in the pull request." is unneeded redirection. : the commit message should describe the issue rather than point to the pull request. It looks like the rest of the commit message already describes it so you can drop the first part.

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]>
@GraysonNocera
Copy link
Contributor Author

GraysonNocera commented Dec 20, 2024

@GraysonNocera a few things:

  • It's not appropriate to add a Signed-off-by from someone else. The first Signed-off-by should match the author of the patch. So I think what you want is:
Signed-off-by: Grayson Nocera <[email protected]>
Suggested-by: Tobias Stoeckmann <[email protected]>
  • "This fix adresses the issue described in the pull request." is unneeded redirection. : the commit message should describe the issue rather than point to the pull request. It looks like the rest of the commit message already describes it so you can drop the first part.

Updated commit message @lucasdemarchi

lucasdemarchi pushed a commit that referenced this pull request Jan 3, 2025
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]>
@lucasdemarchi
Copy link
Contributor

Applied, thanks.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants