zsh-workers
 help / color / mirror / code / Atom feed
* [Bug] modules zsh/tcp, zsh/zftp unloadable, probably affecting most modern Linuxes
@ 2023-06-04 13:51 Marcus Müller
  2023-06-04 20:37 ` Marcus Müller
  0 siblings, 1 reply; 17+ messages in thread
From: Marcus Müller @ 2023-06-04 13:51 UTC (permalink / raw)
  To: zsh-workers

Dear ZSH community,

I just opened a Fedora bug[1], since I suspected this to a configuration-vs-facts mistake 
in the build, but it turns out that this happens on debian, too, and that I can see in the 
source code that the offending function is actually used – which should have made linkage 
fail, but it only does so at dynamic runtime linking.

Don't really know how to go from there – someone would have to rework name resolution to 
use getaddrinfo/freeaddrinfo (which is POSIX) instead of getipnodebyname/freehostent 
(which isn't POSIX).

I see that this already happened, in 2007, in commit 
a5187bb6ac96cc43f68367c5dc9332854c250713, "23670: use getaddrinfo() and getnameinfo() 
instead of get*by* functions.", but was promptly reverted 30 minutes later without 
explanation. Maybe it's time to revisit that? Maybe it's also just a sign that the code 
hasn't been used by anyone in roughly forever, and deserves to be not built on the 
platforms it doesn't support, or removed altogether.

Bug description:

when running `zmodload zsh/zftp`, it fails due to missing symbol `freehostent`. This is 
worrisome, because a) that's a broken feature, and b) `freehostent` shouldn't be used on 
glibc systems (far as I can tell) – `man freehostent` tells us that the function is *not* 
present in glibc and deprecated.

Steps to Reproduce:
1. clean F37 or F38 or debian stable installation
2. `sudo dnf --refresh install -y zsh`
3. `zsh`
4. in zsh: `zmodload zsh/zftp`

Actual Results:
zsh: failed to load module `zsh/zftp': /usr/lib64/zsh/5.9/zsh/zftp.so: undefined symbol: 
freehostent

Expected Results:
loading of module

Best regards,
Marcus Müller


[1] https://bugzilla.redhat.com/show_bug.cgi?id=2212160



^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: [Bug] modules zsh/tcp, zsh/zftp unloadable, probably affecting most modern Linuxes
  2023-06-04 13:51 [Bug] modules zsh/tcp, zsh/zftp unloadable, probably affecting most modern Linuxes Marcus Müller
@ 2023-06-04 20:37 ` Marcus Müller
  2023-06-04 21:17   ` Philippe Troin
  2023-06-04 22:41   ` Axel Beckert
  0 siblings, 2 replies; 17+ messages in thread
From: Marcus Müller @ 2023-06-04 20:37 UTC (permalink / raw)
  To: zsh-workers

Bit more debugging: Doesn't work with Fedora 30 / glibc 2.29, does work with OpenSUSE leap 
15.2 / glibc 2.26.

For that reason I must assume the regression must have appeared between release 2.26 in 
August 2017 and release 2.29 in Februrary 2019.

On 04.06.23 15:51, Marcus Müller wrote:
> Dear ZSH community,
>
> I just opened a Fedora bug[1], since I suspected this to a configuration-vs-facts 
> mistake in the build, but it turns out that this happens on debian, too, and that I can 
> see in the source code that the offending function is actually used – which should have 
> made linkage fail, but it only does so at dynamic runtime linking.
>
> Don't really know how to go from there – someone would have to rework name resolution to 
> use getaddrinfo/freeaddrinfo (which is POSIX) instead of getipnodebyname/freehostent 
> (which isn't POSIX).
>
> I see that this already happened, in 2007, in commit 
> a5187bb6ac96cc43f68367c5dc9332854c250713, "23670: use getaddrinfo() and getnameinfo() 
> instead of get*by* functions.", but was promptly reverted 30 minutes later without 
> explanation. Maybe it's time to revisit that? Maybe it's also just a sign that the code 
> hasn't been used by anyone in roughly forever, and deserves to be not built on the 
> platforms it doesn't support, or removed altogether.
>
> Bug description:
>
> when running `zmodload zsh/zftp`, it fails due to missing symbol `freehostent`. This is 
> worrisome, because a) that's a broken feature, and b) `freehostent` shouldn't be used on 
> glibc systems (far as I can tell) – `man freehostent` tells us that the function is 
> *not* present in glibc and deprecated.
>
> Steps to Reproduce:
> 1. clean F37 or F38 or debian stable installation
> 2. `sudo dnf --refresh install -y zsh`
> 3. `zsh`
> 4. in zsh: `zmodload zsh/zftp`
>
> Actual Results:
> zsh: failed to load module `zsh/zftp': /usr/lib64/zsh/5.9/zsh/zftp.so: undefined symbol: 
> freehostent
>
> Expected Results:
> loading of module
>
> Best regards,
> Marcus Müller
>
>
> [1] https://bugzilla.redhat.com/show_bug.cgi?id=2212160
>


