From 50bbbbd27866ff5118fc178a5af42e98922eb580 Mon Sep 17 00:00:00 2001 From: Kyle Huey Date: Thu, 31 Oct 2024 18:56:07 -0700 Subject: [PATCH] Handle open(NULL). Fixes #3865 --- CMakeLists.txt | 1 + src/preload/syscallbuf.c | 2 +- src/record_syscall.cc | 5 +++-- src/test/open_null.c | 12 ++++++++++++ 4 files changed, 17 insertions(+), 3 deletions(-) create mode 100644 src/test/open_null.c diff --git a/CMakeLists.txt b/CMakeLists.txt index 26da2457d29..cd5ff04c089 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1203,6 +1203,7 @@ set(BASIC_TESTS numa x86/old_fork orphan_process + open_null openat2 packet_mmap_disable x86/patch_syscall_restart diff --git a/src/preload/syscallbuf.c b/src/preload/syscallbuf.c index 66415bdd664..a203456d476 100644 --- a/src/preload/syscallbuf.c +++ b/src/preload/syscallbuf.c @@ -2532,7 +2532,7 @@ static long sys_open(struct syscall_info* call) { assert(syscallno == call->no); - if (!supported_open(pathname, flags)) { + if (!pathname || !supported_open(pathname, flags)) { return traced_raw_syscall(call); } diff --git a/src/record_syscall.cc b/src/record_syscall.cc index caf14149e4c..8c7603ea209 100644 --- a/src/record_syscall.cc +++ b/src/record_syscall.cc @@ -6861,8 +6861,9 @@ static void rec_process_syscall_arch(RecordTask* t, Registers r = t->regs(); if (r.syscall_failed()) { uintptr_t path = syscallno == Arch::open ? r.orig_arg1() : r.arg2(); - string pathname = t->read_c_str(remote_ptr(path)); - if (is_gcrypt_deny_file(pathname.c_str())) { + bool ok = false; + string pathname = t->read_c_str(remote_ptr(path), &ok); + if (ok && is_gcrypt_deny_file(pathname.c_str())) { fake_gcrypt_file(t, &r); t->set_regs(r); } diff --git a/src/test/open_null.c b/src/test/open_null.c new file mode 100644 index 00000000000..c24a75cd0c1 --- /dev/null +++ b/src/test/open_null.c @@ -0,0 +1,12 @@ +/* -*- Mode: C; tab-width: 8; c-basic-offset: 2; indent-tabs-mode: nil; -*- */ +#include "util.h" +#include + +int main(void) { + // Use syscall(2) because the glibc prototype for open(2) might enforce that + // it's nonnull. + int fd = syscall(SYS_open, NULL, O_RDONLY); + test_assert(fd == -1); + atomic_puts("EXIT-SUCCESS"); + return 0; +}