Bug 842

Summary: visudo does not build reproducibly
Product: Sudo Reporter: Bernhard M. Wiedemann <sudobugbmw>
Component: VisudoAssignee: Todd C. Miller <Todd.Miller>
Status: RESOLVED FIXED    
Severity: normal    
Priority: low    
Version: 1.8.23   
Hardware: PC   
OS: Linux   
URL: https://build.opensuse.org/request/show/622342
Attachments: draft patch

Description Bernhard M. Wiedemann 2018-07-20 07:24: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.
Comment 1 Bernhard M. Wiedemann 2018-07-20 07:28:19 MDT
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
Comment 2 Todd C. Miller 2018-07-20 10:19:13 MDT
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.
Comment 3 Bernhard M. Wiedemann 2018-07-23 22:00:08 MDT
I tested the patch and results look good.
Thanks for this nice fix.
Comment 4 Todd C. Miller 2018-08-18 13:27:37 MDT
Fixed in sudo 1.8.24, available now.