^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: [Bug] modules zsh/tcp, zsh/zftp unloadable, probably affecting most modern Linuxes
  2023-06-04 20:37 ` Marcus Müller
@ 2023-06-04 21:17   ` Philippe Troin
  2023-06-05 19:35     ` Marcus Müller
  2023-06-04 22:41   ` Axel Beckert
  1 sibling, 1 reply; 17+ messages in thread
From: Philippe Troin @ 2023-06-04 21:17 UTC (permalink / raw)
  To: Marcus Müller, zsh-workers

On Sun, 2023-06-04 at 22:37 +0200, Marcus Müller wrote:
> 
> On 04.06.23 15:51, Marcus Müller wrote:
> > Steps to Reproduce:
> > 1. clean F37 or F38 or debian stable installation
> > 2. `sudo dnf --refresh install -y zsh`
> > 3. `zsh`
> > 4. in zsh: `zmodload zsh/zftp`
> > 
> > Actual Results:
> > zsh: failed to load module `zsh/zftp': /usr/lib64/zsh/5.9/zsh/zftp.so: undefined symbol: 
> > freehostent

Interestingly:

   % zsh -f
   % echo $ZSH_VERSION 
   5.9
   % rpm -q zsh
   zsh-5.9-5.fc38.x86_64
   % zmodload zsh/zftp
   zsh: failed to load module `zsh/zftp': /usr/lib64/zsh/5.9/zsh/zftp.so: undefined symbol: freehostent
   % autoload zfinit
   % zfinit
   % zmodload zsh/zftp
   % zmodload
   zsh/compctl
   zsh/complete
   zsh/main
   zsh/net/tcp
   zsh/zftp
   zsh/zle
   zsh/zutil
   
If you look at zfinit, it loads zsh/net/tcp first.

   % zsh -f
   % zmodload zsh/net/tcp
   % zmodload zsh/zftp   
   
freehostent is defined in zsh/net/tcp:

   % nm --dynamic /usr/lib64/zsh/5.9/zsh/net/tcp.so| grep freehostent
   00000000000027c0 T freehostent

Since I think you're supposed to initialize zftp through zfinit, I do
not think this qualifies as a bug.
But the freehostent symbol in zsh/net/tcp.so feels a little funky.

Phil.



^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: [Bug] modules zsh/tcp, zsh/zftp unloadable, probably affecting most modern Linuxes
  2023-06-04 20:37 ` Marcus Müller
  2023-06-04 21:17   ` Philippe Troin
@ 2023-06-04 22:41   ` Axel Beckert
  1 sibling, 0 replies; 17+ messages in thread
From: Axel Beckert @ 2023-06-04 22:41 UTC (permalink / raw)
  To: zsh-workers

Hi,

Debian's zsh maintainer writing here.

On Sun, Jun 04, 2023 at 10:37:21PM +0200, Marcus Müller wrote:
> Bit more debugging: Doesn't work with Fedora 30 / glibc 2.29, does work with
> OpenSUSE leap 15.2 / glibc 2.26.
> 
> For that reason I must assume the regression must have appeared between
> release 2.26 in August 2017 and release 2.29 in Februrary 2019.

Can confirm that this is reproducible on Debian 9 Stretch, 10 Buster,
11 Bullseye, 12 Bookworm (and testing/unstable as of now).

It does not happen in Debian 8 Jessie.

On Sun, Jun 04, 2023 at 02:17:30PM -0700, Philippe Troin wrote:
> > > 4. in zsh: `zmodload zsh/zftp`
> > > 
> > > Actual Results:
> > > zsh: failed to load module `zsh/zftp': /usr/lib64/zsh/5.9/zsh/zftp.so: undefined symbol: 
> > > freehostent
> 
> Interestingly:
> 
>    % zsh -f
>    % echo $ZSH_VERSION 
>    5.9
>    % rpm -q zsh
>    zsh-5.9-5.fc38.x86_64
>    % zmodload zsh/zftp
>    zsh: failed to load module `zsh/zftp': /usr/lib64/zsh/5.9/zsh/zftp.so: undefined symbol: freehostent
>    % autoload zfinit
>    % zfinit
>    % zmodload zsh/zftp
>    % zmodload
>    zsh/compctl
>    zsh/complete
>    zsh/main
>    zsh/net/tcp
>    zsh/zftp
>    zsh/zle
>    zsh/zutil
>    
> If you look at zfinit, it loads zsh/net/tcp first.
> 
>    % zsh -f
>    % zmodload zsh/net/tcp
>    % zmodload zsh/zftp   

Can confirm this on at least Debian 12, too. (Haven't tested elsewhere.)

> Since I think you're supposed to initialize zftp through zfinit, I do
> not think this qualifies as a bug.

Depends. zshzftpsys(1) says in its second paragraph:

  If the shell is configured to load new commands at run time, it
  probably is: typing `zmodload zsh/zftp' will make sure (if that runs
  silently, it has worked).

