Bug 2203863
Summary: | php: Should not use RTLD_DEEPBIND for opening extension modules | ||
---|---|---|---|
Product: | [Fedora] Fedora | Reporter: | Ralf Ertzinger <redhat-bugzilla> |
Component: | php | Assignee: | Remi Collet <fedora> |
Status: | CLOSED EOL | QA Contact: | Fedora Extras Quality Assurance <extras-qa> |
Severity: | medium | Docs Contact: | |
Priority: | unspecified | ||
Version: | 38 | CC: | dmalcolm, fedora, fweimer, jakub, jlaw, jorton, jwakely, mcermak, mpolacek, msebor, nickc, sipoyare |
Target Milestone: | --- | ||
Target Release: | --- | ||
Hardware: | x86_64 | ||
OS: | Linux | ||
Whiteboard: | |||
Fixed In Version: | Doc Type: | If docs needed, set a value | |
Doc Text: | Story Points: | --- | |
Clone Of: | Environment: | ||
Last Closed: | 2024-05-22 10:58:21 UTC | Type: | --- |
Regression: | --- | Mount Type: | --- |
Documentation: | --- | CRM: | |
Verified Versions: | Category: | --- | |
oVirt Team: | --- | RHEL 7.3 requirements from Atomic Host: | |
Cloudforms Team: | --- | Target Upstream Version: | |
Embargoed: |
Description
Ralf Ertzinger
2023-05-15 13:39:59 UTC
If environ is NULL, it is IMNSHO a bug in whatever program changed that pointer to NULL. There's also a glibc bug in this area, when dlopen is called from a preinit function. Not sure if this applies in this case. Setting a hardware watchpoint on the environ variable should be illuminating. But `environ` is not NULL, that's the strange thing. `environ` points to a, as far as I can tell, completely valid environment structure. ``` >>> print environ $1 = (char **) 0x55555564ca70 >>> print env $2 = (char **) 0x0 >>> print *(environ) $3 = 0x555555648e60 "SHELL=/bin/bash" ``` This is the disassembly around the error: ``` 0x00007ffff5909a13 <+99>: mov rax,QWORD PTR [rip+0x4559e] # 0x7ffff594efb8 0x00007ffff5909a1a <+106>: pxor xmm0,xmm0 0x00007ffff5909a1e <+110>: mov WORD PTR [rbp+0x54],0x100 0x00007ffff5909a24 <+116>: lea r14,[rbp+0x8] 0x00007ffff5909a28 <+120>: movups XMMWORD PTR [rbp+0x8],xmm0 0x00007ffff5909a2c <+124>: movdqa xmm1,XMMWORD PTR [rip+0x363bc] # 0x7ffff593fdf0 0x00007ffff5909a34 <+132>: lea r13,[rip+0x358d4] # 0x7ffff593f30f 0x00007ffff5909a3b <+139>: mov r15,QWORD PTR [rax] 0x00007ffff5909a3e <+142>: mov QWORD PTR [rbp+0x48],0xffffffffffffffff 0x00007ffff5909a46 <+150>: mov BYTE PTR [rbp+0x56],0x0 0x00007ffff5909a4a <+154>: movups XMMWORD PTR [rbp+0x28],xmm0 => 0x00007ffff5909a4e <+158>: mov r12,QWORD PTR [r15] ``` `[r15]` blows up, because `r15` is 0. This gets loaded from `[rax]` four lines above, and `rax` in turn was loaded from a `rip` relative position at the start. This looks like the assembly expects `[rip+0x4559e]` to be the memory location where `environ` is, but that's not where it is? I'm not really useful with gdb, I admit. It's due to use of RTLD_DEEPBIND in php: # define DL_LOAD(libname) dlopen(libname, PHP_RTLD_MODE | RTLD_GLOBAL | RTLD_DEEPBIND) RTLD_DEEPBIND changes the binding of environ in libc.so.6 from the main executable (present there because of a copy relocation, and correctly initialized) to the previously dormant symbol in libc.so.6 (which is uninitialized). GDB doesn't really handle this rebinding, which is why environ shows up as not NULL. Ideally, php would stop using RTLD_DEEPBIND. If this is not possible, you can build the main program (uswgi in this case) as PIC, not PIE, which avoids copy relocations. Is there another can of worms that I'd open with the PIE/PIC change? Is that a change that's required for uwsgi as a whole (binary and dynamically loadable modules), or just for the php module? (In reply to Ralf Ertzinger from comment #5) > Is there another can of worms that I'd open with the PIE/PIC change? Is that > a change that's required for uwsgi as a whole (binary and dynamically > loadable modules), or just for the php module? Just the main program (uwsgi), the modules are already PIC. Thanks, I'll try that. I was tagged into an upstream user hitting problems with RTLD_DEEPBIND recently. https://github.com/php/php-src/issues/10670 It may be time to turn this into a config option and flip the default from On to Off. I've rebuilt uwsgi with %undefine _hardened_build which should disable PIE according to https://docs.fedoraproject.org/en-US/packaging-guidelines/#_pie And the executable no longer says "LSB pie executable" /usr/sbin/uwsgi: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib64/ld-linux-x86-64.so.2, BuildID[sha1]=160cd2740fd9e07a5a72f574f62d2043a8fa075d, for GNU/Linux 3.2.0, stripped Unfortunately it still blows up in the same way. (In reply to Ralf Ertzinger from comment #9) > I've rebuilt uwsgi with > > %undefine _hardened_build > > which should disable PIE according to > https://docs.fedoraproject.org/en-US/packaging-guidelines/#_pie > > And the executable no longer says "LSB pie executable" > > /usr/sbin/uwsgi: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), > dynamically linked, interpreter /lib64/ld-linux-x86-64.so.2, > BuildID[sha1]=160cd2740fd9e07a5a72f574f62d2043a8fa075d, for GNU/Linux 3.2.0, > stripped > > Unfortunately it still blows up in the same way. You need to build as PIC. Try adding -fPIC to CFLAGS. I've rebuilt the main binary (and the php plugin for good measure) with -fPIC (both in CFLAGS and LDFLAGS), and it still crashes the same way. Build logs: https://download.copr.fedorainfracloud.org/results/ertzing/scratch_x64/fedora-38-x86_64/05929259-uwsgi/build.log.gz what are the chances of having php buiit without RTLD_DEEPBIND for Fedora? I've managed to build uwsgi so this isn't an acute issue any more, but this requires disabling `_hardened_build` in the .spec file, which according to https://docs.fedoraproject.org/en-US/packaging-guidelines/#_pie I probably shouldn't be doing. Fedora Linux 38 entered end-of-life (EOL) status on 2024-05-21. Fedora Linux 38 is no longer maintained, which means that it will not receive any further security or bug fix updates. As a result we are closing this bug. If you can reproduce this bug against a currently maintained version of Fedora Linux please feel free to reopen this bug against that version. Note that the version field may be hidden. Click the "Show advanced fields" button if you do not see the version field. If you are unable to reopen this bug, please file a new report against an active release. Thank you for reporting this bug and we are sorry it could not be fixed. |