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

Codechange: Limit field width to avoid sscanf crash #8017

Merged
merged 1 commit into from Feb 23, 2020

Conversation

Quipyowert2
Copy link
Contributor

According to Cppcheck, "sscanf() without field width limits can crash with huge input data."

I added a field width of 127 since cp->text is a buffer of size 32 * MAX_CHAR_LENGTH (src/command_type.h:483) where MAX_CHAR_LENGTH = 4 (src/strings_type.h:18), so a total length of 128. Cppcheck recommends to subtract one from the field width to leave room for the null byte at the end of the buffer.

Cppcheck error below:

[D:/Linux_home/nathan/src/OpenTTD/src/network/network.cpp:920] (warning) sscanf() without field width limits can crash with huge input data. Add a field width specifier to fix this problem.

Sample program that can crash:

#include <stdio.h>
int main()
{
    char c[5];
    scanf("%s", c);
    return 0;
}

Typing in 5 or more characters may make the program crash. The correct usage here is 'scanf("%4s", c);', as the maximum field width does not include the terminating null byte.
Source: http://linux.die.net/man/3/scanf
Source: http://www.opensource.apple.com/source/xnu/xnu-1456.1.26/libkern/stdio/scanf.c [invalidscanf]```

@nielsmh
Copy link
Contributor

nielsmh commented Feb 21, 2020

Looks like this happens in a rarely-exercised piece of code, only used in network command logging-enabled builds. It looks correct, but I think I'd prefer if the buffer length in the format string was either taken from the actual field size, or at least had a static_assert check before the sscanf() that would fail if the buffer size ever changes.

@Quipyowert2
Copy link
Contributor Author

I changed the field width to be calculated based on the size of cp->text minus one but now gcc complains that it isn't a string literal so the format won't be checked.

@LordAro
Copy link
Member

LordAro commented Feb 22, 2020

Yeah, that's not a better solution - go with the static_assert method (or in OTTD world, assert_compile) instead

@Quipyowert2
Copy link
Contributor Author

Ok, I changed it to use assert_compile and changed the field width back to %127.

@LordAro LordAro merged commit d1b7eb2 into OpenTTD:master Feb 23, 2020
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.

None yet

3 participants