So this suggests that "zmodload zsh/zftp" suffices. (And I think
there's something missing in that sentence behind "will make sure
(…)".)

Then again in the "INSTALLATION" some paragraphs later, there's

  fpath=(~/myfns $fpath)
  autoload -U zfinit
  zfinit

mentioned, but it seems only necessary if zftp didn't come
preinstalled.

So it still looks like a bug to me, just one with an easy workaround.

		Kind regards, Axel
-- 
PGP: 2FF9CD59612616B5      /~\  Plain Text Ribbon Campaign, http://arc.pasp.de/
Mail: abe@deuxchevaux.org  \ /  Say No to HTML in E-Mail and Usenet
Mail+Jabber: abe@noone.org  X
https://axel.beckert.ch/   / \  I love long mails: https://email.is-not-s.ms/


^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: [Bug] modules zsh/tcp, zsh/zftp unloadable, probably affecting most modern Linuxes
  2023-06-04 21:17   ` Philippe Troin
@ 2023-06-05 19:35     ` Marcus Müller
  2023-06-05 20:07       ` Bart Schaefer
  0 siblings, 1 reply; 17+ messages in thread
From: Marcus Müller @ 2023-06-05 19:35 UTC (permalink / raw)
  To: Philippe Troin, Marcus Müller, zsh-workers

Hi Phil,

thanks for the follow-up:

On 6/4/23 23:17, Philippe Troin wrote:
> Interestingly:
>     % zsh -f
>     % echo $ZSH_VERSION
>     5.9
>     % rpm -q zsh
>     zsh-5.9-5.fc38.x86_64
>     % zmodload zsh/zftp
>     zsh: failed to load module `zsh/zftp': /usr/lib64/zsh/5.9/zsh/zftp.so: undefined symbol: freehostent
>     % autoload zfinit
>     % zfinit
>     % zmodload zsh/zftp
ah, ok, that's how it's supposed to work? Shouldn't the module then not 
trigger some warning or specific error on load, before the dynamic 
loader runs and fails?
> freehostent is defined in zsh/net/tcp:
>
>     % nm --dynamic /usr/lib64/zsh/5.9/zsh/net/tcp.so| grep freehostent
>     00000000000027c0 T freehostent

Hui. Looking into tcp.c:197, that function is

---

/**/
mod_export void
freehostent(UNUSED(struct hostent *ptr))
{
}

---

Why is that not calling `free`? Oh, very simple, because above, the 
comment near the getipnodebyname implementation says:

---

/* note: this is not a complete implementation.  If ignores the flags,
    and does not provide the memory allocation of the standard interface.
    Each returned structure will overwrite the previous one. */

---

Ah, so we're exporting and thus overwriting a symbol that overwrites a 
pointer by the name of an existing libc function with a "overrides 
potentially unowned memory" one?

That sounds a tad undesirable in the grander scheme of things :)

Since the only use of this function pair (zsh_getipnodebyname, 
freehostent) is to be used internally in zfinit'ed modules, and the 
number of internal consumers is zftp.c, could I propose we just rename 
`freehostent` to `zsh_freehostent`? That would sound less invasive, and 
would at least send the next person not down the tracks looking for libc 
anachronisms (not blaming anyone but me for going down that road) ;-)

> Since I think you're supposed to initialize zftp through zfinit, I do
> not think this qualifies as a bug.
Hm, yeah, surprising to me, but probably documented somewhere well enough.
> But the freehostent symbol in zsh/net/tcp.so feels a little funky.

I'd agree, see above

Cheers,
Marcus



^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: [Bug] modules zsh/tcp, zsh/zftp unloadable, probably affecting most modern Linuxes
  2023-06-05 19:35     ` Marcus Müller
@ 2023-06-05 20:07       ` Bart Schaefer
  2023-06-06  6:42         ` Jun T
  2023-06-07  9:25         ` Marcus Müller
  0 siblings, 2 replies; 17+ messages in thread
