Page MenuHomeFreeBSD

pkill(1): fix /rescue/pgrep not working
AbandonedPublic

Authored by christos on Feb 21 2023, 11:49 PM.
Tags
None
Referenced Files
Unknown Object (File)
Sat, Apr 27, 9:52 PM
Unknown Object (File)
Mar 15 2024, 2:48 AM
Unknown Object (File)
Jan 5 2024, 5:45 PM
Unknown Object (File)
Dec 25 2023, 5:12 PM
Unknown Object (File)
Dec 20 2023, 7:32 AM
Unknown Object (File)
Sep 3 2023, 12:32 PM
Unknown Object (File)
Jun 24 2023, 7:49 AM
Unknown Object (File)
May 4 2023, 4:16 PM

Diff Detail

Repository
rG FreeBSD src repository
Lint
Lint Skipped
Unit
Tests Skipped

Event Timeline

zlei requested changes to this revision.Feb 22 2023, 10:46 AM
zlei added inline comments.
bin/pkill/pkill.c
152

getprogname() should return name without the path /rescue/ .

I think we should investigate why pgrep linked with contrib/openzfs/lib/libspl

Debugging with lldb shows that the call to getprogname() is actually calling getexecname() from sys/contrib/openzfs/lib/libspl/os/freebsd/getexecname.c, which does not trim the leading path from the executable name, resulting in "if (strcmp(_getprogname(), "pgrep") == 0) {" not matching, and the executable behaving as pkill instead of pgrep.

This revision now requires changes to proceed.Feb 22 2023, 10:46 AM
stephen.wall_redcom.com added inline comments.
bin/pkill/pkill.c
152

It is not just the pgrep binary. Most of the executables in /rescue are a single binary linked to multiple filenames. This includes zfs and zpool. My question is, why is the getprogname() call in pkill.c calling getexecname() instead?

bin/pkill/pkill.c
152

After dig into libspl I get some clues.

zlei@:~ % llvm-objdump -d /lib/libspl.so.2 | grep getexecname
zlei@:~ % llvm-objdump -d /lib/libspl.so.2 | grep getprogname
0000000000007220 <getprogname>:
    724c: 74 09                        	je	0x7257 <getprogname+0x37>
    7255: eb 52                        	jmp	0x72a9 <getprogname+0x89>
    728e: 75 10                        	jne	0x72a0 <getprogname+0x80>
    7298: 74 06                        	je	0x72a0 <getprogname+0x80>
    729e: eb 09                        	jmp	0x72a9 <getprogname+0x89>
    72bc: 75 0c                        	jne	0x72ca <getprogname+0xaa>

stable/13 merged openzfs and it contains libspl which has its own implementation of getexecname() [1] . Well unfortunately the Makefile [2] of libspl still include the *shim* cddl/compat/opensolaris/include/stdlib.h which define getexecname to getprogname . sys/contrib/openzfs/lib/libspl/os/freebsd/getexecname.c include stdlib.h resulting the function name change from getexecname to getprogname which conflict with stand c library (libc).

So when statically linked with libspl, programs requires getprogname() might bind the wrong version of getprogname().

For /rescue, if zfs is enabled (the default), then all programs will link with libspl .

.if ${MK_ZFS} != "no"
CRUNCH_LIBS+= -lavl -lzpool -lzfs_core -lzfs -lnvpair -lpthread -luutil -lumem
CRUNCH_LIBS+= -lbe -lzfsbootenv -lzutil -ltpool -lspl -licp_rescue
.else
...

After checking zfs sources in stable/12, I think the *shim* is no longer needed for stable/13 and current/14 .

[1] sys/contrib/openzfs/lib/libspl/os/freebsd/getexecname.c
[2] cddl/lib/libspl/Makefile