aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--executor/android/android_seccomp.h7
-rw-r--r--executor/common_bsd.h17
-rw-r--r--executor/common_fuchsia.h3
-rw-r--r--executor/common_linux.h176
-rw-r--r--executor/common_usb_netbsd.h20
-rw-r--r--executor/cov_filter.h2
-rw-r--r--executor/executor.cc119
-rw-r--r--executor/executor_bsd.h2
-rw-r--r--executor/executor_fuchsia.h2
-rw-r--r--executor/executor_linux.h2
-rw-r--r--executor/style_test.go10
-rw-r--r--pkg/csource/csource.go2
-rw-r--r--pkg/csource/generated.go218
-rw-r--r--pkg/report/report.go12
-rw-r--r--pkg/report/testdata/linux/report/60126
15 files changed, 326 insertions, 292 deletions
diff --git a/executor/android/android_seccomp.h b/executor/android/android_seccomp.h
index d8df52792..f3febac2c 100644
--- a/executor/android/android_seccomp.h
+++ b/executor/android/android_seccomp.h
@@ -46,7 +46,7 @@ typedef struct Filter_t {
static void push_back(Filter* filter_array, struct sock_filter filter)
{
if (filter_array->count == kFilterMaxSize)
- fail("can't add another syscall to seccomp filter: count %zu", filter_array->count);
+ failmsg("can't add another syscall to seccomp filter", "count=%zu", filter_array->count);
filter_array->data[filter_array->count++] = filter;
}
@@ -79,9 +79,8 @@ static void install_filter(const Filter* f)
(struct sock_filter*)&f->data[0],
};
// This assumes either the current process has CAP_SYS_ADMIN, or PR_SET_NO_NEW_PRIVS bit is set.
- if (prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, &prog) < 0) {
- fail("Could not set seccomp filter of size %zu", f->count);
- }
+ if (prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, &prog) < 0)
+ failmsg("could not set seccomp filter", "size=%zu", f->count);
}
// Modified from the orignal Android code as we don't need dual arch support
diff --git a/executor/common_bsd.h b/executor/common_bsd.h
index 7ccd1053f..1bed0cf3c 100644
--- a/executor/common_bsd.h
+++ b/executor/common_bsd.h
@@ -33,7 +33,7 @@ static void setup_usb(void)
char path[1024];
snprintf(path, sizeof(path), "/dev/%s", ent->d_name);
if (chmod(path, 0666))
- fail("failed to chmod %s", path);
+ failmsg("failed to chmod vhci", "path=%s", path);
}
closedir(dir);
@@ -61,7 +61,7 @@ static int inject_fault(int nth)
en.mode = 0; // FAULT_MODE_NTH_ONESHOT
en.nth = nth + 2; // FAULT_NTH_MIN
if (ioctl(fd, FAULT_IOC_ENABLE, &en) != 0)
- fail("FAULT_IOC_ENABLE failed with nth=%d", nth);
+ failmsg("FAULT_IOC_ENABLE failed", "nth=%d", nth);
return fd;
}
@@ -149,7 +149,7 @@ static void vsnprintf_check(char* str, size_t size, const char* format, va_list
if (rv < 0)
fail("vsnprintf failed");
if ((size_t)rv >= size)
- fail("vsnprintf: string '%s...' doesn't fit into buffer", str);
+ failmsg("vsnprintf: string doesn't fit into buffer", "string='%s'", str);
}
static void snprintf_check(char* str, size_t size, const char* format, ...)
@@ -179,7 +179,7 @@ static void execute_command(bool panic, const char* format, ...)
int rv = system(command);
if (rv) {
if (panic)
- fail("command '%s' failed: %d", &command[0], rv);
+ failmsg("command failed", "command=%s: %d", &command[0], rv);
debug("command '%s': %d\n", &command[0], rv);
}
}
@@ -191,9 +191,8 @@ static void initialize_tun(int tun_id)
return;
#endif // SYZ_EXECUTOR
- if (tun_id < 0 || tun_id >= MAX_TUN) {
- fail("tun_id out of range %d", tun_id);
- }
+ if (tun_id < 0 || tun_id >= MAX_TUN)
+ failmsg("tun_id out of range", "tun_id=%d", tun_id);
char tun_device[sizeof(TUN_DEVICE)];
snprintf_check(tun_device, sizeof(tun_device), TUN_DEVICE, tun_id);
@@ -219,7 +218,7 @@ static void initialize_tun(int tun_id)
#endif
if (tunfd == -1) {
#if SYZ_EXECUTOR
- fail("tun: can't open %s", tun_device);
+ failmsg("tun: can't open device", "device=%s", tun_device);
#else
printf("tun: can't open %s: errno=%d\n", tun_device, errno);
return;
@@ -300,7 +299,7 @@ static int read_tun(char* data, int size)
if (rv < 0) {
if (errno == EAGAIN)
return -1;
- fail("tun: read failed with %d", rv);
+ fail("tun: read failed");
}
return rv;
}
diff --git a/executor/common_fuchsia.h b/executor/common_fuchsia.h
index 6576e83f0..607518178 100644
--- a/executor/common_fuchsia.h
+++ b/executor/common_fuchsia.h
@@ -119,7 +119,8 @@ static void install_segv_handler(void)
zx_status_t status;
zx_handle_t exception_channel;
if ((status = zx_task_create_exception_channel(zx_process_self(), 0, &exception_channel)) != ZX_OK)
- fail("zx_task_create_exception_channel failed: %s (%d)", zx_status_get_string(status), status);
+ failmsg("zx_task_create_exception_channel failed",
+ "status=%s (%d)", zx_status_get_string(status), status);
pthread_t th;
if (pthread_create(&th, 0, ex_handler, (void*)(long)exception_channel))
fail("pthread_create failed");
diff --git a/executor/common_linux.h b/executor/common_linux.h
index a6a117c5b..1d3500a57 100644
--- a/executor/common_linux.h
+++ b/executor/common_linux.h
@@ -186,7 +186,7 @@ static int netlink_send_ext(struct nlmsg* nlmsg, int sock,
ssize_t n = sendto(sock, nlmsg->buf, hdr->nlmsg_len, 0, (struct sockaddr*)&addr, sizeof(addr));
if (n != (ssize_t)hdr->nlmsg_len) {
if (dofail)
- fail("netlink_send_ext: short netlink write: %zd/%d", n, hdr->nlmsg_len);
+ failmsg("netlink_send_ext: short netlink write", "wrote=%zd, want=%d", n, hdr->nlmsg_len);
debug("netlink_send_ext: short netlink write: %zd/%d errno=%d\n", n, hdr->nlmsg_len, errno);
return -1;
}
@@ -195,14 +195,14 @@ static int netlink_send_ext(struct nlmsg* nlmsg, int sock,
*reply_len = 0;
if (n < 0) {
if (dofail)
- fail("netlink_send_ext: netlink read failed: %zd", n);
- debug("netlink_send_ext: netlink read failed: %zd errno=%d\n", n, errno);
+ fail("netlink_send_ext: netlink read failed");
+ debug("netlink_send_ext: netlink read failed: errno=%d\n", errno);
return -1;
}
if (n < (ssize_t)sizeof(struct nlmsghdr)) {
errno = EINVAL;
if (dofail)
- fail("netlink_send_ext: short netlink read: %zd", n);
+ failmsg("netlink_send_ext: short netlink read", "read=%zd", n);
debug("netlink_send_ext: short netlink read: %zd\n", n);
return -1;
}
@@ -215,14 +215,14 @@ static int netlink_send_ext(struct nlmsg* nlmsg, int sock,
if (n < (ssize_t)(sizeof(struct nlmsghdr) + sizeof(struct nlmsgerr))) {
errno = EINVAL;
if (dofail)
- fail("netlink_send_ext: short netlink read: %zd", n);
+ failmsg("netlink_send_ext: short netlink read", "read=%zd", n);
debug("netlink_send_ext: short netlink read: %zd\n", n);
return -1;
}
if (hdr->nlmsg_type != NLMSG_ERROR) {
errno = EINVAL;
if (dofail)
- fail("netlink_send_ext: short netlink ack: %d", hdr->nlmsg_type);
+ failmsg("netlink_send_ext: bad netlink ack type", "type=%d", hdr->nlmsg_type);
debug("netlink_send_ext: short netlink ack: %d\n", hdr->nlmsg_type);
return -1;
}
@@ -1011,7 +1011,7 @@ static void initialize_wifi_devices(void)
mac_addr[5] = device_id;
int ret = hwsim80211_create_device(&nlmsg, sock, hwsim_family_id, mac_addr);
if (ret < 0)
- fail("initialize_wifi_devices: failed to create device #%d", device_id);
+ failmsg("initialize_wifi_devices: failed to create device", "device=%d", device_id);
// For each device, unless HWSIM_ATTR_NO_VIF is passed, a network interface is created
// automatically. Such interfaces are named "wlan0", "wlan1" and so on.
@@ -1019,7 +1019,7 @@ static void initialize_wifi_devices(void)
interface[4] += device_id;
if (nl80211_setup_ibss_interface(&nlmsg, sock, nl80211_family_id, interface, &ibss_props) < 0)
- fail("initialize_wifi_devices: failed set up IBSS network for #%d", device_id);
+ failmsg("initialize_wifi_devices: failed set up IBSS network", "device=%d", device_id);
}
// Wait for all devices to join the IBSS network
@@ -1028,7 +1028,8 @@ static void initialize_wifi_devices(void)
interface[4] += device_id;
int ret = await_ifla_operstate(&nlmsg, interface, IF_OPER_UP);
if (ret < 0)
- fail("initialize_wifi_devices: get_ifla_operstate failed for #%d, ret %d", device_id, ret);
+ failmsg("initialize_wifi_devices: get_ifla_operstate failed",
+ "device=%d, ret=%d", device_id, ret);
}
close(sock);
@@ -1561,7 +1562,7 @@ static int read_tun(char* data, int size)
// Tun sometimes returns EBADFD, unclear if it's a kernel bug or not.
if (errno == EAGAIN || errno == EBADFD)
return -1;
- fail("tun: read failed with %d", rv);
+ fail("tun read failed");
}
return rv;
}
@@ -1856,8 +1857,6 @@ static long syz_io_uring_submit(volatile long a0, volatile long a1, volatile lon
static long syz_usbip_server_init(volatile long a0)
{
- int socket_pair[2];
- char buffer[100];
// port_alloc[0] corresponds to ports which can be used by usb2 and
// port_alloc[1] corresponds to ports which can be used by usb3.
static int port_alloc[2];
@@ -1865,9 +1864,9 @@ static long syz_usbip_server_init(volatile long a0)
int speed = (int)a0;
bool usb3 = (speed == USB_SPEED_SUPER);
- int rc = socketpair(AF_UNIX, SOCK_STREAM, 0, socket_pair);
- if (rc < 0)
- fail("syz_usbip_server_init : socketpair failed: %d", rc);
+ int socket_pair[2];
+ if (socketpair(AF_UNIX, SOCK_STREAM, 0, socket_pair))
+ fail("syz_usbip_server_init: socketpair failed");
int client_fd = socket_pair[0];
int server_fd = socket_pair[1];
@@ -1887,6 +1886,7 @@ static long syz_usbip_server_init(volatile long a0)
// Under normal USB/IP usage, devid represents the device ID on the server.
// When fuzzing with syzkaller we don't have an actual server or an actual device, so use 0 for devid.
+ char buffer[100];
sprintf(buffer, "%d %d %s %d", port_num, client_fd, "0", speed);
write_file("/sys/devices/platform/vhci_hcd.0/attach", buffer);
@@ -2495,7 +2495,7 @@ static bool process_command_pkt(int fd, char* buf, ssize_t buf_size)
struct hci_command_hdr* hdr = (struct hci_command_hdr*)buf;
if (buf_size < (ssize_t)sizeof(struct hci_command_hdr) ||
hdr->plen != buf_size - sizeof(struct hci_command_hdr)) {
- fail("invalid size: %zx", buf_size);
+ failmsg("process_command_pkt: invalid size", "suze=%zx", buf_size);
}
switch (hdr->opcode) {
@@ -3078,7 +3078,7 @@ static void checkpoint_iptables(struct ipt_table_desc* tables, int num_tables, i
case ENOPROTOOPT:
return;
}
- fail("iptable checkpoint %d: socket failed", family);
+ failmsg("iptable checkpoint: socket(SOCK_STREAM, IPPROTO_TCP) failed", "family=%d", family);
}
for (int i = 0; i < num_tables; i++) {
struct ipt_table_desc* table = &tables[i];
@@ -3092,25 +3092,26 @@ static void checkpoint_iptables(struct ipt_table_desc* tables, int num_tables, i
case ENOPROTOOPT:
continue;
}
- fail("iptable checkpoint %s/%d: getsockopt(IPT_SO_GET_INFO)", table->name, family);
+ failmsg("iptable checkpoint: getsockopt(IPT_SO_GET_INFO) failed",
+ "table=%s, family=%d", table->name, family);
}
debug("iptable checkpoint %s/%d: checkpoint entries=%d hooks=%x size=%d\n",
table->name, family, table->info.num_entries,
table->info.valid_hooks, table->info.size);
if (table->info.size > sizeof(table->replace.entrytable))
- fail("iptable checkpoint %s/%d: table size is too large: %u",
- table->name, family, table->info.size);
+ failmsg("iptable checkpoint: table size is too large", "table=%s, family=%d, size=%u",
+ table->name, family, table->info.size);
if (table->info.num_entries > XT_MAX_ENTRIES)
- fail("iptable checkpoint %s/%d: too many counters: %u",
- table->name, family, table->info.num_entries);
+ failmsg("iptable checkpoint: too many counters", "table=%s, family=%d, counters=%d",
+ table->name, family, table->info.num_entries);
struct ipt_get_entries entries;
memset(&entries, 0, sizeof(entries));
strcpy(entries.name, table->name);
entries.size = table->info.size;
optlen = sizeof(entries) - sizeof(entries.entrytable) + table->info.size;
if (getsockopt(fd, level, IPT_SO_GET_ENTRIES, &entries, &optlen))
- fail("iptable checkpoint %s/%d: getsockopt(IPT_SO_GET_ENTRIES)",
- table->name, family);
+ failmsg("iptable checkpoint: getsockopt(IPT_SO_GET_ENTRIES) failed",
+ "table=%s, family=%d", table->name, family);
table->replace.valid_hooks = table->info.valid_hooks;
table->replace.num_entries = table->info.num_entries;
table->replace.size = table->info.size;
@@ -3130,7 +3131,7 @@ static void reset_iptables(struct ipt_table_desc* tables, int num_tables, int fa
case ENOPROTOOPT:
return;
}
- fail("iptable %d: socket failed", family);
+ failmsg("iptable: socket(SOCK_STREAM, IPPROTO_TCP) failed", "family=%d", family);
}
for (int i = 0; i < num_tables; i++) {
struct ipt_table_desc* table = &tables[i];
@@ -3141,7 +3142,8 @@ static void reset_iptables(struct ipt_table_desc* tables, int num_tables, int fa
strcpy(info.name, table->name);
socklen_t optlen = sizeof(info);
if (getsockopt(fd, level, IPT_SO_GET_INFO, &info, &optlen))
- fail("iptable %s/%d: getsockopt(IPT_SO_GET_INFO)", table->name, family);
+ failmsg("iptable: getsockopt(IPT_SO_GET_INFO) failed",
+ "table=%s, family=%d", table->name, family);
if (memcmp(&table->info, &info, sizeof(table->info)) == 0) {
struct ipt_get_entries entries;
memset(&entries, 0, sizeof(entries));
@@ -3149,7 +3151,8 @@ static void reset_iptables(struct ipt_table_desc* tables, int num_tables, int fa
entries.size = table->info.size;
optlen = sizeof(entries) - sizeof(entries.entrytable) + entries.size;
if (getsockopt(fd, level, IPT_SO_GET_ENTRIES, &entries, &optlen))
- fail("iptable %s/%d: getsockopt(IPT_SO_GET_ENTRIES)", table->name, family);
+ failmsg("iptable: getsockopt(IPT_SO_GET_ENTRIES) failed",
+ "table=%s, family=%d", table->name, family);
if (memcmp(table->replace.entrytable, entries.entrytable, table->info.size) == 0)
continue;
}
@@ -3159,7 +3162,8 @@ static void reset_iptables(struct ipt_table_desc* tables, int num_tables, int fa
table->replace.counters = counters;
optlen = sizeof(table->replace) - sizeof(table->replace.entrytable) + table->replace.size;
if (setsockopt(fd, level, IPT_SO_SET_REPLACE, &table->replace, optlen))
- fail("iptable %s/%d: setsockopt(IPT_SO_SET_REPLACE)", table->name, family);
+ failmsg("iptable: setsockopt(IPT_SO_SET_REPLACE) failed",
+ "table=%s, family=%d", table->name, family);
}
close(fd);
}
@@ -3173,7 +3177,7 @@ static void checkpoint_arptables(void)
case ENOPROTOOPT:
return;
}
- fail("arptable checkpoint: socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)");
+ fail("arptable checkpoint: socket(AF_INET, SOCK_STREAM, IPPROTO_TCP) failed");
}
for (unsigned i = 0; i < sizeof(arpt_tables) / sizeof(arpt_tables[0]); i++) {
struct arpt_table_desc* table = &arpt_tables[i];
@@ -3187,23 +3191,23 @@ static void checkpoint_arptables(void)
case ENOPROTOOPT:
continue;
}
- fail("arptable checkpoint %s: getsockopt(ARPT_SO_GET_INFO)", table->name);
+ failmsg("arptable checkpoint: getsockopt(ARPT_SO_GET_INFO) failed", "table=%s", table->name);
}
debug("arptable checkpoint %s: entries=%d hooks=%x size=%d\n",
table->name, table->info.num_entries, table->info.valid_hooks, table->info.size);
if (table->info.size > sizeof(table->replace.entrytable))
- fail("arptable checkpoint %s: table size is too large: %u",
- table->name, table->info.size);
+ failmsg("arptable checkpoint: table size is too large",
+ "table=%s, size=%u", table->name, table->info.size);
if (table->info.num_entries > XT_MAX_ENTRIES)
- fail("arptable checkpoint %s: too many counters: %u",
- table->name, table->info.num_entries);
+ failmsg("arptable checkpoint: too many counters",
+ "table=%s, counters=%u", table->name, table->info.num_entries);
struct arpt_get_entries entries;
memset(&entries, 0, sizeof(entries));
strcpy(entries.name, table->name);
entries.size = table->info.size;
optlen = sizeof(entries) - sizeof(entries.entrytable) + table->info.size;
if (getsockopt(fd, SOL_IP, ARPT_SO_GET_ENTRIES, &entries, &optlen))
- fail("arptable checkpoint %s: getsockopt(ARPT_SO_GET_ENTRIES)", table->name);
+ failmsg("arptable checkpoint: getsockopt(ARPT_SO_GET_ENTRIES) failed", "table=%s", table->name);
table->replace.valid_hooks = table->info.valid_hooks;
table->replace.num_entries = table->info.num_entries;
table->replace.size = table->info.size;
@@ -3234,7 +3238,7 @@ static void reset_arptables()
strcpy(info.name, table->name);
socklen_t optlen = sizeof(info);
if (getsockopt(fd, SOL_IP, ARPT_SO_GET_INFO, &info, &optlen))
- fail("arptable %s:getsockopt(ARPT_SO_GET_INFO)", table->name);
+ failmsg("arptable: getsockopt(ARPT_SO_GET_INFO) failed", "table=%s", table->name);
if (memcmp(&table->info, &info, sizeof(table->info)) == 0) {
struct arpt_get_entries entries;
memset(&entries, 0, sizeof(entries));
@@ -3242,7 +3246,7 @@ static void reset_arptables()
entries.size = table->info.size;
optlen = sizeof(entries) - sizeof(entries.entrytable) + entries.size;
if (getsockopt(fd, SOL_IP, ARPT_SO_GET_ENTRIES, &entries, &optlen))
- fail("arptable %s: getsockopt(ARPT_SO_GET_ENTRIES)", table->name);
+ failmsg("arptable: getsockopt(ARPT_SO_GET_ENTRIES) failed", "table=%s", table->name);
if (memcmp(table->replace.entrytable, entries.entrytable, table->info.size) == 0)
continue;
debug("arptable %s: data changed\n", table->name);
@@ -3255,7 +3259,8 @@ static void reset_arptables()
table->replace.counters = counters;
optlen = sizeof(table->replace) - sizeof(table->replace.entrytable) + table->replace.size;
if (setsockopt(fd, SOL_IP, ARPT_SO_SET_REPLACE, &table->replace, optlen))
- fail("arptable %s: setsockopt(ARPT_SO_SET_REPLACE)", table->name);
+ failmsg("arptable: setsockopt(ARPT_SO_SET_REPLACE) failed",
+ "table=%s", table->name);
}
close(fd);
}
@@ -3328,19 +3333,21 @@ static void checkpoint_ebtables(void)
case ENOPROTOOPT:
continue;
}
- fail("ebtable checkpoint %s: getsockopt(EBT_SO_GET_INIT_INFO)", table->name);
+ failmsg("ebtable checkpoint: getsockopt(EBT_SO_GET_INIT_INFO) failed",
+ "table=%s", table->name);
}
debug("ebtable checkpoint %s: entries=%d hooks=%x size=%d\n",
table->name, table->replace.nentries, table->replace.valid_hooks,
table->replace.entries_size);
if (table->replace.entries_size > sizeof(table->entrytable))
- fail("ebtable checkpoint %s: table size is too large: %u",
- table->name, table->replace.entries_size);
+ failmsg("ebtable checkpoint: table size is too large", "table=%s, size=%u",
+ table->name, table->replace.entries_size);
table->replace.num_counters = 0;
table->replace.entries = table->entrytable;
optlen = sizeof(table->replace) + table->replace.entries_size;
if (getsockopt(fd, SOL_IP, EBT_SO_GET_INIT_ENTRIES, &table->replace, &optlen))
- fail("ebtable checkpoint %s: getsockopt(EBT_SO_GET_INIT_ENTRIES)", table->name);
+ failmsg("ebtable checkpoint: getsockopt(EBT_SO_GET_INIT_ENTRIES) failed",
+ "table=%s", table->name);
}
close(fd);
}
@@ -3365,7 +3372,7 @@ static void reset_ebtables()
strcpy(replace.name, table->name);
socklen_t optlen = sizeof(replace);
if (getsockopt(fd, SOL_IP, EBT_SO_GET_INFO, &replace, &optlen))
- fail("ebtable %s: getsockopt(EBT_SO_GET_INFO)", table->name);
+ failmsg("ebtable: getsockopt(EBT_SO_GET_INFO)", "table=%s", table->name);
replace.num_counters = 0;
table->replace.entries = 0;
for (unsigned h = 0; h < NF_BR_NUMHOOKS; h++)
@@ -3376,7 +3383,7 @@ static void reset_ebtables()
replace.entries = entrytable;
optlen = sizeof(replace) + replace.entries_size;
if (getsockopt(fd, SOL_IP, EBT_SO_GET_ENTRIES, &replace, &optlen))
- fail("ebtable %s: getsockopt(EBT_SO_GET_ENTRIES)", table->name);
+ failmsg("ebtable: getsockopt(EBT_SO_GET_ENTRIES) failed", "table=%s", table->name);
if (memcmp(table->entrytable, entrytable, replace.entries_size) == 0)
continue;
}
@@ -3391,7 +3398,7 @@ static void reset_ebtables()
table->replace.entries = table->entrytable;
optlen = sizeof(table->replace) + table->replace.entries_size;
if (setsockopt(fd, SOL_IP, EBT_SO_SET_ENTRIES, &table->replace, optlen))
- fail("ebtable %s: setsockopt(EBT_SO_SET_ENTRIES)", table->name);
+ failmsg("ebtable: setsockopt(EBT_SO_SET_ENTRIES) failed", "table=%s", table->name);
}
close(fd);
}
@@ -3978,19 +3985,18 @@ const size_t UNTRUSTED_APP_NUM_GROUPS = sizeof(UNTRUSTED_APP_GROUPS) / sizeof(UN
// - No library dependency
// - No dynamic memory allocation
// - Uses fail() instead of returning an error code
-static void syz_getcon(char* context, size_t context_size)
+static void getcon(char* context, size_t context_size)
{
int fd = open(SELINUX_CONTEXT_FILE, O_RDONLY);
-
if (fd < 0)
- fail("getcon: Couldn't open %s", SELINUX_CONTEXT_FILE);
+ fail("getcon: couldn't open context file");
ssize_t nread = read(fd, context, context_size);
close(fd);
if (nread <= 0)
- fail("getcon: Failed to read from %s", SELINUX_CONTEXT_FILE);
+ fail("getcon: failed to read context file");
// The contents of the context file MAY end with a newline
// and MAY not have a null terminator. Handle this here.
@@ -4002,7 +4008,7 @@ static void syz_getcon(char* context, size_t context_size)
// - No library dependency
// - No dynamic memory allocation
// - Uses fail() instead of returning an error code
-static void syz_setcon(const char* context)
+static void setcon(const char* context)
{
char new_context[512];
@@ -4010,7 +4016,7 @@ static void syz_setcon(const char* context)
int fd = open(SELINUX_CONTEXT_FILE, O_WRONLY);
if (fd < 0)
- fail("setcon: Could not open %s", SELINUX_CONTEXT_FILE);
+ fail("setcon: could not open context file");
ssize_t bytes_written = write(fd, context, strlen(context));
@@ -4019,45 +4025,29 @@ static void syz_setcon(const char* context)
close(fd);
if (bytes_written != (ssize_t)strlen(context))
- fail("setcon: Could not write entire context. Wrote %zi, expected %zu", bytes_written, strlen(context));
+ failmsg("setcon: could not write entire context", "wrote=%zi, expected=%zu", bytes_written, strlen(context));
// Validate the transition by checking the context
- syz_getcon(new_context, sizeof(new_context));
+ getcon(new_context, sizeof(new_context));
if (strcmp(context, new_context) != 0)
- fail("setcon: Failed to change to %s, context is %s", context, new_context);
-}
-
-// Similar to libselinux getfilecon(3), but:
-// - No library dependency
-// - No dynamic memory allocation
-// - Uses fail() instead of returning an error code
-static int syz_getfilecon(const char* path, char* context, size_t context_size)
-{
- int length = getxattr(path, SELINUX_XATTR_NAME, context, context_size);
-
- if (length == -1)
- fail("getfilecon: getxattr failed");
-
- return length;
+ failmsg("setcon: failed to change", "want=%s, context=%s", context, new_context);
}
// Similar to libselinux setfilecon(3), but:
// - No library dependency
// - No dynamic memory allocation
// - Uses fail() instead of returning an error code
-static void syz_setfilecon(const char* path, const char* context)
+static void setfilecon(const char* path, const char* context)
{
char new_context[512];
if (setxattr(path, SELINUX_XATTR_NAME, context, strlen(context) + 1, 0) != 0)
fail("setfilecon: setxattr failed");
-
- if (syz_getfilecon(path, new_context, sizeof(new_context)) <= 0)
- fail("setfilecon: getfilecon failed");
-
+ if (getxattr(path, SELINUX_XATTR_NAME, new_context, sizeof(new_context)) < 0)
+ fail("setfilecon: getxattr failed");
if (strcmp(context, new_context) != 0)
- fail("setfilecon: could not set context to %s, currently %s", context, new_context);
+ failmsg("setfilecon: could not set context", "want=%s, got=%s", context, new_context);
}
#define SYZ_HAVE_SANDBOX_ANDROID 1
@@ -4088,13 +4078,13 @@ static int do_sandbox_android(void)
#endif
if (chown(".", UNTRUSTED_APP_UID, UNTRUSTED_APP_UID) != 0)
- fail("chmod failed");
+ fail("do_sandbox_android: chmod failed");
if (setgroups(UNTRUSTED_APP_NUM_GROUPS, UNTRUSTED_APP_GROUPS) != 0)
- fail("setgroups failed");
+ fail("do_sandbox_android: setgroups failed");
if (setresgid(UNTRUSTED_APP_GID, UNTRUSTED_APP_GID, UNTRUSTED_APP_GID) != 0)
- fail("setresgid failed");
+ fail("do_sandbox_android: setresgid failed");
#if GOARCH_arm || GOARCH_arm64 || GOARCH_386 || GOARCH_amd64
// Will fail() if anything fails.
@@ -4104,13 +4094,13 @@ static int do_sandbox_android(void)
#endif
if (setresuid(UNTRUSTED_APP_UID, UNTRUSTED_APP_UID, UNTRUSTED_APP_UID) != 0)
- fail("setresuid failed");
+ fail("do_sandbox_android: setresuid failed");
// setresuid and setresgid clear the parent-death signal.
prctl(PR_SET_PDEATHSIG, SIGKILL, 0, 0, 0);
- syz_setfilecon(".", SELINUX_LABEL_APP_DATA_FILE);
- syz_setcon(SELINUX_CONTEXT_UNTRUSTED_APP);
+ setfilecon(".", SELINUX_LABEL_APP_DATA_FILE);
+ setcon(SELINUX_CONTEXT_UNTRUSTED_APP);
loop();
doexit(1);
@@ -4454,7 +4444,7 @@ static void setup_fault()
if (!write_file(files[i].file, files[i].val)) {
debug("failed to write %s: %d\n", files[i].file, errno);
if (files[i].fatal)
- fail("failed to write %s", files[i].file);
+ failmsg("failed to write fault injection file", "file=%s", files[i].file);
}
}
}
@@ -4473,12 +4463,12 @@ static void setup_leak()
{
// Flush boot leaks.
if (!write_file(KMEMLEAK_FILE, "scan"))
- fail("failed to write %s", KMEMLEAK_FILE);
+ fail("failed to write(kmemleak, \"scan\")");
sleep(5); // account for MSECS_MIN_AGE
if (!write_file(KMEMLEAK_FILE, "scan"))
- fail("failed to write %s", KMEMLEAK_FILE);
+ fail("failed to write(kmemleak, \"scan\")");
if (!write_file(KMEMLEAK_FILE, "clear"))
- fail("failed to write %s", KMEMLEAK_FILE);
+ fail("failed to write(kmemleak, \"clear\")");
}
#define SYZ_HAVE_LEAK_CHECK 1
@@ -4490,7 +4480,7 @@ static void check_leaks(void)
{
int fd = open(KMEMLEAK_FILE, O_RDWR);
if (fd == -1)
- fail("failed to open(\"%s\")", KMEMLEAK_FILE);
+ fail("failed to open(kmemleak)");
// KMEMLEAK has false positives. To mitigate most of them, it checksums
// potentially leaked objects, and reports them only on the next scan
// iff the checksum does not change. Because of that we do the following
@@ -4501,28 +4491,28 @@ static void check_leaks(void)
// hopefully these are true positives during the previous testing cycle.
uint64 start = current_time_ms();
if (write(fd, "scan", 4) != 4)
- fail("failed to write(%s, \"scan\")", KMEMLEAK_FILE);
+ fail("failed to write(kmemleak, \"scan\")");
sleep(1);
// Account for MSECS_MIN_AGE
// (1 second less because scanning will take at least a second).
while (current_time_ms() - start < 4 * 1000)
sleep(1);
if (write(fd, "scan", 4) != 4)
- fail("failed to write(%s, \"scan\")", KMEMLEAK_FILE);
+ fail("failed to write(kmemleak, \"scan\")");
static char buf[128 << 10];
ssize_t n = read(fd, buf, sizeof(buf) - 1);
if (n < 0)
- fail("failed to read(%s)", KMEMLEAK_FILE);
+ fail("failed to read(kmemleak)");
int nleaks = 0;
if (n != 0) {
sleep(1);
if (write(fd, "scan", 4) != 4)
- fail("failed to write(%s, \"scan\")", KMEMLEAK_FILE);
+ fail("failed to write(kmemleak, \"scan\")");
if (lseek(fd, 0, SEEK_SET) < 0)
- fail("failed to lseek(%s)", KMEMLEAK_FILE);
+ fail("failed to lseek(kmemleak)");
n = read(fd, buf, sizeof(buf) - 1);
if (n < 0)
- fail("failed to read(%s)", KMEMLEAK_FILE);
+ fail("failed to read(kmemleak)");
buf[n] = 0;
char* pos = buf;
char* end = buf + n;
@@ -4552,7 +4542,7 @@ static void check_leaks(void)
}
}
if (write(fd, "clear", 5) != 5)
- fail("failed to write(%s, \"clear\")", KMEMLEAK_FILE);
+ fail("failed to write(kmemleak, \"clear\")");
close(fd);
if (nleaks)
doexit(1);
@@ -4589,7 +4579,7 @@ static void setup_kcsan_filterlist(char** frames, int nframes, bool suppress)
{
int fd = open(KCSAN_DEBUGFS_FILE, O_WRONLY);
if (fd == -1)
- fail("failed to open(\"%s\")", KCSAN_DEBUGFS_FILE);
+ fail("failed to open kcsan debugfs file");
printf("%s KCSAN reports in functions: ",
suppress ? "suppressing" : "only showing");
diff --git a/executor/common_usb_netbsd.h b/executor/common_usb_netbsd.h
index 56c9718be..138b50557 100644
--- a/executor/common_usb_netbsd.h
+++ b/executor/common_usb_netbsd.h
@@ -218,14 +218,11 @@ static volatile long syz_usb_connect_impl(int fd, uint64 speed, uint64 dev_len,
analyze_usb_device(index);
#endif
- int rv = vhci_setport(fd, 1);
- if (rv != 0) {
- fail("syz_usb_connect: vhci_setport failed with %d", errno);
- }
+ if (vhci_setport(fd, 1))
+ fail("syz_usb_connect: vhci_setport failed with");
- rv = vhci_usb_attach(fd);
- if (rv != 0) {
- debug("syz_usb_connect: vhci_usb_attach failed with %d\n", rv);
+ if (vhci_usb_attach(fd)) {
+ debug("syz_usb_connect: vhci_usb_attach failed with %d\n", errno);
return -1;
}
debug("syz_usb_connect: vhci_usb_attach success\n");
@@ -234,8 +231,7 @@ static volatile long syz_usb_connect_impl(int fd, uint64 speed, uint64 dev_len,
while (!done) {
vhci_request_t req;
- rv = vhci_usb_recv(fd, &req, sizeof(req));
- if (rv != 0) {
+ if (vhci_usb_recv(fd, &req, sizeof(req))) {
debug("syz_usb_connect: vhci_usb_recv failed with %d\n", errno);
return -1;
}
@@ -285,6 +281,7 @@ static volatile long syz_usb_connect_impl(int fd, uint64 speed, uint64 dev_len,
else
memset(data, 0, response_length);
+ int rv = 0;
if (req.u.ctrl.bmRequestType & UE_DIR_IN) {
debug("syz_usb_connect: writing %d bytes\n", response_length);
if (response_length > 0) {
@@ -329,9 +326,8 @@ static volatile long syz_usb_connect(volatile long a0, volatile long a1,
debug_dump_data(dev, dev_len);
int fd = vhci_open();
- if (fd < 0) {
- fail("syz_usb_connect: vhci_open failed with %d", errno);
- }
+ if (fd < 0)
+ fail("syz_usb_connect: vhci_open failed");
long res = syz_usb_connect_impl(fd, speed, dev_len, dev, descs, &lookup_connect_response_out_generic);
close(fd);
return res;
diff --git a/executor/cov_filter.h b/executor/cov_filter.h
index 26eb67ec8..a8b6624fe 100644
--- a/executor/cov_filter.h
+++ b/executor/cov_filter.h
@@ -30,7 +30,7 @@ static void init_coverage_filter()
void* preferred = (void*)0x110f230000ull;
cov_filter = (cov_filter_t*)mmap(preferred, st.st_size, PROT_READ, MAP_PRIVATE, f, 0);
if (cov_filter != preferred)
- fail("failed to initialize coverage filter bitmap at %p", preferred);
+ failmsg("failed to mmap coverage filter bitmap", "want=%p, got=%p", preferred, cov_filter);
if ((uint32)st.st_size != sizeof(uint32) * 2 + ((cov_filter->pcsize >> 4) + 7) / 8)
fail("bad coverage filter bitmap size");
close(f);
diff --git a/executor/executor.cc b/executor/executor.cc
index 5bb2d7226..80fdc49cc 100644
--- a/executor/executor.cc
+++ b/executor/executor.cc
@@ -75,7 +75,12 @@ const int kCoverSize = 256 << 10;
const int kFailStatus = 67;
// Logical error (e.g. invalid input program), use as an assert() alternative.
-static NORETURN PRINTF(1, 2) void fail(const char* msg, ...);
+// If such error happens 10+ times in a row, it will be detected as a bug by syz-fuzzer.
+// syz-fuzzer will fail and syz-manager will create a bug for this.
+// Note: err is used for bug deduplication, thus distinction between err (constant message)
+// and msg (varying part).
+static NORETURN void fail(const char* err);
+static NORETURN PRINTF(2, 3) void failmsg(const char* err, const char* msg, ...);
// Just exit (e.g. due to temporal ENOMEM error).
static NORETURN PRINTF(1, 2) void exitf(const char* msg, ...);
static NORETURN void doexit(int status);
@@ -524,9 +529,9 @@ void receive_handshake()
handshake_req req = {};
int n = read(kInPipeFd, &req, sizeof(req));
if (n != sizeof(req))
- fail("handshake read failed: %d", n);
+ failmsg("handshake read failed", "read=%d", n);
if (req.magic != kInMagic)
- fail("bad handshake magic 0x%llx", req.magic);
+ failmsg("bad handshake magic", "magic=0x%llx", req.magic);
parse_env_flags(req.flags);
procid = req.pid;
}
@@ -548,9 +553,9 @@ void receive_execute()
if (read(kInPipeFd, &req, sizeof(req)) != (ssize_t)sizeof(req))
fail("control pipe read failed");
if (req.magic != kInMagic)
- fail("bad execute request magic 0x%llx", req.magic);
+ failmsg("bad execute request magic", "magic=0x%llx", req.magic);
if (req.prog_size > kMaxInput)
- fail("bad execute prog size 0x%llx", req.prog_size);
+ failmsg("bad execute prog size", "size=0x%llx", req.prog_size);
parse_env_flags(req.env_flags);
procid = req.pid;
syscall_timeout_ms = req.syscall_timeout_ms;
@@ -574,7 +579,8 @@ void receive_execute()
flag_fault_call, flag_fault_nth, syscall_timeout_ms, program_timeout_ms, slowdown_scale,
req.prog_size, flag_coverage_filter);
if (syscall_timeout_ms == 0 || program_timeout_ms <= syscall_timeout_ms || slowdown_scale == 0)
- fail("bad timeouts: %llu/%llu/%llu", syscall_timeout_ms, program_timeout_ms, slowdown_scale);
+ failmsg("bad timeouts", "syscall=%llu, program=%llu, scale=%llu",
+ syscall_timeout_ms, program_timeout_ms, slowdown_scale);
if (SYZ_EXECUTOR_USES_SHMEM) {
if (req.prog_size)
fail("need_prog: no program");
@@ -592,7 +598,7 @@ void receive_execute()
break;
}
if (pos != req.prog_size)
- fail("bad input size %lld, want %lld", pos, req.prog_size);
+ failmsg("bad input size", "size=%lld, want=%lld", pos, req.prog_size);
}
#if GOOS_akaros
@@ -681,7 +687,7 @@ retry:
switch (csum_kind) {
case arg_csum_inet: {
if (size != 2)
- fail("inet checksum must be 2 bytes, not %llu", size);
+ failmsg("bag inet checksum size", "size=%llu", size);
debug_verbose("calculating checksum for %p\n", csum_addr);
struct csum_inet csum;
csum_inet_init(&csum);
@@ -698,16 +704,15 @@ retry:
NONFAILING(csum_inet_update(&csum, (const uint8*)chunk_value, chunk_size));
break;
case arg_csum_chunk_const:
- if (chunk_size != 2 && chunk_size != 4 && chunk_size != 8) {
- fail("bad checksum const chunk size %lld", chunk_size);
- }
+ if (chunk_size != 2 && chunk_size != 4 && chunk_size != 8)
+ failmsg("bad checksum const chunk size", "size=%lld", chunk_size);
// Here we assume that const values come to us big endian.
debug_verbose("#%lld: const chunk, value: %llx, size: %llu\n",
chunk, chunk_value, chunk_size);
csum_inet_update(&csum, (const uint8*)&chunk_value, chunk_size);
break;
default:
- fail("bad checksum chunk kind %llu", chunk_kind);
+ failmsg("bad checksum chunk kind", "kind=%llu", chunk_kind);
}
}
uint16 csum_value = csum_inet_digest(&csum);
@@ -716,12 +721,12 @@ retry:
break;
}
default:
- fail("bad checksum kind %llu", csum_kind);
+ failmsg("bad checksum kind", "kind=%llu", csum_kind);
}
break;
}
default:
- fail("bad argument type %llu", typ);
+ failmsg("bad argument type", "type=%llu", typ);
}
continue;
}
@@ -735,10 +740,10 @@ retry:
// Normal syscall.
if (call_num >= ARRAY_SIZE(syscalls))
- fail("invalid command number %llu", call_num);
+ failmsg("invalid syscall number", "call_num=%llu", call_num);
const call_t* call = &syscalls[call_num];
if (call->attrs.disabled)
- fail("executing disabled syscall %s", call->name);
+ failmsg("executing disabled syscall", "syscall=%s", call->name);
if (prog_extra_timeout < call->attrs.prog_timeout)
prog_extra_timeout = call->attrs.prog_timeout * slowdown_scale;
if (strncmp(syscalls[call_num].name, "syz_usb", strlen("syz_usb")) == 0)
@@ -748,7 +753,7 @@ retry:
uint64 copyout_index = read_input(&input_pos);
uint64 num_args = read_input(&input_pos);
if (num_args > kMaxArgs)
- fail("command has bad number of arguments %llu", num_args);
+ failmsg("command has bad number of arguments", "args=%llu", num_args);
uint64 args[kMaxArgs] = {};
for (uint64 i = 0; i < num_args; i++)
args[i] = read_arg(&input_pos);
@@ -856,8 +861,8 @@ thread_t* schedule_call(int call_index, int call_num, bool colliding, uint64 cop
exitf("out of threads");
thread_t* th = &threads[i];
if (event_isset(&th->ready) || !event_isset(&th->done) || th->executing)
- fail("bad thread state in schedule: ready=%d done=%d executing=%d",
- event_isset(&th->ready), event_isset(&th->done), th->executing);
+ failmsg("bad thread state in schedule", "ready=%d done=%d executing=%d",
+ event_isset(&th->ready), event_isset(&th->done), th->executing);
last_scheduled = th;
th->colliding = colliding;
th->copyout_pos = pos;
@@ -925,8 +930,8 @@ void write_coverage_signal(cover_t* cov, uint32* signal_count_pos, uint32* cover
void handle_completion(thread_t* th)
{
if (event_isset(&th->ready) || !event_isset(&th->done) || !th->executing)
- fail("bad thread state in completion: ready=%d done=%d executing=%d",
- event_isset(&th->ready), event_isset(&th->done), th->executing);
+ failmsg("bad thread state in completion", "ready=%d done=%d executing=%d",
+ event_isset(&th->ready), event_isset(&th->done), th->executing);
if (th->res != (intptr_t)-1)
copyout_call_results(th);
if (!collide && !th->colliding) {
@@ -947,7 +952,7 @@ void handle_completion(thread_t* th)
event_isset(&th1->ready), event_isset(&th1->done),
th1->call_index, (uint64)th1->res, th1->reserrno);
}
- fail("running = %d", running);
+ fail("negative running");
}
}
@@ -955,7 +960,7 @@ void copyout_call_results(thread_t* th)
{
if (th->copyout_index != no_copyout) {
if (th->copyout_index >= kMaxCommands)
- fail("result idx %lld overflows kMaxCommands", th->copyout_index);
+ failmsg("result overflows kMaxCommands", "index=%lld", th->copyout_index);
results[th->copyout_index].executed = true;
results[th->copyout_index].val = th->res;
}
@@ -965,7 +970,7 @@ void copyout_call_results(thread_t* th)
case instr_copyout: {
uint64 index = read_input(&th->copyout_pos);
if (index >= kMaxCommands)
- fail("result idx %lld overflows kMaxCommands", index);
+ failmsg("result overflows kMaxCommands", "index=%lld", index);
char* addr = (char*)read_input(&th->copyout_pos);
uint64 size = read_input(&th->copyout_pos);
uint64 val = 0;
@@ -1008,7 +1013,7 @@ void write_call_output(thread_t* th, bool finished)
kcov_comparison_t* start = (kcov_comparison_t*)(th->cov.data + sizeof(uint64));
kcov_comparison_t* end = start + ncomps;
if ((char*)end > th->cov.data_end)
- fail("too many comparisons %u", ncomps);
+ failmsg("too many comparisons", "ncomps=%u", ncomps);
cover_unprotect(&th->cov);
std::sort(start, end);
ncomps = std::unique(start, end) - start;
@@ -1143,7 +1148,7 @@ void execute_call(thread_t* th)
if (flag_coverage) {
cover_collect(&th->cov);
if (th->cov.size >= kCoverSize)
- fail("#%d: too much cover %u", th->id, th->cov.size);
+ failmsg("too much cover", "thr=%d, cov=%u", th->id, th->cov.size);
}
th->fault_injected = false;
@@ -1217,7 +1222,7 @@ void copyin(char* addr, uint64 val, uint64 size, uint64 bf, uint64 bf_off, uint6
debug_verbose("copyin: addr=%p val=0x%llx size=%llu bf=%llu bf_off=%llu bf_len=%llu\n",
addr, val, size, bf, bf_off, bf_len);
if (bf != binary_format_native && bf != binary_format_bigendian && (bf_off != 0 || bf_len != 0))
- fail("bitmask for string format %llu/%llu", bf_off, bf_len);
+ failmsg("bitmask for string format", "off=%llu, len=%llu", bf_off, bf_len);
switch (bf) {
case binary_format_native:
case binary_format_bigendian:
@@ -1235,26 +1240,26 @@ void copyin(char* addr, uint64 val, uint64 size, uint64 bf, uint64 bf_off, uint6
copyin_int<uint64>(addr, val, bf, bf_off, bf_len);
break;
default:
- fail("copyin: bad argument size %llu", size);
+ failmsg("copyin: bad argument size", "size=%llu", size);
});
break;
case binary_format_strdec:
if (size != 20)
- fail("bad strdec size %llu", size);
+ failmsg("bad strdec size", "size=%llu", size);
NONFAILING(sprintf((char*)addr, "%020llu", val));
break;
case binary_format_strhex:
if (size != 18)
- fail("bad strhex size %llu", size);
+ failmsg("bad strhex size", "size=%llu", size);
NONFAILING(sprintf((char*)addr, "0x%016llx", val));
break;
case binary_format_stroct:
if (size != 23)
- fail("bad stroct size %llu", size);
+ failmsg("bad stroct size", "size=%llu", size);
NONFAILING(sprintf((char*)addr, "%023llo", val));
break;
default:
- fail("unknown binary format %llu", bf);
+ failmsg("unknown binary format", "format=%llu", bf);
}
}
@@ -1275,7 +1280,7 @@ bool copyout(char* addr, uint64 size, uint64* res)
*res = *(uint64*)addr;
break;
default:
- fail("copyout: bad argument size %llu", size);
+ failmsg("copyout: bad argument size", "size=%llu", size);
});
}
@@ -1287,20 +1292,20 @@ uint64 read_arg(uint64** input_posp)
uint64 size, bf, bf_off, bf_len;
uint64 val = read_const_arg(input_posp, &size, &bf, &bf_off, &bf_len);
if (bf != binary_format_native && bf != binary_format_bigendian)
- fail("bad argument binary format %llu", bf);
+ failmsg("bad argument binary format", "format=%llu", bf);
if (bf_off != 0 || bf_len != 0)
- fail("bad argument bitfield %llu/%llu", bf_off, bf_len);
+ failmsg("bad argument bitfield", "off=%llu, len=%llu", bf_off, bf_len);
return swap(val, size, bf);
}
case arg_result: {
uint64 meta = read_input(input_posp);
uint64 bf = meta >> 8;
if (bf != binary_format_native)
- fail("bad result argument format %llu", bf);
+ failmsg("bad result argument format", "format=%llu", bf);
return read_result(input_posp);
}
default:
- fail("bad argument type %llu", typ);
+ failmsg("bad argument type", "type=%llu", typ);
}
}
@@ -1309,7 +1314,7 @@ uint64 swap(uint64 v, uint64 size, uint64 bf)
if (bf == binary_format_native)
return v;
if (bf != binary_format_bigendian)
- fail("bad binary format in swap: %llu", bf);
+ failmsg("bad binary format in swap", "format=%llu", bf);
switch (size) {
case 2:
return htobe16(v);
@@ -1318,7 +1323,7 @@ uint64 swap(uint64 v, uint64 size, uint64 bf)
case 8:
return htobe64(v);
default:
- fail("bad big-endian int size %llu", size);
+ failmsg("bad big-endian int size", "size=%llu", size);
}
}
@@ -1343,7 +1348,7 @@ uint64 read_result(uint64** input_posp)
uint64 op_add = read_input(input_posp);
uint64 arg = read_input(input_posp);
if (idx >= kMaxCommands)
- fail("command refers to bad result %lld", idx);
+ failmsg("command refers to bad result", "result=%lld", idx);
if (results[idx].executed) {
arg = results[idx].val;
if (op_div != 0)
@@ -1357,7 +1362,7 @@ uint64 read_input(uint64** input_posp, bool peek)
{
uint64* input_pos = *input_posp;
if ((char*)input_pos >= input_data + kMaxInput)
- fail("input command overflows input %p: [%p:%p)", input_pos, input_data, input_data + kMaxInput);
+ failmsg("input command overflows input", "pos=%p: [%p:%p)", input_pos, input_data, input_data + kMaxInput);
if (!peek)
*input_posp = input_pos + 1;
return *input_pos;
@@ -1367,8 +1372,8 @@ uint64 read_input(uint64** input_posp, bool peek)
uint32* write_output(uint32 v)
{
if (output_pos < output_data || (char*)output_pos >= (char*)output_data + kMaxOutput)
- fail("output overflow: pos=%p region=[%p:%p]",
- output_pos, output_data, (char*)output_data + kMaxOutput);
+ failmsg("output overflow", "pos=%p region=[%p:%p]",
+ output_pos, output_data, (char*)output_data + kMaxOutput);
*output_pos = v;
return output_pos++;
}
@@ -1376,8 +1381,8 @@ uint32* write_output(uint32 v)
uint32* write_output_64(uint64 v)
{
if (output_pos < output_data || (char*)(output_pos + 1) >= (char*)output_data + kMaxOutput)
- fail("output overflow: pos=%p region=[%p:%p]",
- output_pos, output_data, (char*)output_data + kMaxOutput);
+ failmsg("output overflow", "pos=%p region=[%p:%p]",
+ output_pos, output_data, (char*)output_data + kMaxOutput);
*(uint64*)output_pos = v;
output_pos += 2;
return output_pos;
@@ -1393,7 +1398,7 @@ void write_completed(uint32 completed)
void kcov_comparison_t::write()
{
if (type > (KCOV_CMP_CONST | KCOV_CMP_SIZE_MASK))
- fail("invalid kcov comp type %llx", type);
+ failmsg("invalid kcov comp type", "type=%llx", type);
// Write order: type arg1 arg2 pc.
write_output((uint32)type);
@@ -1499,18 +1504,21 @@ void setup_features(char** enable, int n)
}
#endif
if (!found)
- fail("unknown feature %s", enable[i]);
+ failmsg("setup features: unknown feature", "feature=%s", enable[i]);
}
}
-void fail(const char* msg, ...)
+void failmsg(const char* err, const char* msg, ...)
{
int e = errno;
- va_list args;
- va_start(args, msg);
- vfprintf(stderr, msg, args);
- va_end(args);
- fprintf(stderr, " (errno %d)\n", e);
+ if (msg) {
+ va_list args;
+ va_start(args, msg);
+ vfprintf(stderr, msg, args);
+ va_end(args);
+ }
+ fprintf(stderr, " (errno %d: %s)\n", e, strerror(e));
+ fprintf(stderr, "SYZFAIL: %s\n", err);
// fail()'s are often used during the validation of kernel reactions to queries
// that were issued by pseudo syscalls implementations. As fault injection may
@@ -1528,6 +1536,11 @@ void fail(const char* msg, ...)
doexit(kFailStatus);
}
+void fail(const char* err)
+{
+ failmsg(err, 0);
+}
+
void exitf(const char* msg, ...)
{
int e = errno;
diff --git a/executor/executor_bsd.h b/executor/executor_bsd.h
index fa31099fe..8ef8186f8 100644
--- a/executor/executor_bsd.h
+++ b/executor/executor_bsd.h
@@ -61,7 +61,7 @@ static void cover_open(cover_t* cov, bool extra)
if (fd == -1)
fail("open of /dev/kcov failed");
if (dup2(fd, cov->fd) < 0)
- fail("failed to dup2(%d, %d) cover fd", fd, cov->fd);
+ failmsg("failed to dup cover fd", "from=%d, to=%d", fd, cov->fd);
close(fd);
#if GOOS_freebsd
diff --git a/executor/executor_fuchsia.h b/executor/executor_fuchsia.h
index 88a1ccff5..646711079 100644
--- a/executor/executor_fuchsia.h
+++ b/executor/executor_fuchsia.h
@@ -15,7 +15,7 @@ static void os_init(int argc, char** argv, void* data, size_t data_size)
{
zx_status_t status = syz_mmap((size_t)data, data_size);
if (status != ZX_OK)
- fail("mmap of data segment failed: %s (%d)", zx_status_get_string(status), status);
+ failmsg("mmap of data segment failed", "status=%s (%d)", zx_status_get_string(status), status);
}
static intptr_t execute_syscall(const call_t* c, intptr_t a[kMaxArgs])
diff --git a/executor/executor_linux.h b/executor/executor_linux.h
index 57c2638ea..3a0620fcd 100644
--- a/executor/executor_linux.h
+++ b/executor/executor_linux.h
@@ -79,7 +79,7 @@ static void cover_open(cover_t* cov, bool extra)
if (fd == -1)
fail("open of /sys/kernel/debug/kcov failed");
if (dup2(fd, cov->fd) < 0)
- fail("filed to dup2(%d, %d) cover fd", fd, cov->fd);
+ failmsg("filed to dup cover fd", "from=%d, to=%d", fd, cov->fd);
close(fd);
const int kcov_init_trace = is_kernel_64_bit ? KCOV_INIT_TRACE64 : KCOV_INIT_TRACE32;
const int cover_size = extra ? kExtraCoverSize : kCoverSize;
diff --git a/executor/style_test.go b/executor/style_test.go
index 3b0ee8ce7..9c83f2536 100644
--- a/executor/style_test.go
+++ b/executor/style_test.go
@@ -111,12 +111,20 @@ if (foo)
},
},
{
- pattern: `\s*(fail|exitf)\(".*\\n`,
+ pattern: `(fail|exitf)\(".*\\n`,
message: "Don't use \\n in fail/exitf messages",
tests: []string{
`fail("some message with new line\n");`,
},
},
+ {
+ pattern: `fail(msg)?\("[^"]*%`,
+ message: "DON'T",
+ tests: []string{
+ `fail("format %s string")`,
+ `failmsg("format %s string", "format")`,
+ },
+ },
}
for _, check := range checks {
re := regexp.MustCompile(check.pattern)
diff --git a/pkg/csource/csource.go b/pkg/csource/csource.go
index a01141567..24717a31a 100644
--- a/pkg/csource/csource.go
+++ b/pkg/csource/csource.go
@@ -500,7 +500,7 @@ func (ctx *context) postProcess(result []byte) []byte {
result = regexp.MustCompile(`\t*debug\((.*\n)*?.*\);\n`).ReplaceAll(result, nil)
result = regexp.MustCompile(`\t*debug_dump_data\((.*\n)*?.*\);\n`).ReplaceAll(result, nil)
result = regexp.MustCompile(`\t*exitf\((.*\n)*?.*\);\n`).ReplaceAll(result, []byte("\texit(1);\n"))
- result = regexp.MustCompile(`\t*fail\((.*\n)*?.*\);\n`).ReplaceAll(result, []byte("\texit(1);\n"))
+ result = regexp.MustCompile(`\t*fail(msg)?\((.*\n)*?.*\);\n`).ReplaceAll(result, []byte("\texit(1);\n"))
result = ctx.hoistIncludes(result)
result = ctx.removeEmptyLines(result)
diff --git a/pkg/csource/generated.go b/pkg/csource/generated.go
index 2d9b1ff4a..62e9b0573 100644
--- a/pkg/csource/generated.go
+++ b/pkg/csource/generated.go
@@ -1420,14 +1420,11 @@ static volatile long syz_usb_connect_impl(int fd, uint64 speed, uint64 dev_len,
analyze_usb_device(index);
#endif
- int rv = vhci_setport(fd, 1);
- if (rv != 0) {
- fail("syz_usb_connect: vhci_setport failed with %d", errno);
- }
+ if (vhci_setport(fd, 1))
+ fail("syz_usb_connect: vhci_setport failed with");
- rv = vhci_usb_attach(fd);
- if (rv != 0) {
- debug("syz_usb_connect: vhci_usb_attach failed with %d\n", rv);
+ if (vhci_usb_attach(fd)) {
+ debug("syz_usb_connect: vhci_usb_attach failed with %d\n", errno);
return -1;
}
debug("syz_usb_connect: vhci_usb_attach success\n");
@@ -1436,8 +1433,7 @@ static volatile long syz_usb_connect_impl(int fd, uint64 speed, uint64 dev_len,
while (!done) {
vhci_request_t req;
- rv = vhci_usb_recv(fd, &req, sizeof(req));
- if (rv != 0) {
+ if (vhci_usb_recv(fd, &req, sizeof(req))) {
debug("syz_usb_connect: vhci_usb_recv failed with %d\n", errno);
return -1;
}
@@ -1486,6 +1482,7 @@ static volatile long syz_usb_connect_impl(int fd, uint64 speed, uint64 dev_len,
else
memset(data, 0, response_length);
+ int rv = 0;
if (req.u.ctrl.bmRequestType & UE_DIR_IN) {
debug("syz_usb_connect: writing %d bytes\n", response_length);
if (response_length > 0) {
@@ -1530,9 +1527,8 @@ static volatile long syz_usb_connect(volatile long a0, volatile long a1,
debug_dump_data(dev, dev_len);
int fd = vhci_open();
- if (fd < 0) {
- fail("syz_usb_connect: vhci_open failed with %d", errno);
- }
+ if (fd < 0)
+ fail("syz_usb_connect: vhci_open failed");
long res = syz_usb_connect_impl(fd, speed, dev_len, dev, descs, &lookup_connect_response_out_generic);
close(fd);
return res;
@@ -1570,7 +1566,7 @@ static void setup_usb(void)
char path[1024];
snprintf(path, sizeof(path), "/dev/%s", ent->d_name);
if (chmod(path, 0666))
- fail("failed to chmod %s", path);
+ failmsg("failed to chmod vhci", "path=%s", path);
}
closedir(dir);
@@ -1598,7 +1594,7 @@ static int inject_fault(int nth)
en.mode = 0;
en.nth = nth + 2;
if (ioctl(fd, FAULT_IOC_ENABLE, &en) != 0)
- fail("FAULT_IOC_ENABLE failed with nth=%d", nth);
+ failmsg("FAULT_IOC_ENABLE failed", "nth=%d", nth);
return fd;
}
@@ -1680,7 +1676,7 @@ static void vsnprintf_check(char* str, size_t size, const char* format, va_list
if (rv < 0)
fail("vsnprintf failed");
if ((size_t)rv >= size)
- fail("vsnprintf: string '%s...' doesn't fit into buffer", str);
+ failmsg("vsnprintf: string doesn't fit into buffer", "string='%s'", str);
}
static void snprintf_check(char* str, size_t size, const char* format, ...)
@@ -1707,7 +1703,7 @@ static void execute_command(bool panic, const char* format, ...)
int rv = system(command);
if (rv) {
if (panic)
- fail("command '%s' failed: %d", &command[0], rv);
+ failmsg("command failed", "command=%s: %d", &command[0], rv);
debug("command '%s': %d\n", &command[0], rv);
}
}
@@ -1719,9 +1715,8 @@ static void initialize_tun(int tun_id)
return;
#endif
- if (tun_id < 0 || tun_id >= MAX_TUN) {
- fail("tun_id out of range %d", tun_id);
- }
+ if (tun_id < 0 || tun_id >= MAX_TUN)
+ failmsg("tun_id out of range", "tun_id=%d", tun_id);
char tun_device[sizeof(TUN_DEVICE)];
snprintf_check(tun_device, sizeof(tun_device), TUN_DEVICE, tun_id);
@@ -1745,7 +1740,7 @@ static void initialize_tun(int tun_id)
#endif
if (tunfd == -1) {
#if SYZ_EXECUTOR
- fail("tun: can't open %s", tun_device);
+ failmsg("tun: can't open device", "device=%s", tun_device);
#else
printf("tun: can't open %s: errno=%d\n", tun_device, errno);
return;
@@ -1813,7 +1808,7 @@ static int read_tun(char* data, int size)
if (rv < 0) {
if (errno == EAGAIN)
return -1;
- fail("tun: read failed with %d", rv);
+ fail("tun: read failed");
}
return rv;
}
@@ -2100,7 +2095,8 @@ static void install_segv_handler(void)
zx_status_t status;
zx_handle_t exception_channel;
if ((status = zx_task_create_exception_channel(zx_process_self(), 0, &exception_channel)) != ZX_OK)
- fail("zx_task_create_exception_channel failed: %s (%d)", zx_status_get_string(status), status);
+ failmsg("zx_task_create_exception_channel failed",
+ "status=%s (%d)", zx_status_get_string(status), status);
pthread_t th;
if (pthread_create(&th, 0, ex_handler, (void*)(long)exception_channel))
fail("pthread_create failed");
@@ -2437,7 +2433,7 @@ static int netlink_send_ext(struct nlmsg* nlmsg, int sock,
ssize_t n = sendto(sock, nlmsg->buf, hdr->nlmsg_len, 0, (struct sockaddr*)&addr, sizeof(addr));
if (n != (ssize_t)hdr->nlmsg_len) {
if (dofail)
- fail("netlink_send_ext: short netlink write: %zd/%d", n, hdr->nlmsg_len);
+ failmsg("netlink_send_ext: short netlink write", "wrote=%zd, want=%d", n, hdr->nlmsg_len);
debug("netlink_send_ext: short netlink write: %zd/%d errno=%d\n", n, hdr->nlmsg_len, errno);
return -1;
}
@@ -2446,14 +2442,14 @@ static int netlink_send_ext(struct nlmsg* nlmsg, int sock,
*reply_len = 0;
if (n < 0) {
if (dofail)
- fail("netlink_send_ext: netlink read failed: %zd", n);
- debug("netlink_send_ext: netlink read failed: %zd errno=%d\n", n, errno);
+ fail("netlink_send_ext: netlink read failed");
+ debug("netlink_send_ext: netlink read failed: errno=%d\n", errno);
return -1;
}
if (n < (ssize_t)sizeof(struct nlmsghdr)) {
errno = EINVAL;
if (dofail)
- fail("netlink_send_ext: short netlink read: %zd", n);
+ failmsg("netlink_send_ext: short netlink read", "read=%zd", n);
debug("netlink_send_ext: short netlink read: %zd\n", n);
return -1;
}
@@ -2466,14 +2462,14 @@ static int netlink_send_ext(struct nlmsg* nlmsg, int sock,
if (n < (ssize_t)(sizeof(struct nlmsghdr) + sizeof(struct nlmsgerr))) {
errno = EINVAL;
if (dofail)
- fail("netlink_send_ext: short netlink read: %zd", n);
+ failmsg("netlink_send_ext: short netlink read", "read=%zd", n);
debug("netlink_send_ext: short netlink read: %zd\n", n);
return -1;
}
if (hdr->nlmsg_type != NLMSG_ERROR) {
errno = EINVAL;
if (dofail)
- fail("netlink_send_ext: short netlink ack: %d", hdr->nlmsg_type);
+ failmsg("netlink_send_ext: bad netlink ack type", "type=%d", hdr->nlmsg_type);
debug("netlink_send_ext: short netlink ack: %d\n", hdr->nlmsg_type);
return -1;
}
@@ -3231,19 +3227,20 @@ static void initialize_wifi_devices(void)
mac_addr[5] = device_id;
int ret = hwsim80211_create_device(&nlmsg, sock, hwsim_family_id, mac_addr);
if (ret < 0)
- fail("initialize_wifi_devices: failed to create device #%d", device_id);
+ failmsg("initialize_wifi_devices: failed to create device", "device=%d", device_id);
char interface[6] = "wlan0";
interface[4] += device_id;
if (nl80211_setup_ibss_interface(&nlmsg, sock, nl80211_family_id, interface, &ibss_props) < 0)
- fail("initialize_wifi_devices: failed set up IBSS network for #%d", device_id);
+ failmsg("initialize_wifi_devices: failed set up IBSS network", "device=%d", device_id);
}
for (int device_id = 0; device_id < WIFI_INITIAL_DEVICE_COUNT; device_id++) {
char interface[6] = "wlan0";
interface[4] += device_id;
int ret = await_ifla_operstate(&nlmsg, interface, IF_OPER_UP);
if (ret < 0)
- fail("initialize_wifi_devices: get_ifla_operstate failed for #%d, ret %d", device_id, ret);
+ failmsg("initialize_wifi_devices: get_ifla_operstate failed",
+ "device=%d, ret=%d", device_id, ret);
}
close(sock);
@@ -3722,7 +3719,7 @@ static int read_tun(char* data, int size)
if (rv < 0) {
if (errno == EAGAIN || errno == EBADFD)
return -1;
- fail("tun: read failed with %d", rv);
+ fail("tun read failed");
}
return rv;
}
@@ -3944,16 +3941,14 @@ static long syz_io_uring_submit(volatile long a0, volatile long a1, volatile lon
static long syz_usbip_server_init(volatile long a0)
{
- int socket_pair[2];
- char buffer[100];
static int port_alloc[2];
int speed = (int)a0;
bool usb3 = (speed == USB_SPEED_SUPER);
- int rc = socketpair(AF_UNIX, SOCK_STREAM, 0, socket_pair);
- if (rc < 0)
- fail("syz_usbip_server_init : socketpair failed: %d", rc);
+ int socket_pair[2];
+ if (socketpair(AF_UNIX, SOCK_STREAM, 0, socket_pair))
+ fail("syz_usbip_server_init: socketpair failed");
int client_fd = socket_pair[0];
int server_fd = socket_pair[1];
@@ -3964,6 +3959,7 @@ static long syz_usbip_server_init(volatile long a0)
return -1;
}
int port_num = procid * VHCI_PORTS + usb3 * VHCI_HC_PORTS + available_port_num;
+ char buffer[100];
sprintf(buffer, "%d %d %s %d", port_num, client_fd, "0", speed);
write_file("/sys/devices/platform/vhci_hcd.0/attach", buffer);
@@ -5885,7 +5881,7 @@ static bool process_command_pkt(int fd, char* buf, ssize_t buf_size)
struct hci_command_hdr* hdr = (struct hci_command_hdr*)buf;
if (buf_size < (ssize_t)sizeof(struct hci_command_hdr) ||
hdr->plen != buf_size - sizeof(struct hci_command_hdr)) {
- fail("invalid size: %zx", buf_size);
+ failmsg("process_command_pkt: invalid size", "suze=%zx", buf_size);
}
switch (hdr->opcode) {
@@ -7488,7 +7484,7 @@ static void checkpoint_iptables(struct ipt_table_desc* tables, int num_tables, i
case ENOPROTOOPT:
return;
}
- fail("iptable checkpoint %d: socket failed", family);
+ failmsg("iptable checkpoint: socket(SOCK_STREAM, IPPROTO_TCP) failed", "family=%d", family);
}
for (int i = 0; i < num_tables; i++) {
struct ipt_table_desc* table = &tables[i];
@@ -7502,25 +7498,26 @@ static void checkpoint_iptables(struct ipt_table_desc* tables, int num_tables, i
case ENOPROTOOPT:
continue;
}
- fail("iptable checkpoint %s/%d: getsockopt(IPT_SO_GET_INFO)", table->name, family);
+ failmsg("iptable checkpoint: getsockopt(IPT_SO_GET_INFO) failed",
+ "table=%s, family=%d", table->name, family);
}
debug("iptable checkpoint %s/%d: checkpoint entries=%d hooks=%x size=%d\n",
table->name, family, table->info.num_entries,
table->info.valid_hooks, table->info.size);
if (table->info.size > sizeof(table->replace.entrytable))
- fail("iptable checkpoint %s/%d: table size is too large: %u",
- table->name, family, table->info.size);
+ failmsg("iptable checkpoint: table size is too large", "table=%s, family=%d, size=%u",
+ table->name, family, table->info.size);
if (table->info.num_entries > XT_MAX_ENTRIES)
- fail("iptable checkpoint %s/%d: too many counters: %u",
- table->name, family, table->info.num_entries);
+ failmsg("iptable checkpoint: too many counters", "table=%s, family=%d, counters=%d",
+ table->name, family, table->info.num_entries);
struct ipt_get_entries entries;
memset(&entries, 0, sizeof(entries));
strcpy(entries.name, table->name);
entries.size = table->info.size;
optlen = sizeof(entries) - sizeof(entries.entrytable) + table->info.size;
if (getsockopt(fd, level, IPT_SO_GET_ENTRIES, &entries, &optlen))
- fail("iptable checkpoint %s/%d: getsockopt(IPT_SO_GET_ENTRIES)",
- table->name, family);
+ failmsg("iptable checkpoint: getsockopt(IPT_SO_GET_ENTRIES) failed",
+ "table=%s, family=%d", table->name, family);
table->replace.valid_hooks = table->info.valid_hooks;
table->replace.num_entries = table->info.num_entries;
table->replace.size = table->info.size;
@@ -7540,7 +7537,7 @@ static void reset_iptables(struct ipt_table_desc* tables, int num_tables, int fa
case ENOPROTOOPT:
return;
}
- fail("iptable %d: socket failed", family);
+ failmsg("iptable: socket(SOCK_STREAM, IPPROTO_TCP) failed", "family=%d", family);
}
for (int i = 0; i < num_tables; i++) {
struct ipt_table_desc* table = &tables[i];
@@ -7551,7 +7548,8 @@ static void reset_iptables(struct ipt_table_desc* tables, int num_tables, int fa
strcpy(info.name, table->name);
socklen_t optlen = sizeof(info);
if (getsockopt(fd, level, IPT_SO_GET_INFO, &info, &optlen))
- fail("iptable %s/%d: getsockopt(IPT_SO_GET_INFO)", table->name, family);
+ failmsg("iptable: getsockopt(IPT_SO_GET_INFO) failed",
+ "table=%s, family=%d", table->name, family);
if (memcmp(&table->info, &info, sizeof(table->info)) == 0) {
struct ipt_get_entries entries;
memset(&entries, 0, sizeof(entries));
@@ -7559,7 +7557,8 @@ static void reset_iptables(struct ipt_table_desc* tables, int num_tables, int fa
entries.size = table->info.size;
optlen = sizeof(entries) - sizeof(entries.entrytable) + entries.size;
if (getsockopt(fd, level, IPT_SO_GET_ENTRIES, &entries, &optlen))
- fail("iptable %s/%d: getsockopt(IPT_SO_GET_ENTRIES)", table->name, family);
+ failmsg("iptable: getsockopt(IPT_SO_GET_ENTRIES) failed",
+ "table=%s, family=%d", table->name, family);
if (memcmp(table->replace.entrytable, entries.entrytable, table->info.size) == 0)
continue;
}
@@ -7569,7 +7568,8 @@ static void reset_iptables(struct ipt_table_desc* tables, int num_tables, int fa
table->replace.counters = counters;
optlen = sizeof(table->replace) - sizeof(table->replace.entrytable) + table->replace.size;
if (setsockopt(fd, level, IPT_SO_SET_REPLACE, &table->replace, optlen))
- fail("iptable %s/%d: setsockopt(IPT_SO_SET_REPLACE)", table->name, family);
+ failmsg("iptable: setsockopt(IPT_SO_SET_REPLACE) failed",
+ "table=%s, family=%d", table->name, family);
}
close(fd);
}
@@ -7583,7 +7583,7 @@ static void checkpoint_arptables(void)
case ENOPROTOOPT:
return;
}
- fail("arptable checkpoint: socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)");
+ fail("arptable checkpoint: socket(AF_INET, SOCK_STREAM, IPPROTO_TCP) failed");
}
for (unsigned i = 0; i < sizeof(arpt_tables) / sizeof(arpt_tables[0]); i++) {
struct arpt_table_desc* table = &arpt_tables[i];
@@ -7597,23 +7597,23 @@ static void checkpoint_arptables(void)
case ENOPROTOOPT:
continue;
}
- fail("arptable checkpoint %s: getsockopt(ARPT_SO_GET_INFO)", table->name);
+ failmsg("arptable checkpoint: getsockopt(ARPT_SO_GET_INFO) failed", "table=%s", table->name);
}
debug("arptable checkpoint %s: entries=%d hooks=%x size=%d\n",
table->name, table->info.num_entries, table->info.valid_hooks, table->info.size);
if (table->info.size > sizeof(table->replace.entrytable))
- fail("arptable checkpoint %s: table size is too large: %u",
- table->name, table->info.size);
+ failmsg("arptable checkpoint: table size is too large",
+ "table=%s, size=%u", table->name, table->info.size);
if (table->info.num_entries > XT_MAX_ENTRIES)
- fail("arptable checkpoint %s: too many counters: %u",
- table->name, table->info.num_entries);
+ failmsg("arptable checkpoint: too many counters",
+ "table=%s, counters=%u", table->name, table->info.num_entries);
struct arpt_get_entries entries;
memset(&entries, 0, sizeof(entries));
strcpy(entries.name, table->name);
entries.size = table->info.size;
optlen = sizeof(entries) - sizeof(entries.entrytable) + table->info.size;
if (getsockopt(fd, SOL_IP, ARPT_SO_GET_ENTRIES, &entries, &optlen))
- fail("arptable checkpoint %s: getsockopt(ARPT_SO_GET_ENTRIES)", table->name);
+ failmsg("arptable checkpoint: getsockopt(ARPT_SO_GET_ENTRIES) failed", "table=%s", table->name);
table->replace.valid_hooks = table->info.valid_hooks;
table->replace.num_entries = table->info.num_entries;
table->replace.size = table->info.size;
@@ -7644,7 +7644,7 @@ static void reset_arptables()
strcpy(info.name, table->name);
socklen_t optlen = sizeof(info);
if (getsockopt(fd, SOL_IP, ARPT_SO_GET_INFO, &info, &optlen))
- fail("arptable %s:getsockopt(ARPT_SO_GET_INFO)", table->name);
+ failmsg("arptable: getsockopt(ARPT_SO_GET_INFO) failed", "table=%s", table->name);
if (memcmp(&table->info, &info, sizeof(table->info)) == 0) {
struct arpt_get_entries entries;
memset(&entries, 0, sizeof(entries));
@@ -7652,7 +7652,7 @@ static void reset_arptables()
entries.size = table->info.size;
optlen = sizeof(entries) - sizeof(entries.entrytable) + entries.size;
if (getsockopt(fd, SOL_IP, ARPT_SO_GET_ENTRIES, &entries, &optlen))
- fail("arptable %s: getsockopt(ARPT_SO_GET_ENTRIES)", table->name);
+ failmsg("arptable: getsockopt(ARPT_SO_GET_ENTRIES) failed", "table=%s", table->name);
if (memcmp(table->replace.entrytable, entries.entrytable, table->info.size) == 0)
continue;
debug("arptable %s: data changed\n", table->name);
@@ -7665,7 +7665,8 @@ static void reset_arptables()
table->replace.counters = counters;
optlen = sizeof(table->replace) - sizeof(table->replace.entrytable) + table->replace.size;
if (setsockopt(fd, SOL_IP, ARPT_SO_SET_REPLACE, &table->replace, optlen))
- fail("arptable %s: setsockopt(ARPT_SO_SET_REPLACE)", table->name);
+ failmsg("arptable: setsockopt(ARPT_SO_SET_REPLACE) failed",
+ "table=%s", table->name);
}
close(fd);
}
@@ -7734,19 +7735,21 @@ static void checkpoint_ebtables(void)
case ENOPROTOOPT:
continue;
}
- fail("ebtable checkpoint %s: getsockopt(EBT_SO_GET_INIT_INFO)", table->name);
+ failmsg("ebtable checkpoint: getsockopt(EBT_SO_GET_INIT_INFO) failed",
+ "table=%s", table->name);
}
debug("ebtable checkpoint %s: entries=%d hooks=%x size=%d\n",
table->name, table->replace.nentries, table->replace.valid_hooks,
table->replace.entries_size);
if (table->replace.entries_size > sizeof(table->entrytable))
- fail("ebtable checkpoint %s: table size is too large: %u",
- table->name, table->replace.entries_size);
+ failmsg("ebtable checkpoint: table size is too large", "table=%s, size=%u",
+ table->name, table->replace.entries_size);
table->replace.num_counters = 0;
table->replace.entries = table->entrytable;
optlen = sizeof(table->replace) + table->replace.entries_size;
if (getsockopt(fd, SOL_IP, EBT_SO_GET_INIT_ENTRIES, &table->replace, &optlen))
- fail("ebtable checkpoint %s: getsockopt(EBT_SO_GET_INIT_ENTRIES)", table->name);
+ failmsg("ebtable checkpoint: getsockopt(EBT_SO_GET_INIT_ENTRIES) failed",
+ "table=%s", table->name);
}
close(fd);
}
@@ -7771,7 +7774,7 @@ static void reset_ebtables()
strcpy(replace.name, table->name);
socklen_t optlen = sizeof(replace);
if (getsockopt(fd, SOL_IP, EBT_SO_GET_INFO, &replace, &optlen))
- fail("ebtable %s: getsockopt(EBT_SO_GET_INFO)", table->name);
+ failmsg("ebtable: getsockopt(EBT_SO_GET_INFO)", "table=%s", table->name);
replace.num_counters = 0;
table->replace.entries = 0;
for (unsigned h = 0; h < NF_BR_NUMHOOKS; h++)
@@ -7782,7 +7785,7 @@ static void reset_ebtables()
replace.entries = entrytable;
optlen = sizeof(replace) + replace.entries_size;
if (getsockopt(fd, SOL_IP, EBT_SO_GET_ENTRIES, &replace, &optlen))
- fail("ebtable %s: getsockopt(EBT_SO_GET_ENTRIES)", table->name);
+ failmsg("ebtable: getsockopt(EBT_SO_GET_ENTRIES) failed", "table=%s", table->name);
if (memcmp(table->entrytable, entrytable, replace.entries_size) == 0)
continue;
}
@@ -7796,7 +7799,7 @@ static void reset_ebtables()
table->replace.entries = table->entrytable;
optlen = sizeof(table->replace) + table->replace.entries_size;
if (setsockopt(fd, SOL_IP, EBT_SO_SET_ENTRIES, &table->replace, optlen))
- fail("ebtable %s: setsockopt(EBT_SO_SET_ENTRIES)", table->name);
+ failmsg("ebtable: setsockopt(EBT_SO_SET_ENTRIES) failed", "table=%s", table->name);
}
close(fd);
}
@@ -8776,7 +8779,7 @@ typedef struct Filter_t {
static void push_back(Filter* filter_array, struct sock_filter filter)
{
if (filter_array->count == kFilterMaxSize)
- fail("can't add another syscall to seccomp filter: count %zu", filter_array->count);
+ failmsg("can't add another syscall to seccomp filter", "count=%zu", filter_array->count);
filter_array->data[filter_array->count++] = filter;
}
@@ -8806,9 +8809,8 @@ static void install_filter(const Filter* f)
(unsigned short)f->count,
(struct sock_filter*)&f->data[0],
};
- if (prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, &prog) < 0) {
- fail("Could not set seccomp filter of size %zu", f->count);
- }
+ if (prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, &prog) < 0)
+ failmsg("could not set seccomp filter", "size=%zu", f->count);
}
static void set_app_seccomp_filter()
{
@@ -8847,61 +8849,49 @@ const char* const SELINUX_XATTR_NAME = "security.selinux";
const gid_t UNTRUSTED_APP_GROUPS[] = {UNTRUSTED_APP_GID, AID_NET_BT_ADMIN, AID_NET_BT, AID_INET, AID_EVERYBODY};
const size_t UNTRUSTED_APP_NUM_GROUPS = sizeof(UNTRUSTED_APP_GROUPS) / sizeof(UNTRUSTED_APP_GROUPS[0]);
-static void syz_getcon(char* context, size_t context_size)
+static void getcon(char* context, size_t context_size)
{
int fd = open(SELINUX_CONTEXT_FILE, O_RDONLY);
-
if (fd < 0)
- fail("getcon: Couldn't open %s", SELINUX_CONTEXT_FILE);
+ fail("getcon: couldn't open context file");
ssize_t nread = read(fd, context, context_size);
close(fd);
if (nread <= 0)
- fail("getcon: Failed to read from %s", SELINUX_CONTEXT_FILE);
+ fail("getcon: failed to read context file");
if (context[nread - 1] == '\n')
context[nread - 1] = '\0';
}
-static void syz_setcon(const char* context)
+static void setcon(const char* context)
{
char new_context[512];
int fd = open(SELINUX_CONTEXT_FILE, O_WRONLY);
if (fd < 0)
- fail("setcon: Could not open %s", SELINUX_CONTEXT_FILE);
+ fail("setcon: could not open context file");
ssize_t bytes_written = write(fd, context, strlen(context));
close(fd);
if (bytes_written != (ssize_t)strlen(context))
- fail("setcon: Could not write entire context. Wrote %zi, expected %zu", bytes_written, strlen(context));
- syz_getcon(new_context, sizeof(new_context));
+ failmsg("setcon: could not write entire context", "wrote=%zi, expected=%zu", bytes_written, strlen(context));
+ getcon(new_context, sizeof(new_context));
if (strcmp(context, new_context) != 0)
- fail("setcon: Failed to change to %s, context is %s", context, new_context);
-}
-static int syz_getfilecon(const char* path, char* context, size_t context_size)
-{
- int length = getxattr(path, SELINUX_XATTR_NAME, context, context_size);
-
- if (length == -1)
- fail("getfilecon: getxattr failed");
-
- return length;
+ failmsg("setcon: failed to change", "want=%s, context=%s", context, new_context);
}
-static void syz_setfilecon(const char* path, const char* context)
+static void setfilecon(const char* path, const char* context)
{
char new_context[512];
if (setxattr(path, SELINUX_XATTR_NAME, context, strlen(context) + 1, 0) != 0)
fail("setfilecon: setxattr failed");
-
- if (syz_getfilecon(path, new_context, sizeof(new_context)) <= 0)
- fail("setfilecon: getfilecon failed");
-
+ if (getxattr(path, SELINUX_XATTR_NAME, new_context, sizeof(new_context)) < 0)
+ fail("setfilecon: getxattr failed");
if (strcmp(context, new_context) != 0)
- fail("setfilecon: could not set context to %s, currently %s", context, new_context);
+ failmsg("setfilecon: could not set context", "want=%s, got=%s", context, new_context);
}
#define SYZ_HAVE_SANDBOX_ANDROID 1
@@ -8928,24 +8918,24 @@ static int do_sandbox_android(void)
#endif
if (chown(".", UNTRUSTED_APP_UID, UNTRUSTED_APP_UID) != 0)
- fail("chmod failed");
+ fail("do_sandbox_android: chmod failed");
if (setgroups(UNTRUSTED_APP_NUM_GROUPS, UNTRUSTED_APP_GROUPS) != 0)
- fail("setgroups failed");
+ fail("do_sandbox_android: setgroups failed");
if (setresgid(UNTRUSTED_APP_GID, UNTRUSTED_APP_GID, UNTRUSTED_APP_GID) != 0)
- fail("setresgid failed");
+ fail("do_sandbox_android: setresgid failed");
#if GOARCH_arm || GOARCH_arm64 || GOARCH_386 || GOARCH_amd64
set_app_seccomp_filter();
#endif
if (setresuid(UNTRUSTED_APP_UID, UNTRUSTED_APP_UID, UNTRUSTED_APP_UID) != 0)
- fail("setresuid failed");
+ fail("do_sandbox_android: setresuid failed");
prctl(PR_SET_PDEATHSIG, SIGKILL, 0, 0, 0);
- syz_setfilecon(".", SELINUX_LABEL_APP_DATA_FILE);
- syz_setcon(SELINUX_CONTEXT_UNTRUSTED_APP);
+ setfilecon(".", SELINUX_LABEL_APP_DATA_FILE);
+ setcon(SELINUX_CONTEXT_UNTRUSTED_APP);
loop();
doexit(1);
@@ -9257,7 +9247,7 @@ static void setup_fault()
if (!write_file(files[i].file, files[i].val)) {
debug("failed to write %s: %d\n", files[i].file, errno);
if (files[i].fatal)
- fail("failed to write %s", files[i].file);
+ failmsg("failed to write fault injection file", "file=%s", files[i].file);
}
}
}
@@ -9275,12 +9265,12 @@ static void setup_fault()
static void setup_leak()
{
if (!write_file(KMEMLEAK_FILE, "scan"))
- fail("failed to write %s", KMEMLEAK_FILE);
+ fail("failed to write(kmemleak, \"scan\")");
sleep(5);
if (!write_file(KMEMLEAK_FILE, "scan"))
- fail("failed to write %s", KMEMLEAK_FILE);
+ fail("failed to write(kmemleak, \"scan\")");
if (!write_file(KMEMLEAK_FILE, "clear"))
- fail("failed to write %s", KMEMLEAK_FILE);
+ fail("failed to write(kmemleak, \"clear\")");
}
#define SYZ_HAVE_LEAK_CHECK 1
@@ -9292,29 +9282,29 @@ static void check_leaks(void)
{
int fd = open(KMEMLEAK_FILE, O_RDWR);
if (fd == -1)
- fail("failed to open(\"%s\")", KMEMLEAK_FILE);
+ fail("failed to open(kmemleak)");
uint64 start = current_time_ms();
if (write(fd, "scan", 4) != 4)
- fail("failed to write(%s, \"scan\")", KMEMLEAK_FILE);
+ fail("failed to write(kmemleak, \"scan\")");
sleep(1);
while (current_time_ms() - start < 4 * 1000)
sleep(1);
if (write(fd, "scan", 4) != 4)
- fail("failed to write(%s, \"scan\")", KMEMLEAK_FILE);
+ fail("failed to write(kmemleak, \"scan\")");
static char buf[128 << 10];
ssize_t n = read(fd, buf, sizeof(buf) - 1);
if (n < 0)
- fail("failed to read(%s)", KMEMLEAK_FILE);
+ fail("failed to read(kmemleak)");
int nleaks = 0;
if (n != 0) {
sleep(1);
if (write(fd, "scan", 4) != 4)
- fail("failed to write(%s, \"scan\")", KMEMLEAK_FILE);
+ fail("failed to write(kmemleak, \"scan\")");
if (lseek(fd, 0, SEEK_SET) < 0)
- fail("failed to lseek(%s)", KMEMLEAK_FILE);
+ fail("failed to lseek(kmemleak)");
n = read(fd, buf, sizeof(buf) - 1);
if (n < 0)
- fail("failed to read(%s)", KMEMLEAK_FILE);
+ fail("failed to read(kmemleak)");
buf[n] = 0;
char* pos = buf;
char* end = buf + n;
@@ -9343,7 +9333,7 @@ static void check_leaks(void)
}
}
if (write(fd, "clear", 5) != 5)
- fail("failed to write(%s, \"clear\")", KMEMLEAK_FILE);
+ fail("failed to write(kmemleak, \"clear\")");
close(fd);
if (nleaks)
doexit(1);
@@ -9380,7 +9370,7 @@ static void setup_kcsan_filterlist(char** frames, int nframes, bool suppress)
{
int fd = open(KCSAN_DEBUGFS_FILE, O_WRONLY);
if (fd == -1)
- fail("failed to open(\"%s\")", KCSAN_DEBUGFS_FILE);
+ fail("failed to open kcsan debugfs file");
printf("%s KCSAN reports in functions: ",
suppress ? "suppressing" : "only showing");
diff --git a/pkg/report/report.go b/pkg/report/report.go
index d46666b66..8d39b2288 100644
--- a/pkg/report/report.go
+++ b/pkg/report/report.go
@@ -645,6 +645,18 @@ var (
// But also catches crashes in Go programs in gvisor/fuchsia.
var commonOopses = []*oops{
{
+ // Errors produced by executor's fail function.
+ []byte("SYZFAIL:"),
+ []oopsFormat{
+ {
+ title: compile("SYZFAIL:(.*)"),
+ fmt: "SYZFAIL:%[1]v",
+ noStackTrace: true,
+ },
+ },
+ []*regexp.Regexp{},
+ },
+ {
[]byte("panic:"),
[]oopsFormat{
{
diff --git a/pkg/report/testdata/linux/report/601 b/pkg/report/testdata/linux/report/601
new file mode 100644
index 000000000..907585130
--- /dev/null
+++ b/pkg/report/testdata/linux/report/601
@@ -0,0 +1,26 @@
+TITLE: SYZFAIL: negative running
+
+2021/02/21 12:37:19 executor 5 failed 11 times:
+executor 5: exit status 67
+running=-1 collide=0 completed=3 flag_threaded=1 flag_collide=1 current=0
+th # 0: created=1 executing=0 colliding=0 ready=0 done=1 call_index=2 res=0 reserrno=14
+th # 1: created=0 executing=0 colliding=0 ready=0 done=0 call_index=0 res=0 reserrno=0
+th # 2: created=0 executing=0 colliding=0 ready=0 done=0 call_index=0 res=0 reserrno=0
+th # 3: created=0 executing=0 colliding=0 ready=0 done=0 call_index=0 res=0 reserrno=0
+th # 4: created=0 executing=0 colliding=0 ready=0 done=0 call_index=0 res=0 reserrno=0
+th # 5: created=0 executing=0 colliding=0 ready=0 done=0 call_index=0 res=0 reserrno=0
+th # 6: created=0 executing=0 colliding=0 ready=0 done=0 call_index=0 res=0 reserrno=0
+th # 7: created=0 executing=0 colliding=0 ready=0 done=0 call_index=0 res=0 reserrno=0
+th # 8: created=0 executing=0 colliding=0 ready=0 done=0 call_index=0 res=0 reserrno=0
+th # 9: created=0 executing=0 colliding=0 ready=0 done=0 call_index=0 res=0 reserrno=0
+th #10: created=0 executing=0 colliding=0 ready=0 done=0 call_index=0 res=0 reserrno=0
+th #11: created=0 executing=0 colliding=0 ready=0 done=0 call_index=0 res=0 reserrno=0
+th #12: created=0 executing=0 colliding=0 ready=0 done=0 call_index=0 res=0 reserrno=0
+th #13: created=0 executing=0 colliding=0 ready=0 done=0 call_index=0 res=0 reserrno=0
+th #14: created=0 executing=0 colliding=0 ready=0 done=0 call_index=0 res=0 reserrno=0
+th #15: created=0 executing=0 colliding=0 ready=0 done=0 call_index=0 res=0 reserrno=0
+ (errno 11: Resource temporarily unavailable)
+SYZFAIL: negative running
+ (errno 0: Success)
+SYZFAIL: child failed
+loop exited with status 67