From: Bart Schaefer @ 2023-06-05 20:07 UTC (permalink / raw)
  To: Marcus Müller; +Cc: Philippe Troin, zsh-workers

On Mon, Jun 5, 2023 at 12:35 PM Marcus Müller <marcus_zsh@hostalia.de> wrote:
>
> Ah, so we're exporting and thus overwriting a symbol that overwrites a
> pointer by the name of an existing libc function with a "overrides
> potentially unowned memory" one?

As I understand it that symbol will only be defined by tcp.c if it's
not available from libc or other linked library, so it's not actually
overwriting an identically-named symbol.

Or at least that's the intention, the #ifdef's that are meant to
accomplish it may need refinement for more recent library changes.


^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: [Bug] modules zsh/tcp, zsh/zftp unloadable, probably affecting most modern Linuxes
  2023-06-05 20:07       ` Bart Schaefer
@ 2023-06-06  6:42         ` Jun T
  2023-06-06  9:05           ` Peter Stephenson
  2023-06-07  9:25         ` Marcus Müller
  1 sibling, 1 reply; 17+ messages in thread
From: Jun T @ 2023-06-06  6:42 UTC (permalink / raw)
  To: zsh-workers


> 2023/06/06 5:07, Bart Schaefer <schaefer@brasslantern.com> wrote:
> 
> As I understand it that symbol will only be defined by tcp.c if it's
> not available from libc or other linked library, so it's not actually
> overwriting an identically-named symbol.

Yes, I agree, and I think the problem is not in 'freehostent'.
I guess the error 'undefined symbol: freehostent' just indicates
that 'freehostent' was the _first_ symbol the loader couldn't resolve
(and the loader gave up, not trying to resolve other symbols such
as zsh_getipnodebyname etc.).

But, first of all, why these symbols need be resolved when loading
zftp.so, because dlopen() is called as:
  dlopen("zftp.so", RTLD_LAZY | RTLD_GLOBAL)  (module.c:1596)
i.e., with the flag RTLD_LAZY?

If I build zsh by myself on Debian/Ubuntu/Fedora/CentOS
then 'zmodload zsh/zftp' works fine.

I don't know how the packages (deb/rpm) are built, but I found
a build log of zsh5.9 for Fedora38:
https://kojipkgs.fedoraproject.org//packages/zsh/5.9/5.fc38/data/logs/x86_64/build.log

The part of the log for creating zftp.so is:

gcc -Wl,-z,relro -Wl,--as-needed  -Wl,-z,now \
 (snip)
  -z lazy -shared -o zftp.so   zftp..o \
  -lpcre -ldl -lncursesw -lrt -lm  -lc 

I think the problem is '-Wl,-z,now'. man ld(1) says:

   now When generating an executable or shared library, mark it to
       tell the dynamic linker to resolve all symbols when the program
       is started, or when the shared library is loaded by dlopen,
       instead of deferring function call resolution to the point when
       the function is first called.

It seems this option has the higher precedence than the option
'-z lazy' in the same command line, or the RTLD_LAZY for dlopen().

On Fedora-38:
% readelf --dynamic /usr/lib64/zsh/5.9/zsh/zftp.so | grep FLAG
 0x000000000000001e (FLAGS)              BIND_NOW
 0x000000006ffffffb (FLAGS_1)            Flags: NOW

I think this flag in zftp.so is the result of '-z now'

On Debian-11, /usr/lib/x86_64-linux-gnu/zsh/5.8/zsh/zftp.so has the
same flag. I guess Debian binary package is also built with '-z now'.

The zftp.so built by myself does not have this flag.

Why '-z now' is used when building binary packages? For security?

^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: [Bug] modules zsh/tcp, zsh/zftp unloadable, probably affecting most modern Linuxes
  2023-06-06  6:42         ` Jun T
@ 2023-06-06  9:05           ` Peter Stephenson
  2023-06-06 14:38             ` Jun. T
  0 siblings, 1 reply; 17+ messages in thread
From: Peter Stephenson @ 2023-06-06  9:05 UTC (permalink / raw)
  To: zsh-workers

> On 06/06/2023 07:42 Jun T <takimoto-j@kba.biglobe.ne.jp> wrote:
> I think the problem is '-Wl,-z,now'. man ld(1) says:
> 
>    now When generating an executable or shared library, mark it to
>        tell the dynamic linker to resolve all symbols when the program
>        is started, or when the shared library is loaded by dlopen,
>        instead of deferring function call resolution to the point when
>        the function is first called.
> 
> It seems this option has the higher precedence than the option
> '-z lazy' in the same command line, or the RTLD_LAZY for dlopen().
> 
> On Fedora-38:
> % readelf --dynamic /usr/lib64/zsh/5.9/zsh/zftp.so | grep FLAG
>  0x000000000000001e (FLAGS)              BIND_NOW
>  0x000000006ffffffb (FLAGS_1)            Flags: NOW
> 
> I think this flag in zftp.so is the result of '-z now'
> 
> On Debian-11, /usr/lib/x86_64-linux-gnu/zsh/5.8/zsh/zftp.so has the
> same flag. I guess Debian binary package is also built with '-z now'.
> 
> The zftp.so built by myself does not have this flag.
> 
> Why '-z now' is used when building binary packages? For security?

I think this is just so that failure to find symbols at all will
show up quickly in the build rather than at run time, which would
be a real pain.

One solution might be to build first with -z now to confirm that it
does link, and then -z lazy to make it more useful when installed.

pws


^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: [Bug] modules zsh/tcp, zsh/zftp unloadable, probably affecting most modern Linuxes
  2023-06-06  9:05           ` Peter Stephenson
