Opened 3 years ago

Closed 3 years ago

#16741 closed bug (fixed)

Kernel Panic on Multiple user_xsi_semget Syscall Invocations

Reported by: thosewhowork Owned by: nobody
Priority: normal Milestone: R1/beta4
Component: System/Kernel Version: R1/beta2
Keywords: Cc:
Blocked By: Blocking:
Platform: All

Description

Hi,

It is possible to cause a kernel panic by invoking the user_xsi_semget syscall with the IPC_CREAT (01000 Octal / 512 Decimal) key twice in a row.

The issue is here: https://github.com/haiku/haiku/blob/r1beta2/src/system/kernel/posix/xsi_semaphore.cpp#L774-L779

When the semaphoreSet == NULL condition is met, the block is entered, which then causes a dereference on the NULL pointer with semaphoreSet->ID().

The following should reproduce the issue:

#include <dlfcn.h>
#include <stdlib.h>

typedef int (*syscall_kern_xsi_semget)(int, int, int);

int
main(int argc, char** argv) {
    // IPC_CREAT is 01000 (Octal), 512 (Decimal)
    int i = 512;
    syscall_kern_xsi_semget p_kern_xsi_semget = NULL;

    if ((p_kern_xsi_semget = dlsym(RTLD_DEFAULT, "_kern_xsi_semget")) == NULL) {
        return 1;
    }
    
    // First call creates the ipcKey
    p_kern_xsi_semget(i, i, i);
    // Second call results in a NULL semaphoreSet, and subsequent NULL pointer deref.
    p_kern_xsi_semget(i, i, i);
    return 0;
}

Compiled with:

gcc -o xsi_semget_syscall src/X-xsi_semget_syscall.c

System Details

Haiku Version: Haiku R1/Beta2

Guest Machine: VMWare Fusion 8.5.3

Host Machine: Mac OS Mojave

I've attached the backtrace from the kernel debugger.

Thanks!

Attachments (1)

X-user_xsi_semget_panic_trace.png (377.9 KB ) - added by thosewhowork 3 years ago.

Download all attachments as: .zip

Change History (13)

by thosewhowork, 3 years ago

comment:1 by pulkomandy, 3 years ago

Proposed fix in https://review.haiku-os.org/c/haiku/+/3623

Userland applications are normally not expected to call syscalls directly. May I ask what you're trying to do?

comment:2 by thosewhowork, 3 years ago

Hi pulkomandy,

Absolutely - As another commenter inferred here: https://dev.haiku-os.org/ticket/16736#comment:5 I'm working on a kernel syscall fuzzer for educational purposes. I'm invoking the syscalls directly for simplicity's sake. I figured I would file the bugs that I find from using it.

If these kinds of reports are too noisy or unhelpful, please let me know and I can stop reporting what I turn up.

Take care!

comment:3 by pulkomandy, 3 years ago

Oh, that's great :)

Bug reports are appreciated and we'll fix the problems. No application should be able to crash the kernel, whatever it tries, and experimenting with kernel fuzzing was on my TODO list but I never got into it. Please continue reporting your findings.

I was worried that this code would be used in a real application, in which case I would try to find something that makes more sense in that context. But as the output of a fuzzer, it is fine of course.

comment:4 by waddlesplash, 3 years ago

Platform: x86All

comment:5 by waddlesplash, 3 years ago

It is worth noting that nightly builds have more asserts and other checks turned on, whereas the beta has a lot of checks turned down or off, so you may want to use a nightly build for your testing instead of the beta (we have also done a bunch of development since the beta, especially in the VM subsystem.)

comment:6 by waddlesplash, 3 years ago

Fix merged in hrev54878, but we may want to leave this open to figure out why it even happened in the first place; as PulkoMandy pointed out, it is not clear how this can even occur.

comment:7 by korli, 3 years ago

semaphoreSet would be NULL when invoking semaphoreSet->ID(). What is not clear exactly?

comment:8 by korli, 3 years ago

Milestone: UnscheduledR1/beta3

I assume this is fixed in beta3

comment:9 by pulkomandy, 3 years ago

semaphoreSet would be NULL when invoking semaphoreSet->ID(). What is not clear exactly?

It's not clear how we got in that situation, where the key appears to be valid (it is found in sIpcHashTable), but then it has no semaphoreSetId attached to it, or that semaphoreSetId is not found in sSemaphoreHashTable.

I would have expected that if the key is valid, the data it points to should be valid too. My understanding is that a valid key always goes with a semaphore, and it does not appear to be possible to delete the semaphore without deleting the key.

So, we are in a strange case that should not have been possible here: the key exists, but it points to no semaphore. How and when is it possible to get in that situation?

After looking more closely at the code, here is one thing that could happen:

Probably the fuzzing test triggered this code path, as it calls the syscall with invalid arguments.

So, it is possible to insert invalid keys in the hashmap here. An additional fix would be to move sIpcHashTable.Insert(ipcKey); to the end of the if (create), where all error checks have been made already.

comment:11 by nielx, 3 years ago

Milestone: R1/beta3R1/beta4

Ticket retargeted after milestone closed

comment:12 by pulkomandy, 3 years ago

Resolution: fixed
Status: newclosed

Patch applied in hrev55265.

Note: See TracTickets for help on using tickets.