Hi!

[ See also my other reply to Eric. ]

On Mon, 2024-04-01 at 20:29:59 +0200, Bruno Haible wrote:
> Guillem Jover wrote in
> <https://lists.gnu.org/archive/html/bug-autoconf/2024-03/msg00000.html>:
> > > While analyzing the recent xz backdoor hook into the build system [A],
> > > I noticed that one of the aspects why the hook worked was because it
> > > seems like «autoreconf -f -i» (that is run in Debian as part of
> > > dh-autoreconf via dh) still seems to take the serial into account,
> > > which was bumped in the tampered .m4 file. If either the gettext.m4
> > > had gotten downgraded (to the version currently in Debian, which would
> > > not have pulled the tampered build-to-host.m4), or once Debian upgrades
> > > gettext, the build-to-host.m4 would get downgraded to the upstream
> > > clean version, then the hook would have been disabled and the backdoor
> > > would be inert. (Of course at that point the malicious actor would
> > > have found another way to hook into the build system, but the less
> > > avenues there are the better.)
> > > 
> > > I've tried to search the list and checked for old bug reports on the
> > > debbugs.gnu.org site, but didn't notice anything. To me this looks like
> > > a very unexpected behavior, but it's not clear whether this is intentional
> > > or a bug. In any case regardless of either position, it would be good to
> > > improve this (either by fixing --force to force things even if
> > > downgrading, or otherwise perhaps to add a new option to really force
> > > everything).
> > > 
> > > [A] <https://lists.debian.org/debian-devel/2024/03/msg00367.html>
> > >     Longish mail, search for "try to go in detail" for the analysis.
> 
> The 'serial' number in *.m4 files exists precisely so that tools like
> 'aclocal --install' or (as you say) 'autoreconf -f -i' can avoid
> overwriting newer .m4 files with older versions.

As mentioned in my other reply, I think taking the serial into account
in non-force mode makes total sense. But when using --force the
current behavior does not. The option description says:

    -f, --force     consider all generated and standard files obsolete

which to me would imply the serial should be considered missing or as
if set to 0 or equivalent.

> The situation is:
>   - Debian stable is still on gettext 0.21, which comes with
>       gettext.m4 serial 71

(This does not change much because in Debian stable and unstable
are both 0.21, but the packages go through unstable and that's where
this incident happened in Debian.)

>   - gettext-0.22 comes with
>       gettext.m4 serial 77
>     which depends on build-to-host.m4.
> Assume furthermore that a package P relies on gettext (via AM_GNU_GETTEXT),
> and the user has installed gettext-0.22 or newer. And they run
>   $ autoreconf
> which invokes autopoint, which installs the gettext.m4.
> 
> If, in this situation, the newer .m4 file would not prevail, Debian's
> old gettext.m4 would take precedence. This would mean that new features
> from new gettext releases would not land in the users' hands; they
> would be blocked by Debian, for the time the user uses this distro+version
> (often 4 or 5 years).

If someone runes «autoreconf» or «autoreconf -i» I'd expect the serial
to be honored and .m4 files to not ever get downgraded (whether they
should always get upgraded I don't have an opinion at this point).

From an upstream PoV I sympathize with a desire to not lose features,
but then autotools are intended precisely to cope with old systems
with whatever might or might not be present and at different versions
and feature sets.

But if as a downstream distribution I explicitly request everything to
be considered obsolete via --force, then I really do want to get whatever
is in the system instead of in the upstream package. Because then I
can fix things centrally in a distribution dependency package, instead
of having to wait for upstreams to do so, for example, or because then I
have a higher chance of building from known system files instead of
local stuff.

> Worse, this would also hold for Red Hat distro releases, which typically
> are not 4-5 years, but 10-12 years behind the newest release. It would
> mean that *for 10 years*, packages P could not make use of new features
> (and bug fixes) that were added in GNU gettext upstream.

I'm not sure, but I think this is perhaps conflating the roles of the
distribution packages (which would have been frozen at the time they
got added to that release anyway), and of a user of such distribution
long after that release was done? For the latter I agree they should
have the choice, and to me that involves whether they use for example
«autoreconf -i» vs «autoreconf -f -i», or even no autoreconf at all!

> This is the problem that the 'serial' number annotation fixes.

I'm not denying the serial number solves problems! In case that was
not clear. :) I'm also using serial numbers in my own upstream .m4
files.

> It may be unexpected to you, but it is very much intended.

The only unexpected part (which I perhaps failed to convey) was that
it is being taken into account with --force.

> And if aclocal's preference was the other way around, always favouring
> the smaller serial number, then the attacker would not have picked
> 'serial 30' but 'serial 1', in order to override the distro's version.

IMO if I use --force, I'd expect the serial to no be taken into account
at all, and not simply reverse its logic and look for downgrades (I'd
also find that behavior very unexpected). I'd expect any local file to
be ignore and replaced by the system ones.

> > In light of this weekend's mess, Bruno may have more ideas about
> > how to prevent his files from being turned into backdoor delivery
> > mechanisms in the future.
> 
> I gave my opinion here:
>   https://lists.gnu.org/archive/html/bug-gnulib/2024-03/msg00422.html
>   https://lists.gnu.org/archive/html/bug-gnulib/2024-03/msg00421.html
> 
> Basically I think that an attacker who is clever enough to bypass the
> RELRO protection by using IFUNC, knowing that IFUNC gets processed
> _before_ the GOT or PLT pages are made read-only, — such an attacker
> will also find ways to conceal their malware triggers, regardless of
> any simple measures at the source code level that we might invent.

I think I mentioned as much in the debian-devel thread, but I still
think that putting as many roadblocks as possible (as long as that
does not make normal development and user cumbersome) seems also
worthwhile, more so when most of what we deal with is based on a
trusting model. In addition in this case I also see benefits to
the --force behavior actually forcing things, from a distribution
PoV, so fixing/changing this seems like an added bonus from various
angles.

Thanks,
Guillem

Reply via email to