@ 2023-06-06 14:38             ` Jun. T
  2023-06-06 15:01               ` Peter Stephenson
  0 siblings, 1 reply; 17+ messages in thread
From: Jun. T @ 2023-06-06 14:38 UTC (permalink / raw)
  To: zsh-workers


> 2023/06/06 18:05, Peter Stephenson <p.w.stephenson@ntlworld.com> wrote:
> 
>> On 06/06/2023 07:42 Jun T <takimoto-j@kba.biglobe.ne.jp> wrote:
>> 
>> Why '-z now' is used when building binary packages? For security?
> 
> I think this is just so that failure to find symbols at all will
> show up quickly in the build rather than at run time, which would
> be a real pain.

I think '-z now' is to mark (add the flag) zftp.so so that the
dynamic linker resolves all the symbols when _loading_ it;
the symbols are not resolved when _building_ zftp.so.


^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: [Bug] modules zsh/tcp, zsh/zftp unloadable, probably affecting most modern Linuxes
  2023-06-06 14:38             ` Jun. T
@ 2023-06-06 15:01               ` Peter Stephenson
  2023-06-06 16:37                 ` Philippe Troin
  0 siblings, 1 reply; 17+ messages in thread
From: Peter Stephenson @ 2023-06-06 15:01 UTC (permalink / raw)
  To: zsh-workers

> On 06/06/2023 15:38 Jun. T <takimoto-j@kba.biglobe.ne.jp> wrote:
> 
>  
> > 2023/06/06 18:05, Peter Stephenson <p.w.stephenson@ntlworld.com> wrote:
> > 
> >> On 06/06/2023 07:42 Jun T <takimoto-j@kba.biglobe.ne.jp> wrote:
> >> 
> >> Why '-z now' is used when building binary packages? For security?
> > 
> > I think this is just so that failure to find symbols at all will
> > show up quickly in the build rather than at run time, which would
> > be a real pain.
> 
> I think '-z now' is to mark (add the flag) zftp.so so that the
> dynamic linker resolves all the symbols when _loading_ it;
> the symbols are not resolved when _building_ zftp.so.

Yes, it does say it gets applied at the point of dlopen(), so it's
explicitly counteracting RTLD_LAZY.

Is this specific to the Fedora configuration in their own source
package?  I don't see an obvious sign the standard zsh build itself
is making this choice.  configure has some system-specific tweaks
for dynamic loading, but not this.

pws


^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: [Bug] modules zsh/tcp, zsh/zftp unloadable, probably affecting most modern Linuxes
  2023-06-06 15:01               ` Peter Stephenson
@ 2023-06-06 16:37                 ` Philippe Troin
  2023-06-06 17:54                   ` Mikael Magnusson
  0 siblings, 1 reply; 17+ messages in thread
From: Philippe Troin @ 2023-06-06 16:37 UTC (permalink / raw)
  To: zsh-workers

On Tue, 2023-06-06 at 16:01 +0100, Peter Stephenson wrote:
> > On 06/06/2023 15:38 Jun. T <takimoto-j@kba.biglobe.ne.jp> wrote:
> > 
> >  
> > > 2023/06/06 18:05, Peter Stephenson <p.w.stephenson@ntlworld.com>
> > > wrote:
> > > 
> > > > On 06/06/2023 07:42 Jun T <takimoto-j@kba.biglobe.ne.jp> wrote:
> > > > 
> > > > Why '-z now' is used when building binary packages? For
> > > > security?
> > > 
> > > I think this is just so that failure to find symbols at all will
> > > show up quickly in the build rather than at run time, which would
> > > be a real pain.
> > 
> > I think '-z now' is to mark (add the flag) zftp.so so that the
> > dynamic linker resolves all the symbols when _loading_ it;
> > the symbols are not resolved when _building_ zftp.so.
> 
> Yes, it does say it gets applied at the point of dlopen(), so it's
> explicitly counteracting RTLD_LAZY.
> 
> Is this specific to the Fedora configuration in their own source
> package?  I don't see an obvious sign the standard zsh build itself
> is making this choice.  configure has some system-specific tweaks
> for dynamic loading, but not this.

