Compiling with -O3 will cause overflow in fgetws() call
Compiling the update master with -O3 on gentoo, I see:
* QA Notice: Package triggers severe warnings which indicate that it
* may exhibit random runtime failures.
* /usr/include/bits/wchar2.h:395:20: warning: call to '__fgetws_chk_warn' declared with attribute warning: fgetws called with bigger size than length of destination buffer [enabled by default]
emerge --info:
ortage 2.1.11.9 (hardened/linux/x86, gcc-4.6.3, glibc-2.15-r2, 3.2.23-gentoo
i686)
=================================================================
System uname:
Linux-3.2.23-gentoo-i686-Intel-R-_Celeron-R-_M_CPU_430_@_1.73GHz-with-gentoo-2.1
Timestamp of tree: Fri, 10 Aug 2012 11:30:01 +0000
app-shells/bash: 4.2_p20
dev-lang/python: 2.7.3-r2
dev-util/cmake: 2.8.7-r5
dev-util/pkgconfig: 0.26
sys-apps/baselayout: 2.1-r1
sys-apps/openrc: 0.9.8.4
sys-apps/sandbox: 2.5
sys-devel/autoconf: 2.13, 2.68
sys-devel/automake: 1.11.1
sys-devel/binutils: 2.22-r1
sys-devel/gcc: 4.5.3-r2, 4.6.3
sys-devel/gcc-config: 1.7.3
sys-devel/libtool: 2.4-r1
sys-devel/make: 3.82-r1
sys-kernel/linux-headers: 3.2-r1 (virtual/os-headers)
sys-libs/glibc: 2.15-r2
Repositories: gentoo x-portage
ACCEPT_KEYWORDS="x86"
ACCEPT_LICENSE="*"
CBUILD="i686-pc-linux-gnu"
CFLAGS="-O2 -march=pentium-m"
CHOST="i686-pc-linux-gnu"
CONFIG_PROTECT="/etc /usr/share/config /usr/share/gnupg/qualified.txt
/usr/share/themes/oxygen-gtk/gtk-2.0 /usr/share/themes/oxygen-gtk/gtk-3.0"
CONFIG_PROTECT_MASK="/etc/ca-certificates.conf /etc/env.d /etc/fonts/fonts.conf
/etc/gconf /etc/gentoo-release /etc/revdep-rebuild /etc/sandbox.d
/etc/terminfo"
CXXFLAGS="-O2 -march=pentium-m"
DISTDIR="/media/sources"
EMERGE_DEFAULT_OPTS="--with-bdeps y"
FCFLAGS="-march=i686 -O2 -pipe"
FEATURES="assume-digests binpkg-logs collision-protect
config-protect-if-modified distlocks ebuild-locks fixlafiles news
parallel-fetch parse-eapi-ebuild-head protect-owned sandbox sfperms sign
split-log strict unknown-features-warn unmerge-logs unmerge-orphans userfetch
userpriv usersandbox usersync"
FFLAGS="-march=i686 -O2 -pipe"
GENTOO_MIRRORS="http://distfiles.gentoo.org"
LANG="it_IT.UTF-8"
LDFLAGS="-Wl,-O1 -Wl,--as-needed -Wl,--hash-style=gnu"
LINGUAS="en en_GB"
MAKEOPTS="-j1"
PKGDIR="/usr/portage/packages"
PORTAGE_CONFIGROOT="/"
PORTAGE_RSYNC_OPTS="--recursive --links --safe-links --perms --times --compress
--force --whole-file --delete --stats --human-readable --timeout=180
--exclude=/distfiles --exclude=/local --exclude=/packages"
PORTAGE_TMPDIR="/tmp"
PORTDIR="/usr/portage"
PORTDIR_OVERLAY="/usr/local/portage"
SYNC="rsync://rsync.gentoo.org/gentoo-portage"
USE="X aac acl acpi alsa apic bash-completion berkdb bzip2 cairo cli consolekit
cracklib crypt custom-cflags custom-optimization cxx dbus dri dvd extras ffmpeg
gdbm gpm gtk hardened iconv jpeg jpeg2k kde lame lm_sensors mad mmx modules mp3
mudflap ncurses networkmanager nptl nsplugin opengl openmp pam pax_kernel pcre
pic png policykit pppd qt3support qt4 readline semantic-desktop session sse
sse2 ssl svg symlink tcpd theora threads tiff tordns udev unicode urandom
vorbis x264 x86 xvid zlib" ALSA_CARDS="hda-intel" ALSA_PCM_PLUGINS="adpcm alaw
asym copy dmix dshare dsnoop empty extplug file hooks iec958 ioplug ladspa
lfloat linear meter mmap_emul mulaw multi null plug rate route share shm
softvol" ELIBC="glibc" INPUT_DEVICES="keyboard mouse evdev synaptics"
KERNEL="linux" LIBREOFFICE_EXTENSIONS="presenter-console presenter-minimizer"
LINGUAS="en en_GB" PYTHON_TARGETS="python2_7" USERLAND="GNU" VIDEO_CARDS="intel"
USE_PYTHON="2.7"
Original issue reported on code.google.com by [email protected] on 14 Aug 2012 at 8:54
I'm unable to edit the summary, but -O* causes this problem
Original comment by [email protected] on 14 Aug 2012 at 12:08
Can you provide an output of manual compile, i.e. standard
./configure
make
make install
I don't understand the problem well.
Sorry for late reply. :)
Original comment by [email protected] on 11 Dec 2012 at 5:40
- Changed state: NeedMoreInfo
Hello, sorry for the confusion about who causes the overflow.
try to compile it with -D_FORTIFY_SOURCE=2
Here the build log produced by portage:
>>> Preparing source in
/tmp/portage/net-analyzer/logkeys-9999/work/logkeys-9999 ...
* Applying cxxflags.patch ...
[ ok ]
* Running eautoreconf in '/tmp/portage/net-analyzer/logkeys-9999/work/logkeys-9999' ...
* Running aclocal ...
[ ok ]
* Running autoconf ...
[ ok ]
* Running autoheader ...
[ ok ]
* Running automake --add-missing --copy --foreign ...
[ ok ]
>>> Source prepared.
>>> Configuring source in
/tmp/portage/net-analyzer/logkeys-9999/work/logkeys-9999 ...
./configure --prefix=/usr --build=x86_64-pc-linux-gnu
--host=x86_64-pc-linux-gnu --mandir=/usr/share/man --infodir=/usr/share/info
--datadir=/usr/share --sysconfdir=/etc --localstatedir=/var/lib
--libdir=/usr/lib64 --disable-dependency-tracking
checking for a BSD-compatible install... /usr/bin/install -c
checking whether build environment is sane... yes
checking for a thread-safe mkdir -p... /bin/mkdir -p
checking for gawk... gawk
checking whether make sets $(MAKE)... yes
checking for x86_64-pc-linux-gnu-g++... x86_64-pc-linux-gnu-g++
checking whether the C++ compiler works... yes
checking for C++ compiler default output file name... a.out
checking for suffix of executables...
checking whether we are cross compiling... no
checking for suffix of object files... o
checking whether we are using the GNU C++ compiler... yes
checking whether x86_64-pc-linux-gnu-g++ accepts -g... yes
checking for style of include used by make... GNU
checking dependency style of x86_64-pc-linux-gnu-g++... none
checking whether make sets $(MAKE)... (cached) yes
checking for which... yes
checking for grep... yes
checking for ps... yes
checking for dumpkeys... yes
checking for /dev/input... yes
checking for /proc/bus/input/devices... yes
checking how to run the C++ preprocessor... x86_64-pc-linux-gnu-g++ -E
checking for grep that handles long lines and -e... /bin/grep
checking for egrep... /bin/grep -E
checking for ANSI C header files... yes
checking for sys/types.h... yes
checking for sys/stat.h... yes
checking for stdlib.h... yes
checking for string.h... yes
checking for memory.h... yes
checking for strings.h... yes
checking for inttypes.h... yes
checking for stdint.h... yes
checking for unistd.h... yes
checking cstdio usability... yes
checking cstdio presence... yes
checking for cstdio... yes
checking cerrno usability... yes
checking cerrno presence... yes
checking for cerrno... yes
checking cwchar usability... yes
checking cwchar presence... yes
checking for cwchar... yes
checking cstring usability... yes
checking cstring presence... yes
checking for cstring... yes
checking cassert usability... yes
checking cassert presence... yes
checking for cassert... yes
checking sstream usability... yes
checking sstream presence... yes
checking for sstream... yes
checking cstdlib usability... yes
checking cstdlib presence... yes
checking for cstdlib... yes
checking csignal usability... yes
checking csignal presence... yes
checking for csignal... yes
checking error.h usability... yes
checking error.h presence... yes
checking for error.h... yes
checking for unistd.h... (cached) yes
checking getopt.h usability... yes
checking getopt.h presence... yes
checking for getopt.h... yes
checking sys/file.h usability... yes
checking sys/file.h presence... yes
checking for sys/file.h... yes
checking for sys/stat.h... (cached) yes
checking linux/input.h usability... yes
checking linux/input.h presence... yes
checking for linux/input.h... yes
checking for stdbool.h that conforms to C99... yes
checking for _Bool... no
checking for inline... inline
checking for pid_t... yes
checking for size_t... yes
checking for error_at_line... yes
checking vfork.h usability... no
checking vfork.h presence... no
checking for vfork.h... no
checking for fork... yes
checking for vfork... yes
checking for working fork... yes
checking for working vfork... (cached) yes
checking for geteuid... yes
checking for error... yes
checking for error_at_line... yes
checking for exit... yes
checking for on_exit... yes
checking for memset... yes
checking for setlocale... yes
checking for strerror... yes
checking for fprintf... yes
checking for getopt_long... yes
checking for fopen... yes
checking for sscanf... yes
checking for fscanf... yes
checking for getpid... yes
checking for getuid... yes
checking for getgid... yes
checking for fclose... yes
checking for remove... yes
checking for kill... yes
checking for strlen... yes
checking for strcat... yes
checking for strcpy... yes
checking for strncat... yes
checking for freopen... yes
checking for feof... yes
checking for fgets... yes
checking for atoi... yes
checking for sigaction... yes
checking for fork... (cached) yes
checking for setsid... yes
checking for open... yes
checking for close... yes
checking for flock... yes
checking for write... yes
checking for umask... yes
checking for setegid... yes
checking for seteuid... yes
checking for strftime... yes
checking for localtime... yes
checking for fflush... yes
checking for read... yes
checking for time... yes
checking for fgetws... yes
checking for wcslen... yes
checking for swscanf... yes
checking for wcscpy... yes
checking for popen... yes
checking for pclose... yes
configure: creating ./config.status
config.status: creating Makefile
config.status: creating src/Makefile
config.status: creating man/Makefile
config.status: creating scripts/Makefile
config.status: creating config.h
config.status: executing depfiles commands
>>> Source configured.
>>> Compiling source in
/tmp/portage/net-analyzer/logkeys-9999/work/logkeys-9999 ...
make -j4
(CDPATH="${ZSH_VERSION+.}:" && cd . && /bin/sh
/tmp/portage/net-analyzer/logkeys-9999/work/logkeys-9999/missing --run
autoheader)
rm -f stamp-h1
touch config.h.in
cd . && /bin/sh ./config.status config.h
config.status: creating config.h
config.status: config.h is unchanged
make all-recursive
make[1]: Entering directory
`/tmp/portage/net-analyzer/logkeys-9999/work/logkeys-9999'
Making all in src
make[2]: Entering directory
`/tmp/portage/net-analyzer/logkeys-9999/work/logkeys-9999/src'
x86_64-pc-linux-gnu-g++ -DHAVE_CONFIG_H -I. -I.. -march=native -O2 -Wall
-DSYS_CONF_DIR=\"/etc\" -march=native -O2 -c -o logkeys.o logkeys.cc
x86_64-pc-linux-gnu-g++ -DHAVE_CONFIG_H -I. -I.. -march=native -O2 -Wall
-DSYS_CONF_DIR=\"/etc\" -march=native -O2 -c -o llk.o llk.cc
x86_64-pc-linux-gnu-g++ -DHAVE_CONFIG_H -I. -I.. -march=native -O2 -Wall
-DSYS_CONF_DIR=\"/etc\" -march=native -O2 -c -o llkk.o llkk.cc
x86_64-pc-linux-gnu-g++ -march=native -O2 -Wall -DSYS_CONF_DIR=\"/etc\"
-march=native -O2 -Wl,-O1 -Wl,--as-needed -Wl,--hash-style=gnu -o llk llk.o
x86_64-pc-linux-gnu-g++ -march=native -O2 -Wall -DSYS_CONF_DIR=\"/etc\"
-march=native -O2 -Wl,-O1 -Wl,--as-needed -Wl,--hash-style=gnu -o llkk llkk.o
In file included from /usr/include/wchar.h:881:0,
from /usr/lib/gcc/x86_64-pc-linux-gnu/4.5.4/include/g++-v4/cwchar:47,
from logkeys.cc:11:
In function ‘wchar_t* fgetws(wchar_t*, int, __FILE*)’,
inlined from ‘void logkeys::parse_input_keymap()’ at logkeys.cc:256:42:
/usr/include/bits/wchar2.h:395:20: warning: call to ‘__fgetws_chk_warn’
declared with attribute warning: fgetws called with bigger size than length of
destination buffer
x86_64-pc-linux-gnu-g++ -march=native -O2 -Wall -DSYS_CONF_DIR=\"/etc\"
-march=native -O2 -Wl,-O1 -Wl,--as-needed -Wl,--hash-style=gnu -o logkeys
logkeys.o
make[2]: Leaving directory
`/tmp/portage/net-analyzer/logkeys-9999/work/logkeys-9999/src'
Making all in man
make[2]: Entering directory
`/tmp/portage/net-analyzer/logkeys-9999/work/logkeys-9999/man'
make[2]: Nessuna operazione da eseguire per «all».
make[2]: Leaving directory
`/tmp/portage/net-analyzer/logkeys-9999/work/logkeys-9999/man'
Making all in scripts
make[2]: Entering directory
`/tmp/portage/net-analyzer/logkeys-9999/work/logkeys-9999/scripts'
make[2]: Nessuna operazione da eseguire per «all».
make[2]: Leaving directory
`/tmp/portage/net-analyzer/logkeys-9999/work/logkeys-9999/scripts'
make[2]: Entering directory
`/tmp/portage/net-analyzer/logkeys-9999/work/logkeys-9999'
make[2]: Leaving directory
`/tmp/portage/net-analyzer/logkeys-9999/work/logkeys-9999'
make[1]: Leaving directory
`/tmp/portage/net-analyzer/logkeys-9999/work/logkeys-9999'
>>> Source compiled.
>>> Test phase [not enabled]: net-analyzer/logkeys-9999
>>> Install logkeys-9999 into /tmp/portage/net-analyzer/logkeys-9999/image/
category net-analyzer
make -j4 DESTDIR=/tmp/portage/net-analyzer/logkeys-9999/image/ install
Making install in src
make[1]: Entering directory
`/tmp/portage/net-analyzer/logkeys-9999/work/logkeys-9999/src'
make[2]: Entering directory
`/tmp/portage/net-analyzer/logkeys-9999/work/logkeys-9999/src'
make[2]: Nessuna operazione da eseguire per «install-data-am».
/bin/mkdir -p '/tmp/portage/net-analyzer/logkeys-9999/image//usr/bin'
/usr/bin/install -c logkeys llk llkk '/tmp/portage/net-analyzer/logkeys-9999/image//usr/bin'
make install-exec-hook
make[3]: Entering directory
`/tmp/portage/net-analyzer/logkeys-9999/work/logkeys-9999/src'
chown root\: /tmp/portage/net-analyzer/logkeys-9999/image//usr/bin/llk
chmod u+s /tmp/portage/net-analyzer/logkeys-9999/image//usr/bin/llk
chown root\: /tmp/portage/net-analyzer/logkeys-9999/image//usr/bin/llkk
chmod u+s /tmp/portage/net-analyzer/logkeys-9999/image//usr/bin/llkk
make[3]: Leaving directory
`/tmp/portage/net-analyzer/logkeys-9999/work/logkeys-9999/src'
make[2]: Leaving directory
`/tmp/portage/net-analyzer/logkeys-9999/work/logkeys-9999/src'
make[1]: Leaving directory
`/tmp/portage/net-analyzer/logkeys-9999/work/logkeys-9999/src'
Making install in man
make[1]: Entering directory
`/tmp/portage/net-analyzer/logkeys-9999/work/logkeys-9999/man'
make[2]: Entering directory
`/tmp/portage/net-analyzer/logkeys-9999/work/logkeys-9999/man'
make[2]: Nessuna operazione da eseguire per «install-exec-am».
/bin/mkdir -p '/tmp/portage/net-analyzer/logkeys-9999/image//usr/share/man/man8'
/usr/bin/install -c -m 644 logkeys.8 '/tmp/portage/net-analyzer/logkeys-9999/image//usr/share/man/man8'
make[2]: Leaving directory
`/tmp/portage/net-analyzer/logkeys-9999/work/logkeys-9999/man'
make[1]: Leaving directory
`/tmp/portage/net-analyzer/logkeys-9999/work/logkeys-9999/man'
Making install in scripts
make[1]: Entering directory
`/tmp/portage/net-analyzer/logkeys-9999/work/logkeys-9999/scripts'
make[2]: Entering directory
`/tmp/portage/net-analyzer/logkeys-9999/work/logkeys-9999/scripts'
make[2]: Nessuna operazione da eseguire per «install-exec-am».
/bin/mkdir -p '/tmp/portage/net-analyzer/logkeys-9999/image//etc'
/usr/bin/install -c logkeys-start.sh logkeys-kill.sh '/tmp/portage/net-analyzer/logkeys-9999/image//etc'
make[2]: Leaving directory
`/tmp/portage/net-analyzer/logkeys-9999/work/logkeys-9999/scripts'
make[1]: Leaving directory
`/tmp/portage/net-analyzer/logkeys-9999/work/logkeys-9999/scripts'
make[1]: Entering directory
`/tmp/portage/net-analyzer/logkeys-9999/work/logkeys-9999'
make[2]: Entering directory
`/tmp/portage/net-analyzer/logkeys-9999/work/logkeys-9999'
make[2]: Nessuna operazione da eseguire per «install-exec-am».
make[2]: Nessuna operazione da eseguire per «install-data-am».
make[2]: Leaving directory
`/tmp/portage/net-analyzer/logkeys-9999/work/logkeys-9999'
make[1]: Leaving directory
`/tmp/portage/net-analyzer/logkeys-9999/work/logkeys-9999'
>>> Completed installing logkeys-9999 into
/tmp/portage/net-analyzer/logkeys-9999/image/
strip: x86_64-pc-linux-gnu-strip --strip-unneeded -R .comment -R
.GCC.command.line
usr/bin/llkk
usr/bin/llk
usr/bin/logkeys
ecompressdir: bzip2 -9 /usr/share/man
ecompressdir: bzip2 -9 /usr/share/doc
* QA Notice: Package triggers severe warnings which indicate that it
* may exhibit random runtime failures.
* /usr/include/bits/wchar2.h:395:20: warning: call to ‘__fgetws_chk_warn’ declared with attribute warning: fgetws called with bigger size than length of destination buffer
* Please do not file a Gentoo bug and instead report the above QA
* issues directly to the upstream developers of this software.
* Homepage: https://code.google.com/p/logkeys/
Original comment by [email protected] on 11 Dec 2012 at 10:48
https://github.com/chewing/libchewing/pull/11
this is an exmaple that gives you an idea of what happens
Original comment by [email protected] on 11 Dec 2012 at 10:56
Ok, I get it, besides reading n widechars, fgetws() appends a \0 to buffer, and
in this code
http://code.google.com/p/logkeys/source/browse/src/logkeys.cc#256
this effectively exceeds alloted buffer size (line[32] - sizeof(line)).
Can you please manually patch this line so that it looks:
if(fgetws(line, sizeof(line) - 1, stdin) == NULL) {
and increase the size of the `line` buffer a few lines above to
`wchar_t line[33];`
Thanks. :)
You may encounter further errors as this (as everything else) appears buggy. :)
And thanks for the report.
Original comment by [email protected] on 11 Dec 2012 at 11:11
- Changed title: Compiling with -O3 will cause overflow in fgetws() call
- Changed state: Accepted
mind to post directly a patch on http://bpaste.net/ ?
It will save a lot of time for me.
Original comment by [email protected] on 11 Dec 2012 at 11:15
Yeah, ok. But I'll do it later when I first test everything myself. :)
Original comment by [email protected] on 11 Dec 2012 at 1:07
Same issue while compiling on openSUSE (x86_64), but the suggested fix didn't
work.
I'm by far not an expert, but, according to man, fgetws "reads a string of at
most n-1 wide characters into the wide-character array pointed to by ws, and
adds a terminating null wide character (L'\0')". Therefore I thought `wchar_t
line[32]` in logkeys.cc might be ok, replaced `if(fgetws(line, sizeof(line),
stdin) == NULL)` with `if(fgetws(line, sizeof(line) / sizeof(wchar_t), stdin)
== NULL)` and the warning disappeared (or, more simply, with: fgetws(line, 32,
stdin).
As far as I can tell after my ugly patch the program is still working, hope it
might be of some help to someone. :)
Original comment by [email protected] on 25 Dec 2012 at 10:28