This issue tracker has been migrated to GitHub, and is currently read-only.
For more information, see the GitHub FAQs in the Python's Developer Guide.

classification
Title: Compilation warnings in getpath.c with gcc on Ubuntu / -D_FORTIFY_SOURCE=2
Type: behavior Stage: resolved
Components: Interpreter Core Versions: Python 3.9
process
Status: closed Resolution: fixed
Dependencies: Superseder:
Assigned To: Nosy List: pitrou, serhiy.storchaka, vstinner
Priority: low Keywords:

Created on 2017-12-19 15:05 by pitrou, last changed 2022-04-11 14:58 by admin. This issue is now closed.

Messages (10)
msg308653 - (view) Author: Antoine Pitrou (pitrou) * (Python committer) Date: 2017-12-19 15:05
On Ubuntu 16.04:

$ gcc --version
gcc (Ubuntu 5.4.0-6ubuntu1~16.04.5) 5.4.0 20160609
Copyright (C) 2015 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.  There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

$ make
[...]
In function ‘wcsncpy’,
    inlined from ‘calculate_zip_path’ at ./Modules/getpath.c:797:5:
/usr/include/x86_64-linux-gnu/bits/wchar2.h:200:9: warning: call to ‘__wcsncpy_chk_warn’ declared with attribute warning: wcsncpy called with length bigger than size of destination buffer
  return __wcsncpy_chk_warn (__dest, __src, __n,
         ^
In function ‘wcsncpy’,
    inlined from ‘calculate_zip_path’ at ./Modules/getpath.c:806:9:
/usr/include/x86_64-linux-gnu/bits/wchar2.h:200:9: warning: call to ‘__wcsncpy_chk_warn’ declared with attribute warning: wcsncpy called with length bigger than size of destination buffer
  return __wcsncpy_chk_warn (__dest, __src, __n,
         ^
In function ‘wcsncpy’,
    inlined from ‘calculate_argv0_path’ at ./Modules/getpath.c:683:5:
/usr/include/x86_64-linux-gnu/bits/wchar2.h:200:9: warning: call to ‘__wcsncpy_chk_warn’ declared with attribute warning: wcsncpy called with length bigger than size of destination buffer
  return __wcsncpy_chk_warn (__dest, __src, __n,
         ^
In function ‘wcsncpy’,
    inlined from ‘calculate_argv0_path’ at ./Modules/getpath.c:736:13:
/usr/include/x86_64-linux-gnu/bits/wchar2.h:200:9: warning: call to ‘__wcsncpy_chk_warn’ declared with attribute warning: wcsncpy called with length bigger than size of destination buffer
  return __wcsncpy_chk_warn (__dest, __src, __n,
         ^
msg308697 - (view) Author: STINNER Victor (vstinner) * (Python committer) Date: 2017-12-20 00:25
In function ‘wcsncpy’,
    inlined from ‘calculate_zip_path’ at ./Modules/getpath.c:797:5:
/usr/include/x86_64-linux-gnu/bits/wchar2.h:200:9: warning: call to ‘__wcsncpy_chk_warn’ declared with attribute warning: wcsncpy called with length bigger than size of destination buffer
  return __wcsncpy_chk_warn (__dest, __src, __n,
         ^

Line 797:

    wcsncpy(calculate->zip_path, prefix, MAXPATHLEN);

calculate type is "PyCalculatePath *" which is defined as:

typedef struct {
    ...
    wchar_t zip_path[MAXPATHLEN+1];    /* ".../lib/pythonXY.zip" */
    ...
} PyCalculatePath;

Earlier, all bytes are set to 0:

    memset(&calculate, 0, sizeof(calculate));

So I don't see how wcsncpy() can overflow.


By the way, I'm unable to reproduce the warning on Fedora 27 with GCC 7.2.1. Are you using -D_FORTIFY_SOURCE=1? Are you compiling Python in release mode? Can you try to find the command line compiling getpath.c?
msg308708 - (view) Author: Antoine Pitrou (pitrou) * (Python committer) Date: 2017-12-20 09:01
Here is the command line:

gcc -pthread -c -Wno-unused-result -Wsign-compare -g -Og -Wall -Wstrict-prototypes    -std=c99 -Wextra -Wno-unused-result -Wno-unused-parameter -Wno-missing-field-initializers -Werror=implicit-function-declaration   -I. -I./Include    -DPy_BUILD_CORE -DPYTHONPATH='":"' \
	-DPREFIX='"/usr/local"' \
	-DEXEC_PREFIX='"/usr/local"' \
	-DVERSION='"3.7"' \
	-DVPATH='""' \
	-o Modules/getpath.o ./Modules/getpath.c
msg308721 - (view) Author: Serhiy Storchaka (serhiy.storchaka) * (Python committer) Date: 2017-12-20 11:23
The same on Ubuntu 17.10 with gcc 7.2.0.
msg308755 - (view) Author: STINNER Victor (vstinner) * (Python committer) Date: 2017-12-20 17:55
Ah, I missed the warning because I forge -O0 when I build Python.

https://wiki.ubuntu.com/ToolChain/CompilerFlags

Ubuntu adds -D_FORTIFY_SOURCE=2 flag by default.

The warnings can be seen with "-D_FORTIFY_SOURCE=2 -Og", but not with "-D_FORTIFY_SOURCE=2 -O3". Moreover, "-D_FORTIFY_SOURCE=2 -O0" complains that _FORTIFY_SOURCE requires to optimize the code.

It looks more like a false alarm because -D_FORTIFY_SOURCE=2 is incompatible with -Og.

Maybe we should force -D_FORTIFY_SOURCE=0 when we build Python in debug mode?
msg308756 - (view) Author: Antoine Pitrou (pitrou) * (Python committer) Date: 2017-12-20 17:56
I don't think so.  It's good to have fortify enabled, especially in debug mode :-)

If the warnings are harmless and there isn't an easy way to suppress them, then I'm ok to close this issue.
msg308757 - (view) Author: STINNER Victor (vstinner) * (Python committer) Date: 2017-12-20 18:02
getpath.c uses many buffers of MAXPATHLEN+1 wide characters. Example:

    wchar_t argv0_path[MAXPATHLEN+1];

These buffers are initialized to zero to make sure that the last character is always a NULL character.

To keep the final NULL character, string copies use:

   wcsncpy(dest, src, MAXPATHLEN);

This code is wrong: it truncates the string if it's longer than MAXPATHLEN characters.

I modified the code to move global buffers closer to where there are used, and to dynamically allocate strings on the heap, rather using fixed sizes. But I didn't finish to "cleanup" Modules/getpath.c and PC/getpathp.c. The code still uses the buffer of fixed size and truncate strings.

The real fix would be to avoid these fixed-size buffers, and only use dynamically allocated strings.

I modified the code to allow to report errors. Previously, it wasn't possible exception using Py_FatalError() which is not a nice way to report errors, especially when Python is embedded in an application.
msg308758 - (view) Author: STINNER Victor (vstinner) * (Python committer) Date: 2017-12-20 18:02
See bpo-32030 for my huge refactoring work on the Python initialization code.
msg316349 - (view) Author: Serhiy Storchaka (serhiy.storchaka) * (Python committer) Date: 2018-05-10 07:42
Warnings are emitted when compile with gcc-5, gcc-6 and gcc-7, but not when compile with gcc-4.8 or gcc-8.

Versions:

gcc-4.8 (Ubuntu 4.8.5-4ubuntu8) 4.8.5
gcc-5 (Ubuntu 5.5.0-12ubuntu1) 5.5.0 20171010
gcc-6 (Ubuntu 6.4.0-17ubuntu1) 6.4.0 20180424
gcc-7 (Ubuntu 7.3.0-16ubuntu3) 7.3.0
gcc-8 (Ubuntu 8-20180414-1ubuntu2) 8.0.1 20180414 (experimental) [trunk revision 259383]
msg353252 - (view) Author: STINNER Victor (vstinner) * (Python committer) Date: 2019-09-26 01:12
I just recompiled the master branch of Python twice using these flags:

* -D_FORTIFY_SOURCE=2 -Og
* -D_FORTIFY_SOURCE=2 -O3

I got a few warnings, the same that I get without FORTIFY SOURCE.

Using -D_FORTIFY_SOURCE=2 -O3, I get one warning, but it's no longer from getpath.c but in socketmodule.c. So I created a new issue: bpo-38282 "socketmodule.c: _FORTIFY_SOURCE=2 warning in AF_ALG case of getsockaddrarg()".

I close this issue. It has been fixed in the master branch.
History
Date User Action Args
2022-04-11 14:58:55adminsetgithub: 76556
2019-09-26 01:12:36vstinnersetstatus: open -> closed
versions: + Python 3.9, - Python 3.7
messages: + msg353252

resolution: fixed
stage: resolved
2018-05-10 07:42:19serhiy.storchakasetmessages: + msg316349
2017-12-20 18:02:53vstinnersetmessages: + msg308758
2017-12-20 18:02:13vstinnersetmessages: + msg308757
2017-12-20 17:57:02vstinnersettitle: Compilation warnings with gcc -> Compilation warnings in getpath.c with gcc on Ubuntu / -D_FORTIFY_SOURCE=2
2017-12-20 17:56:33pitrousetmessages: + msg308756
2017-12-20 17:55:33vstinnersetmessages: + msg308755
2017-12-20 11:23:19serhiy.storchakasetmessages: + msg308721
2017-12-20 09:01:29pitrousetmessages: + msg308708
2017-12-20 00:25:58vstinnersetmessages: + msg308697
2017-12-19 15:05:24pitroucreate