"-z now" is automatically added to all builds by the hardening
configuration on RedHat/Fedora and possibly derived distributions:

   % ag -- -Wl.*now /usr/lib/rpm/
   /usr/lib/rpm/macros.d/macros.rust
   46:  -Clink-arg=-Wl,-z,now
   
   /usr/lib/rpm/redhat/macros
   302:%_hardening_ldflags	 -Wl,-z,now %[ "%{toolchain}" == "gcc" ? "-specs=/usr/lib/rpm/redhat/redhat-hardened-ld" : "" ]

Phil.



^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: [Bug] modules zsh/tcp, zsh/zftp unloadable, probably affecting most modern Linuxes
  2023-06-06 16:37                 ` Philippe Troin
@ 2023-06-06 17:54                   ` Mikael Magnusson
  2023-06-07  2:05                     ` Jun T
  0 siblings, 1 reply; 17+ messages in thread
From: Mikael Magnusson @ 2023-06-06 17:54 UTC (permalink / raw)
  To: Philippe Troin; +Cc: zsh-workers

On 6/6/23, Philippe Troin <phil@fifi.org> wrote:
> On Tue, 2023-06-06 at 16:01 +0100, Peter Stephenson wrote:
>> > On 06/06/2023 15:38 Jun. T <takimoto-j@kba.biglobe.ne.jp> wrote:
>> >
>> >
>> > > 2023/06/06 18:05, Peter Stephenson <p.w.stephenson@ntlworld.com>
>> > > wrote:
>> > >
>> > > > On 06/06/2023 07:42 Jun T <takimoto-j@kba.biglobe.ne.jp> wrote:
>> > > >
>> > > > Why '-z now' is used when building binary packages? For
>> > > > security?
>> > >
>> > > I think this is just so that failure to find symbols at all will
>> > > show up quickly in the build rather than at run time, which would
>> > > be a real pain.
>> >
>> > I think '-z now' is to mark (add the flag) zftp.so so that the
>> > dynamic linker resolves all the symbols when _loading_ it;
>> > the symbols are not resolved when _building_ zftp.so.
>>
>> Yes, it does say it gets applied at the point of dlopen(), so it's
>> explicitly counteracting RTLD_LAZY.
>>
>> Is this specific to the Fedora configuration in their own source
>> package?  I don't see an obvious sign the standard zsh build itself
>> is making this choice.  configure has some system-specific tweaks
>> for dynamic loading, but not this.
>
> "-z now" is automatically added to all builds by the hardening
> configuration on RedHat/Fedora and possibly derived distributions:
>
>    % ag -- -Wl.*now /usr/lib/rpm/
>    /usr/lib/rpm/macros.d/macros.rust
>    46:  -Clink-arg=-Wl,-z,now
>
>    /usr/lib/rpm/redhat/macros
>    302:%_hardening_ldflags	 -Wl,-z,now %[ "%{toolchain}" == "gcc" ?
> "-specs=/usr/lib/rpm/redhat/redhat-hardened-ld" : "" ]

The zftp module's setup_ function is:
int
setup_(UNUSED(Module m))
{
    return (require_module("zsh/net/tcp", NULL, 0) == 1);
}

So the module providing the "missing" symbol will always be loaded
before any functions in zftp using it will be called, and there will
not be any failed symbol resolutions at runtime, which we indicate by
the RTLD_LAZY flag to dlopen().

The glibc manpage says
       RTLD_LAZY   Perform  lazy binding.  Resolve symbols only as the
code that references them
 is executed.  If the symbol is never referenced, then it is  never  resolved.

The posix manpage does not agree with the glibc manpage and says
       RTLD_LAZY   Relocations shall be performed at an
implementation-defined time,  ranging  from  the  time of the dlopen()
call until the first reference to a given symbol occurs.

Ie, it allows the behavior in Fedora.

I guess it would probably not be very hard to make this work on both
setups. Another workaround you (or the packager) could do in the
meantime is to statically link the tcp module.

-- 
Mikael Magnusson


^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: [Bug] modules zsh/tcp, zsh/zftp unloadable, probably affecting most modern Linuxes
  2023-06-06 17:54                   ` Mikael Magnusson
