Hi,

In sys/kern/kern_ktrace.c, ktrpsig() stack-allocates a struct ktr_psig
and assigns its fields individually, but does not zero the struct first.
The struct contains a 4-byte alignment hole at offset 4 (between
"int signo" and "sig_t action"), which is then written verbatim to the
ktrace output file via ktrwrite().

This is the same class as the April 2026 fixes for shm_internal
(1b900a0, deraadt) and sem_base (76d3556, dgl) -- uninitialised
kernel-stack data exposed to userland through a same-UID syscall path.

Source (current master, sys/kern/kern_ktrace.c line 283):

    void
    ktrpsig(struct proc *p, int sig, sig_t action, int mask, int code,
        siginfo_t *si)
    {
        struct ktr_header kth;
        struct ktr_psig kp;      /* not memset before field assignments */

        atomic_setbits_int(&p->p_flag, P_INKTR);
        ktrinitheader(&kth, p, KTR_PSIG);
        kp.signo = (char)sig;
        kp.action = action;
        kp.mask = mask;
        kp.code = code;
        kp.si = *si;

        KERNEL_LOCK();
        ktrwrite(p, &kth, &kp, sizeof(kp));
        KERNEL_UNLOCK();
        atomic_clearbits_int(&p->p_flag, P_INKTR);
    }

struct ktr_psig layout (sys/sys/ktrace.h):

    int        signo;     /* offset  0 */
                          /* offset  4: 4-byte padding hole (sig_t
alignment) */
    sig_t      action;    /* offset  8 */
    int        mask;      /* offset 16 */
    int        code;      /* offset 20 */
    siginfo_t  si;        /* offset 24 */

The padding hole is never assigned anywhere in the function.

Tested on OpenBSD 7.7 arm64 (GENERIC.MP #361, 22 Apr 2025) in a UTM VM.
A PoC that traces its own process with KTRFAC_PSIG and raises 32 signals
interleaved with various other syscalls produces 32 PSIG records of
which 13 (40%) carry the value 0xffffff80 in the padding hole -- the
upper 32 bits of an arm64 kernel virtual address (TTBR1 region prefix).
The remaining 19 (59%) carry 0x00000000, consistent with the slot being
overwritten by zero by an intervening kernel function on those code
paths.

Verbatim hexdump of a leaking record:

    00000080  1e 00 00 00 80 ff ff ff  c0 14 9e 95 01 00 00 00
              signo=30      PADDING       action=0x1959e14c0
              SIGUSR1       LEAKED
                            0xffffff80

I am not claiming this is an exploitable KASLR weakening -- on arm64
the 0xffffff80 prefix is constant across the architecture, so it does
not disclose anything secret. But the structurally-equivalent reference
fixes were treated as worth correcting on hygiene grounds, and I think
the same applies here: the kernel should not be writing uninitialised
stack contents into a user-readable file, even on an opt-in trace
interface. On a different stack history or a different architecture
(amd64 not tested in this session) the leaked bytes could plausibly
carry less innocuous data.

Suggested fix:

    --- sys/kern/kern_ktrace.c
    +++ sys/kern/kern_ktrace.c
    @@ -285,6 +285,7 @@ ktrpsig(struct proc *p, int sig, sig_t action,
         struct ktr_header kth;
         struct ktr_psig kp;

    +    memset(&kp, 0, sizeof(kp));
         atomic_setbits_int(&p->p_flag, P_INKTR);
         ktrinitheader(&kth, p, KTR_PSIG);
         kp.signo = (char)sig;

PoC sources attached:
- POC_ktr_psig_padding.c: minimal reproducer, 16 PSIG records
- POC_ktr_entropy.c: extended PoC, 32 records across 4 signal types
  with interleaved syscalls, showing the 40%/59% distribution

Both build with: cc -O0 -o poc poc.c

Honestly noted:
- amd64 not tested by me; padding rules are arch-agnostic on LP64 so
  the layout will be the same, but the values landing in the slot may
  differ.
- The bug is opt-in (ktrace must be enabled) and same-UID.
- The constant 0xffffff80 prefix is not by itself a KASLR defeat.

Reporting this primarily as a hygiene/consistency fix matching
1b900a0 and 76d3556.

Thanks,
Stuart Thomas



--
*please note, there is no expectation for you to read/reply to my email
outside your normal working hours. *

Attachment: POC_ktr_psig_padding.c
Description: Binary data

Attachment: POC_ktr_entropy.c
Description: Binary data

Reply via email to