Skip to content

gh-112301: Add -Wformat=2 compiler option to NODIST #122474

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

Open
wants to merge 20 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 6 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/workflows/reusable-ubuntu.yml
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,7 @@ jobs:
working-directory: ${{ env.CPYTHON_BUILDDIR }}
run: make pythoninfo
- name: Check compiler warnings
run: python Tools/build/check_warnings.py --compiler-output-file-path=${{ env.CPYTHON_BUILDDIR }}/compiler_output.txt --warning-ignore-file-path ${GITHUB_WORKSPACE}/Tools/build/.warningignore_ubuntu
run: python Tools/build/check_warnings.py --compiler-output-file-path=${{ env.CPYTHON_BUILDDIR }}/compiler_output.txt --warning-ignore-file-path ${GITHUB_WORKSPACE}/Tools/build/.warningignore_ubuntu --fail-on-regression
- name: Remount sources writable for tests
# some tests write to srcdir, lack of pyc files slows down testing
run: sudo mount $CPYTHON_RO_SRCDIR -oremount,rw
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Add -Wformat=2 to NODIST build flags to warn about potential vulnerabilities related to format strings.
11 changes: 11 additions & 0 deletions Objects/unicodeobject.c
Original file line number Diff line number Diff line change
Expand Up @@ -2851,6 +2851,14 @@ unicode_fromformat_arg(_PyUnicodeWriter *writer,
default: fmt = formats[sizemod]; break;
}
int issigned = (*f == 'd' || *f == 'i');
// Format strings for sprintf are selected from constant arrays of
// constant strings, and the variable used to index into the arrays
// is only assigned known constant values. Ignore warnings related
// to the format string not being a string literal.
#if defined(__GNUC__) || defined(__clang__)
#pragma GCC diagnostic push
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Consider using _Py_COMP_DIAG_PUSH/_Py_COMP_DIAG_POP, and adding a macro like _Py_COMP_DIAG_IGNORE_DEPR_DECLS, to make this easier to port to other compilers.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@encukou created macro for ignoring format nonliterals and applied it to this block

#pragma GCC diagnostic ignored "-Wformat-nonliteral"
#endif
switch (sizemod) {
case F_LONG:
len = issigned ?
Expand Down Expand Up @@ -2881,6 +2889,9 @@ unicode_fromformat_arg(_PyUnicodeWriter *writer,
sprintf(buffer, fmt, va_arg(*vargs, unsigned int));
break;
}
#if defined(__GNUC__) || defined(__clang__)
#pragma GCC diagnostic pop
#endif
assert(len >= 0);

int sign = (buffer[0] == '-');
Expand Down
9 changes: 9 additions & 0 deletions Python/getversion.c
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,17 @@ void _Py_InitVersion(void)
#else
const char *buildinfo_format = "%.80s (%.80s) %.80s";
#endif
// The format string is defined above and is observably safe.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could it be switched to a #defined literal? That way it could look safe to the compiler, too.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I just pushed a change. I figure instead of going through the trouble defining a format string in the preprocessor #if/#else blocks and adding all of the diagnostic pragmas we can just put the PyOS_snprintf() with the relevant format string literals in the respective #if/#else blocks. We eliminate the root cause of the warning instead of ignore it.

// Ignore warnings related to non-literal format strings.
#if defined(__GNUC__) && !defined(__clang__)
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wformat-nonliteral"
#endif
PyOS_snprintf(version, sizeof(version), buildinfo_format,
PY_VERSION, Py_GetBuildInfo(), Py_GetCompiler());
#if defined(__GNUC__) && !defined(__clang__)
#pragma GCC diagnostic pop
#endif
}

const char *
Expand Down
39 changes: 39 additions & 0 deletions configure

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions configure.ac
Original file line number Diff line number Diff line change
Expand Up @@ -2510,6 +2510,7 @@ if test "$disable_safety" = "no"
then
AX_CHECK_COMPILE_FLAG([-fstack-protector-strong], [CFLAGS_NODIST="$CFLAGS_NODIST -fstack-protector-strong"], [AC_MSG_WARN([-fstack-protector-strong not supported])], [-Werror])
AX_CHECK_COMPILE_FLAG([-Wtrampolines], [CFLAGS_NODIST="$CFLAGS_NODIST -Wtrampolines"], [AC_MSG_WARN([-Wtrampolines not supported])], [-Werror])
AX_CHECK_COMPILE_FLAG([-Wformat -Wformat=2], [CFLAGS_NODIST="$CFLAGS_NODIST -Wformat -Wformat=2"], [AC_MSG_WARN([-Wformat and -Wformat=2 not supported])], [-Werror])
fi

AC_MSG_CHECKING([for --enable-slower-safety])
Expand Down
Loading