@ 2023-06-07  2:05                     ` Jun T
  2023-06-07  2:35                       ` Jun T
  0 siblings, 1 reply; 17+ messages in thread
From: Jun T @ 2023-06-07  2:05 UTC (permalink / raw)
  To: zsh-workers

I've found some related discussions:

zsh workers/37064
https://www.zsh.org/mla/workers/2015/msg02978.html

RedHat bugzilla #1277996 mentioned in workers/37064
https://bugzilla.redhat.com/1277996

Commit b5cac6b for zsh rpm source:
https://src.fedoraproject.org/rpms/zsh/c/b5cac6b431f08c03d2712fa9aac41b7cb43b9384

The bug #1277996 was exactly the same as the one we have now,
and it seems it was fixed by this commit at that time.
I guess 'gcc -z now -z lazy' worked as 'gcc -z lazy' in Fedora24 (2015),
but '-z now' has higher precedence now.



^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: [Bug] modules zsh/tcp, zsh/zftp unloadable, probably affecting most modern Linuxes
  2023-06-07  2:05                     ` Jun T
@ 2023-06-07  2:35                       ` Jun T
  2023-06-07 14:40                         ` Jun. T
  0 siblings, 1 reply; 17+ messages in thread
From: Jun T @ 2023-06-07  2:35 UTC (permalink / raw)
  To: zsh-workers


> 2023/06/07 11:05, I wrote:
> 
> I guess 'gcc -z now -z lazy' worked as 'gcc -z lazy' in Fedora24 (2015),
> but '-z now' has higher precedence now.

'-z lazy' does not work, but it seems '-Wl,-z,lazy' works, i.e.,
can overwrite '-Wl,-z,now'.

I've added this info to the RedHat bugzilla #2212160 started by
Marcus Müller:
https://bugzilla.redhat.com/show_bug.cgi?id=2212160

^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: [Bug] modules zsh/tcp, zsh/zftp unloadable, probably affecting most modern Linuxes
  2023-06-05 20:07       ` Bart Schaefer
  2023-06-06  6:42         ` Jun T
@ 2023-06-07  9:25         ` Marcus Müller
  1 sibling, 0 replies; 17+ messages in thread
From: Marcus Müller @ 2023-06-07  9:25 UTC (permalink / raw)
  To: Bart Schaefer; +Cc: Philippe Troin, zsh-workers

