gcc-7 toolchain triggers bug in build system causing non snmp drivers failing to be linked

Bug #1711092 reported by Christian Ehrhardt 
6
This bug affects 1 person
Affects Status Importance Assigned to Milestone
nut (Ubuntu)
Fix Released
Undecided
Unassigned

Bug Description

It was building a week ago, so likely gcc7 as you expect, taking a look ...

View might first fall on:
al175.c:400:28: warning: ‘%2X’ directive output may be truncated writing between 2 and 4 bytes into a region of size between 3 and 5 [-Wformat-truncation=]

But that is only a warning due to:
-Wformat-truncation being default on -Wall now [1]

But the actual "break" are errors like:
/usr/bin/ld: al175.o: relocation R_X86_64_32 against `.rodata.str1.1' can not be used when making a shared object; recompile with -fPIC

Actually -fPIC was used on parts of the build pre and post gcc-7 as seen in the buildlogs [2] [3].
The root cause seems in a change that dropped the former:
"-fPIE"
options and replaced them with
-specs=/usr/share/dpkg/no-pie-compile.specs

Since no change was made to nut this likely is from the toolchain upgrade.
This is kind of inverse to what I knew - like [4] where it is about enabling pie.
Did we intentionally drop that - I don't think so?

When analyzing the build it seems there are two times hardning options.
- The first one got the no-pie spec
- And the second lost the -fPIE

--- old 2017-08-16 09:14:46.667114832 +0200
+++ new 2017-08-16 09:14:47.275115931 +0200
@@ -1,15 +1,15 @@
 gcc -DHAVE_CONFIG_H -I. -I../include -Wdate-time -D_FORTIFY_SOURCE=2 -I../include -DNETSNMP_ENABLE_IPV6 -fno-strict-aliasing -g -O2 -fdebug-prefix-map=/build/net-snmp=.
-
+-specs=/usr/share/dpkg/no-pie-compile.specs
 -fstack-protector-strong -Wformat -Werror=format-security -DNETSNMP_USE_INLINE -Ulinux -Dlinux=linux -D_REENTRANT -D_GNU_SOURCE -DDEBIAN -fwrapv -fno-strict-aliasing -pipe -I/usr/local/include -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64 -I/usr/lib/x86_64-linux-gnu/perl/5.2 -Wdate-time -D_FORTIFY_SOURCE=2 -I/usr/include -I/usr/include/neon -g -O2 -fdebug-prefix-map=/<<PKGBUILDDIR>>=.
--fPIE
--fstack-protector-strong -Wformat -Werror=format-security -Wall -Wsign-compare -c -o al175.o al175.c
-/bin/bash ../libtool --tag=CC --mode=link gcc -I../include -DNETSNMP_ENABLE_IPV6 -fno-strict-aliasing -g -O2 -fdebug-prefix-map=/build/net-snmp=.

It almost seems to have two hardening entries one behaving one and one the other way.
I've found the source (form nut's POV) of both changes:
1. loosing -fPIE is the actual configure call changing from
CFLAGS="-g -O2 -fdebug-prefix-map=/<<PKGBUILDDIR>>=. -fPIE -fstack-protector-strong [...]
to
CFLAGS="-g -O2 -fdebug-prefix-map=/<<PKGBUILDDIR>>=. -fstack-protector-strong [...]
This can be checked when comparing zesty with artful calling:
$ DEB_BUILD_MAINT_OPTIONS=hardening=+all dpkg-buildflags --get CFLAGS
(Lets assume for now it is dropped because it is considered default anyway?)

2. gaining the no-pie spec is from net-snmp by configure
checking for Net-SNMP cflags... [...] -specs=/usr/share/dpkg/no-pie-compile.specs [...]
checking for Net-SNMP libs... [...] -specs=/usr/share/dpkg/no-pie-compile.specs [...]
While in the past this was without pie reference at all.

The options of #2 come later than #1 and so even if #1 would have -fPIE it would be disabled again.
The real source for the change in #2 is actually outside of the nut package.
On its build it wants to build a net-snmp plugin and to do so gets the build options that used.
And a change from zesty [5] to artful [6] is to add the -specs=/usr/share/dpkg/no-pie-compile.specs and the ld equivalent.

The source for that is there since a long time (2013), in d/rules of net-snmp:
  # without -pie build fails during perl module build somehow...
  export DEB_BUILD_MAINT_OPTIONS := hardening=+all,-pie

There is also a "-specs=/usr/share/dpkg/no-pie-link.specs" for the linker.
And in fact that should be used, so in the linking call replacing no-pie-compile.specs with no-pie-link.specs makes the link work (and seems more correct).

Of course that is hidden in auto-generated makefiles, so debug there if a reasonable way to make the (properly detected) net-snmp lib flags appear.

These (correct) flags are used in:
snmp_ups_LDADD = $(LDADD_DRIVERS) $(LIBNETSNMP_LIBS)
[...]
snmp-ups$(EXEEXT): $(snmp_ups_OBJECTS) $(snmp_ups_DEPENDENCIES) $(EXTRA_snmp_ups_DEPENDENCIES)
        @rm -f snmp-ups$(EXEEXT)
        $(AM_V_CCLD)$(LINK) $(snmp_ups_OBJECTS) $(snmp_ups_LDADD) $(LIBS)

But they are missing on the failing object which has:
al175$(EXEEXT): $(al175_OBJECTS) $(al175_DEPENDENCIES) $(EXTRA_al175_DEPENDENCIES)
        @rm -f al175$(EXEEXT)
        $(AM_V_CCLD)$(LINK) $(al175_OBJECTS) $(al175_LDADD) $(LIBS)

The reason is that there is a mis-assumption in the makefile:
# Avoid per-target CFLAGS, because this will prevent re-use of object
# files. In any case, CFLAGS are only -I options, so there is no harm,
# but only add them if we really use the target.
AM_CFLAGS = -I$(top_srcdir)/include $(am__append_1) $(am__append_2) \
        $(am__append_3) $(am__append_4) $(am__append_5)

In am__append_2 are the cflags which carry "no-pie-compile.specs" but on the link stage they only propagate to the target that matters (snmp_ups).

That mismatch causes the breakage as CFLAGS are not "In any case, CFLAGS are only -I options, so there is no harm".

Revision history for this message
Launchpad Janitor (janitor) wrote :

This bug was fixed in the package nut - 2.7.4-5ubuntu4

---------------
nut (2.7.4-5ubuntu4) artful; urgency=medium

  * d/p/fix-snmp-driver-compile-options.patch: fix cflags/ldflags
    mismatch (LP: #1711092).
  * d/libnutclient0.symbols: fix symbols in regard to gcc-7 (LP: #1711091).

 -- Christian Ehrhardt <email address hidden> Wed, 16 Aug 2017 12:44:26 +0200

Changed in nut (Ubuntu):
status: New → Fix Released
To post a comment you must log in.
This report contains Public information  
Everyone can see this information.

Other bug subscribers

Remote bug watches

Bug watches keep track of this bug in other bug trackers.