Bugzilla – Bug 842
visudo does not build reproducibly
Last modified: 2018-08-18 13:27:37 MDT
Created attachment 512 [details] draft patch We did a patch in openSUSE at https://build.opensuse.org/request/show/622342 because there is likely an issue with sudo's build system .c files in the plugins/sudoers/ directory are compiled ~4 times and sometimes the compilation compiles ./foo.c and sometimes it compiles foo.c without leading ./ And this causes random differences in the resulting visudo binary. See https://reproducible-builds.org/ for why this matters. make -B avoids the unreproducibility and so does the attached patch, but the patch has the side-effect that sometimes parallel builds fail because a .o file is missing, even though there was just a call run to create it. One wild guess is that libtool creates .o files before creating .lo files and then removes the 'intermediate' .o files again and that confuses make's dependency handling.
Here is an interesting extract of a diff from two runs of make -d -j$N (with N=2 and N=4) Finished prerequisites of target file 'group_plugin.o'. Prerequisite 'group_plugin.c' is older than target 'group_plugin.o'. - Prerequisite 'group_plugin.lo' is older than target 'group_plugin.o'. - No need to remake target 'group_plugin.o'. + Prerequisite 'group_plugin.lo' is newer than target 'group_plugin.o'. + Must remake target 'group_plugin.o'. + gcc -c -I../../include -I../.. -I. -I. -I../.. -DLIBDIR=\"/usr/lib64\" -DLOCALEDIR=\"/usr/share/locale\" -D_PATH_SUDOERS=\"/etc/sudoers\" -D_PATH_CVTSUDOERS_CONF=\"/etc/cvtsudoers.conf\" -DSUDOERS_UID=0 -DSUDOERS_GID=0 -DSUDOERS_MODE=0440 -D_FORTIFY_SOURCE=2 -fmessage-length=0 -grecord-gcc-switches -O2 -Wall -D_FORTIFY_SOURCE=2 -fstack-protector-strong -funwind-tables -fasynchronous-unwind-tables -fstack-clash-protection -Wall -fpie -DLDAP_DEPRECATED -fvisibility=hidden -Wall -Wsign-compare -Wpointer-arith -fPIE -fstack-protector-strong group_plugin.c
This should be fixed by https://www.sudo.ws/repos/sudo/rev/a8d94e6aed9f When both a .o and .lo file was used in a Makefile, we used to make the .o depend on the .lo. Unfortunately, this creates a race condition for parallel make since libtool is not atomic (it creates a .o and then renames it when building PIC objects for shared libs). We always link with libtool so the only reason to prefer the .o over the .lo file is to avoid mixing .o and .lo in the dependencies. That's not a good enough reason so change mkdep.pl to warn when both a .o and .lo are referenced in a Makefile and do nothing else.
I tested the patch and results look good. Thanks for this nice fix.
Fixed in sudo 1.8.24, available now.