Bug 842 - visudo does not build reproducibly
visudo does not build reproducibly
Status: RESOLVED FIXED
Product: Sudo
Classification: Unclassified
Component: Visudo
1.8.23
PC Linux
: low normal
Assigned To: Todd C. Miller
https://build.opensuse.org/request/sh...
Depends on:
Blocks:
  Show dependency treegraph
 
Reported: 2018-07-20 07:24 MDT by Bernhard M. Wiedemann
Modified: 2018-08-18 13:27 MDT (History)
0 users

See Also:


Attachments
draft patch (500 bytes, patch)
2018-07-20 07:24 MDT, Bernhard M. Wiedemann
Details | Diff

Note You need to log in before you can comment on or make changes to this bug.
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.