Package: at
Version: 3.2.5
`at` crashes with a segmentation fault when invoked with a malformed
environment entry (missing '='), potentially leaving partially written
job files under /var/spool/at.
Proof of concept in python:
```
import ctypes, os
libc = ctypes.CDLL(None)
argv = (ctypes.c_char_p * 6)(b"/usr/bin/at", b"now", b"+", b"1",
b"minute", None)
env = (ctypes.c_char_p * 8)(b"PATH=/usr/bin'", b"HOME=/tmp",
b"USER=testuser", b"MALFORMED", b"NORMAL=value", b"SHELL=/bin/sh", None)
# A entry with no = is present
libc.execve(b"/usr/bin/at", argv, env) # should segfault (this is the
issue)
```
```
import ctypes, os
libc = ctypes.CDLL(None)
argv = (ctypes.c_char_p * 6)(b"/usr/bin/at", b"now", b"+", b"1",
b"minute", None)
env = (ctypes.c_char_p * 8)(b"PATH=/usr/bin'", b"HOME=/tmp",
b"USER=testuser", b"NOTMALFORMED=1", b"NORMAL=value", b"SHELL=/bin/sh",
None) # All entries are proper key pair values
libc.execve(b"/usr/bin/at", argv, env) # should not segfault
```
Stack trace extracted from `coredumpctl debug`
Stack trace of thread 152251:
#0 0x00007f26db3e1d49 __memcpy_evex_unaligned_erms
(libc.so.6 + 0x157d49)
#1 0x00007f26db2f3071 _IO_file_xsputn@@GLIBC_2.2.5
(libc.so.6 + 0x69071)
#2 0x00007f26db2e6893 _IO_fwrite (libc.so.6 + 0x5c893)
#3 0x0000557032b63c67 writefile (at + 0x3c67)
#4 0x0000557032b62a06 main (at + 0x2a06)
#5 0x00007f26db28d248 __libc_start_call_main
(libc.so.6 + 0x3248)
#6 0x00007f26db28d30b __libc_start_main@@GLIBC_2.34
(libc.so.6 + 0x330b)
#7 0x0000557032b62d25 _start (at + 0x2d25)
I believe this is happening due to at.c line 434 in master branch of
salsa.debian.org/debian/at
```
eqp = strchr(*atenv, '=');
if (ap == NULL)
eqp = *atenv;
else {
unsigned int i;
for (i = 0; i < sizeof(no_export) / sizeof(no_export[0]); i++) {
export = export
&& (strncmp(*atenv, no_export[i],
(size_t) (eqp - *atenv)) != 0);
}
eqp++;
}
if (export) {
fwrite(*atenv, sizeof(char), eqp - *atenv, fp);
```
When strchr() returns NULL for an entry without a '=', eqp becomes NULL
and `eqp - *atenv` underflows to a large size_t, causing `fwrite()` to
attempt to write an excessive number of bytes and eventually crash
(SIGSEGV).
Tested on,
* Fedora Linux 41, Linux 6.12.11-200.fc41.x86_64 and libc 2.40
* Debian GNU/Linux 12 (bookworm), Linux 6.12.11-200.fc41.x86_64 and libc
2.36
Please assign a CVE if appropriate
I would like to be credited as: Tarith Jayasooriya <[email protected]>
Regards,
Tarith