-
Bug
-
Resolution: Done-Errata
-
Major
-
rhel-9.3.0
-
None
-
systemd-252-33.el9
-
None
-
Moderate
-
ZStream
-
rhel-sst-cs-plumbers
-
ssg_core_services
-
7
-
26
-
1
-
False
-
-
None
-
Red Hat Enterprise Linux
-
None
-
Approved Blocker
-
Pass
-
Automated
-
-
All
-
None
What were you trying to do that didn't work?
When having a service configured to load credentials, the child process of systemd aborts in assertion because of passing an invalid directory fd (-1 instead of AT_FDCWD):
(gdb) bt #0 __pthread_kill_implementation (threadid=<optimized out>, signo=signo@entry=6, no_tid=no_tid@entry=0) at pthread_kill.c:44 #1 0x00007fae912a15b3 in __pthread_kill_internal (signo=6, threadid=<optimized out>) at pthread_kill.c:78 #2 0x00007fae91254d06 in __GI_raise (sig=sig@entry=6) at ../sysdeps/posix/raise.c:26 #3 0x00007fae912287f3 in __GI_abort () at abort.c:79 #4 0x00007fae91687da0 in log_assert_failed (text=<optimized out>, file=<optimized out>, line=<optimized out>, func=<optimized out>) at ../src/basic/log.c:853 #5 0x00007fae917c14e7 in connect_unix_path (fd=4, dir_fd=-1, path=0x556d5cc6bf70 "/run/repro.socket") at ../src/basic/socket-util.c:1437 #6 0x00007fae91794a02 in read_full_file_full (dir_fd=dir_fd@entry=-1, filename=0x556d5cc6bf70 "/run/repro.socket", offset=offset@entry=18446744073709551615, size=size@entry=1048576, flags=flags@entry=(READ_FULL_FILE_SECURE | READ_FULL_FILE_CONNECT_SOCKET | READ_FULL_FILE_FAIL_WHEN_LARGER), bind_name=<optimized out>, ret_contents=0x7ffd71011e30, ret_size=0x7ffd71011e20) at ../src/basic/fileio.c:798 #7 0x00007fae91aa51f4 in load_credential (context=0x556d5cdc6b98, params=<optimized out>, id=0x556d5cdf6c90 "foo", path=0x556d5cc6bf70 "/run/repro.socket", encrypted=<optimized out>, unit=<optimized out>, read_dfd=-1, write_dfd=3, uid=4294967295, ownership_ok=true, left=0x7ffd71011f30) at ../src/core/execute.c:2734 #8 0x00007fae91aa59c3 in acquire_credentials (ownership_ok=true, uid=4294967295, p=<optimized out>, unit=0x556d5ccd4930 "reproducer.service", params=0x7ffd71012580, context=0x556d5cdc6b98) at ../src/core/execute.c:2884 : (gdb) f 5 #5 0x00007fae917c14e7 in connect_unix_path (fd=4, dir_fd=-1, path=0x556d5cc6bf70 "/run/repro.socket") at ../src/basic/socket-util.c:1437 1437 assert(dir_fd == AT_FDCWD || dir_fd >= 0); (gdb) p dir_fd $1 = -1 (gdb) up #6 0x00007fae91794a02 in read_full_file_full (dir_fd=dir_fd@entry=-1, filename=0x556d5cc6bf70 "/run/repro.socket", offset=offset@entry=18446744073709551615, size=size@entry=1048576, flags=flags@entry=(READ_FULL_FILE_SECURE | READ_FULL_FILE_CONNECT_SOCKET | READ_FULL_FILE_FAIL_WHEN_LARGER), bind_name=<optimized out>, ret_contents=0x7ffd71011e30, ret_size=0x7ffd71011e20) at ../src/basic/fileio.c:798 798 r = connect_unix_path(sk, dir_fd, filename); (gdb) #7 0x00007fae91aa51f4 in load_credential (context=0x556d5cdc6b98, params=<optimized out>, id=0x556d5cdf6c90 "foo", path=0x556d5cc6bf70 "/run/repro.socket", encrypted=<optimized out>, unit=<optimized out>, read_dfd=-1, write_dfd=3, uid=4294967295, ownership_ok=true, left=0x7ffd71011f30) at ../src/core/execute.c:2734 2734 r = read_full_file_full( (gdb) #8 0x00007fae91aa59c3 in acquire_credentials (ownership_ok=true, uid=4294967295, p=<optimized out>, unit=0x556d5ccd4930 "reproducer.service", params=0x7ffd71012580, context=0x556d5cdc6b98) at ../src/core/execute.c:2884 2884 r = load_credential( (gdb) list 2879 return log_debug_errno(errno, "Failed to open '%s': %m", lc->path); 2880 } 2881 2882 if (sub_fd < 0) 2883 /* Regular file (incl. a credential passed in from higher up) */ 2884 r = load_credential( 2885 context, 2886 params, 2887 lc->id, 2888 lc->path, (gdb) 2889 lc->encrypted, 2890 unit, 2891 -1, 2892 dfd, 2893 uid, 2894 ownership_ok, 2895 &left); 2896 else 2897 /* Directory */ 2898 r = recurse_dir( :
Faulty line is 2891, which passes -1.
This got fixed Upstream by the following commit:
commit 661e4251a5b157d1aee1df98fbd2f0c95285ebba Author: Daan De Meyer <daan.j.demeyer@gmail.com> Date: Tue Dec 13 10:50:01 2022 +0000 execute: Pass AT_FDCWD instead of -1 Let's enforce that callers pass AT_FDCWD as read_dfd to load_credential() to avoid an assert() in read_full_file_full() if read_dfd is -1.
Please provide the package NVR for which bug is seen:
systemd-252-18.el9
How reproducible:
Always
Steps to reproduce
- Create a dummy service loading credentials from a Unix socket
# cat /etc/systemd/system/reproducer.service [Service] Type=oneshot LoadCredential=foo:/run/repro.socket ExecStart=/bin/true
- Start the unix socket
# ncat -l -U /run/repro.socket &
- Set SELinux to Permissive (because of context issues) and start the service
# setenforce 0 # systemctl start reproducer
Expected results
No assertion failure
Actual results
Apr 04 15:20:31 vm-rhel9 systemd[1]: Starting reproducer.service...
Apr 04 15:20:31 vm-rhel9 systemd[39710]: Assertion 'dir_fd == AT_FDCWD || dir_fd >= 0' failed at src/basic/socket-util.c:1437, function connect_unix_path(). Aborting.
- is cloned by
-
RHEL-32257 systemd service child crashes when loading credentials
-
- Closed
-
- links to
-
RHBA-2024:131313 systemd update