[-- Attachment #1: Type: text/plain, Size: 1492 bytes --]

Hey,

it looks like the Fedora crowd has decided that was a bug that surfaced already a while 
ago, which they then fixed, which then re-surfaced, as described in the newest comment on 
https://bugzilla.redhat.com/show_bug.cgi?id=2212160#c3 :

> This is the same bug as #1277996.
> It was fix by commit b5cac6b for zsh rpm by adding
> export LIBLDFLAGS='-z lazy'
> to zsh.spec.
>
> https://src.fedoraproject.org/rpms/zsh/c/b5cac6b431f08c03d2712fa9aac41b7cb43b9384
>
> But in recent Fedora '-z lazy' does not overwrite the '-Wl,-z,now'. It _seems_ we need to use '-Wl,-z,lazy'.
>
To summarize that #1277996 https://bugzilla.redhat.com/show_bug.cgi?id=1277996 , this 
*does* seem to actually be a bug:

https://www.zsh.org/mla/workers/2015/msg02981.html

Something must have reintroduced "now" instead of "lazy" linking in the module linking 
process.

Best,
Marcus

On 05.06.23 22:07, Bart Schaefer wrote:

> On Mon, Jun 5, 2023 at 12:35 PM Marcus Müller<marcus_zsh@hostalia.de>  wrote:
>> Ah, so we're exporting and thus overwriting a symbol that overwrites a
>> pointer by the name of an existing libc function with a "overrides
>> potentially unowned memory" one?
> As I understand it that symbol will only be defined by tcp.c if it's
> not available from libc or other linked library, so it's not actually
> overwriting an identically-named symbol.
>
> Or at least that's the intention, the #ifdef's that are meant to
> accomplish it may need refinement for more recent library changes.

[-- Attachment #2: Type: text/html, Size: 2713 bytes --]

^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: [Bug] modules zsh/tcp, zsh/zftp unloadable, probably affecting most modern Linuxes
  2023-06-07  2:35                       ` Jun T
@ 2023-06-07 14:40                         ` Jun. T
  2023-06-23 13:41                           ` Jun. T
  0 siblings, 1 reply; 17+ messages in thread
From: Jun. T @ 2023-06-07 14:40 UTC (permalink / raw)
  To: zsh-workers

It seems using linker options '-z relro -z now' is now a widely
used way for enhancing security; see for example:
https://www.redhat.com/ja/blog/hardening-elf-binaries-using-relocation-read-only-relro

Both RedHat/Fedora/CentOS and Debian/Ubuntu are now using
these options by default.

zsh rpm for Fedora 'gcc ... -z lazy' for overriding '-z now'.
# this is not working now, but '-Wl,-z,lazy' would work.

It seems Debian zsh package does not try to override '-z now'.

Whether accepting '-z lazy' or not is up to the distribution,
but if using '-z lazy' (partial RELRO) is not recommended
from security point of view, then we can just document that
net/tcp must be loaded before zftp.

^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: [Bug] modules zsh/tcp, zsh/zftp unloadable, probably affecting most modern Linuxes
  2023-06-07 14:40                         ` Jun. T
@ 2023-06-23 13:41                           ` Jun. T
  0 siblings, 0 replies; 17+ messages in thread
From: Jun. T @ 2023-06-23 13:41 UTC (permalink / raw)
  To: zsh-workers

load_module("zsh/zftp", ...) is so designed that if
add_dep("zsh/zftp", "zsh/net/tcp")
is called before calling it (for example in init.c) then tcp
module is loaded before loading zftp (module.c, line 2268).

The patch below modifies mkbltnmlst.sh so that it outputs
the add_dep() in bltinmods.list.

Please test on Linux with LDFLAGS='-Wl,-z,relro -Wl,-z,now'.


diff --git a/Src/Modules/zftp.c b/Src/Modules/zftp.c
index 49b3ffa89..47a5e9de9 100644
--- a/Src/Modules/zftp.c
+++ b/Src/Modules/zftp.c
@@ -3172,7 +3172,7 @@ static struct features module_features = {
 int
 setup_(UNUSED(Module m))
 {
-    return (require_module("zsh/net/tcp", NULL, 0) == 1);
+    return 0;
 }
 
 /**/
diff --git a/Src/mkbltnmlst.sh b/Src/mkbltnmlst.sh
index c4611d8b3..ea7d5ac3d 100644
--- a/Src/mkbltnmlst.sh
+++ b/Src/mkbltnmlst.sh
@@ -76,6 +76,30 @@ for x_mod in $x_mods; do
     test "x$linked" = xno && echo "#endif"
 done
 
+# if dynamic module 'mod' with load=no has moddeps in its .mdd,
+# then output add_dep(mod, dep) for each 'mod' in moddeps.
+dyn_mods="`grep ' link=dynamic .* load=no ' $CFMOD | \
+          sed -e '/^#/d' -e 's/ .*/ /' -e 's/^name=/ /'`"
+
+for mod in $dyn_mods; do
+    modfile="`grep '^name='$mod' ' $CFMOD | \
+              sed -e 's/^.* modfile=//' -e 's/ .*//'`"
+    if test "x$modfile" = x; then
+	echo >&2 "WARNING: no name for \`$mod' in $CFMOD (ignored)"
+	continue
+    fi
+    unset moddeps
+    . $srcdir/../$modfile
+    if test -n "$moddeps"; then
+        echo '#ifdef DYNAMIC'
+        echo "/* non-linked-in known module \`$mod' */"
+        for dep in $moddeps; do
+          echo "  add_dep(\"$mod\", \"$dep\");"
+        done
+        echo '#endif'
+    fi
+done
+
 echo
 done_mods=" "
 for bin_mod in $bin_mods; do




^ permalink raw reply	[flat|nested] 17+ messages in thread

end of thread, other threads:[~2023-06-23 13:42 UTC | newest]

Thread overview: 17+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2023-06-04 13:51 [Bug] modules zsh/tcp, zsh/zftp unloadable, probably affecting most modern Linuxes Marcus Müller
2023-06-04 20:37 ` Marcus Müller
2023-06-04 21:17   ` Philippe Troin
2023-06-05 19:35     ` Marcus Müller
2023-06-05 20:07       ` Bart Schaefer
2023-06-06  6:42         ` Jun T
2023-06-06  9:05           ` Peter Stephenson
2023-06-06 14:38             ` Jun. T
2023-06-06 15:01               ` Peter Stephenson
2023-06-06 16:37                 ` Philippe Troin
2023-06-06 17:54                   ` Mikael Magnusson
2023-06-07  2:05                     ` Jun T
2023-06-07  2:35                       ` Jun T
2023-06-07 14:40                         ` Jun. T
2023-06-23 13:41                           ` Jun. T
2023-06-07  9:25         ` Marcus Müller
2023-06-04 22:41   ` Axel Beckert

Code repositories for project(s) associated with this public inbox

	https://git.vuxu.org/mirror/zsh/

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).