This is the mail archive of the libc-alpha@sourceware.org mailing list for the glibc project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: [PATCH] Set behavior of sprintf-like functions with overlapping source and destination


* Jonathan Nieder:

> Learning from the GLIBC_2.14 memcpy,

I assume you've taken my observations in

  <https://sourceware.org/ml/libc-alpha/2018-12/msg00871.html>

into account.

> I wonder what our best option is.  I wonder if something like the
> following would be too complex:
>
>  1. Introduce GLIBC_2.29 printf that does *not* support this undefined
>     behavior.  Use __asm__(".symver [...]@@GLIBC_2.0") to ensure we
>     still default to the GLIBC_2.0 version even when building new
>     programs.
>
>  2. After a critical mass of users are using glibc 2.29 or newer (e.g.
>     after a year), switch the default version to GLIBC_2.29.
>
> What do you think?

So you want to introduce a compat symbol for GLIBC_2.29, but leave the
default symbol version at whatever version we have today?

Waiting a year (until a 2020 release—how time flies!) will not make a
substantial difference in deployment due to the release schedules of
distributions currently under development and their glibc version
choices.  That part is a non-starter, I'm afraid.  A multi-year delay
would make a difference, of course, but I'm not sure if that's
appropriate.  I think the most feasible course of action would be to
bundle several such changes together, so that the impact is felt only
once.

Historically, we have used symbol versioning (in the sense that we
changed the default symbol version) for two different situations:

(1) A type changed size or a function changed its prototype in a
    binary-incompatible way, usually prompted by a desire to increase
    standards conformance.

(2) A function changed behavior and existing software broke.

memcpy@GLIBC_2.14 is clearly in the second category.  A more recent
example is glob@GLIBC_2.27.

The key difference between (1) and (2) is that rebuilding existing
software for (1) either works as before, or you get at a compiler
error and have to apply a simple fix.  For (2), on the other hand, the
bug is still there, and recompilation reintroduces it.

Over the years, I have come to the realization that (2) really only
benefits proprietary software, and unmaintained proprietary software
at that.  We still receive bug reports about the glob@GLIBC_2.27
transition because people try to build the wrong version of GNU make
on glibc 2.27 or later.  I would say that using symbol versioning to
make such backwards-incompatible changes is very confusing and may not
be worth it.  Instead, we should make the change without introducing a
symbol version (to treat everyone the same), or not make the change at
all.

The sprintf change clearly is in category (2).  However, there's a
mitigation circumstance: Distributions already build with
_FORTIFY_SOURCE (at least they try to), so they are largely exposed to
the new behavior.  So I'd expect that in this particular case, the
recompilation problem would largely affect unpackaged, in-house
software.  Maybe this makes the change more acceptable and could
actually justify introducing a symbol version in this case?


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]