aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAndy Nguyen <theflow@google.com>2020-08-23 11:51:54 +0200
committerDmitry Vyukov <dvyukov@google.com>2020-08-23 12:31:52 +0200
commit5bde7c3b04ebdee3e83abb0f53ba985ae937e2ea (patch)
treee2ccbc097e082458e43fb59423286001665f6822
parenta6d5f3ad1385fe724cdb2c9ee3b05c7d4ce48ef6 (diff)
executor/common_linux.h: unblock rfkill and retry HCIDEVUP on ERFKILL
-rw-r--r--executor/common_linux.h29
-rw-r--r--pkg/csource/generated.go29
2 files changed, 54 insertions, 4 deletions
diff --git a/executor/common_linux.h b/executor/common_linux.h
index 68be3eeff..410e97bdc 100644
--- a/executor/common_linux.h
+++ b/executor/common_linux.h
@@ -1981,6 +1981,7 @@ static long syz_init_net_socket(volatile long domain, volatile long type, volati
#if SYZ_EXECUTOR || SYZ_VHCI_INJECTION
#include <errno.h>
#include <fcntl.h>
+#include <linux/rfkill.h>
#include <pthread.h>
#include <sys/epoll.h>
#include <sys/ioctl.h>
@@ -2089,6 +2090,22 @@ struct vhci_vendor_pkt {
static int vhci_fd = -1;
+void rfkill_unblock_all()
+{
+ int fd = open("/dev/rfkill", O_WRONLY);
+ if (fd < 0)
+ fail("open /dev/rfkill failed");
+ struct rfkill_event event = {0};
+ event.idx = 0;
+ event.type = RFKILL_TYPE_ALL;
+ event.op = RFKILL_OP_CHANGE_ALL;
+ event.soft = 0;
+ event.hard = 0;
+ if (write(fd, &event, sizeof(event)) < 0)
+ fail("write rfkill event failed\n");
+ close(fd);
+}
+
static void hci_send_event_packet(int fd, uint8 evt, void* data, size_t data_len)
{
struct iovec iv[3];
@@ -2232,8 +2249,16 @@ static void initialize_vhci()
fail("pthread_create failed");
// Bring hci device up
- if (ioctl(hci_sock, HCIDEVUP, vendor_pkt.id) && errno != EALREADY)
- fail("ioctl(HCIDEVUP) failed");
+ int ret = ioctl(hci_sock, HCIDEVUP, vendor_pkt.id);
+ if (ret) {
+ if (errno == ERFKILL) {
+ rfkill_unblock_all();
+ ret = ioctl(hci_sock, HCIDEVUP, vendor_pkt.id);
+ }
+
+ if (ret && errno != EALREADY)
+ fail("ioctl(HCIDEVUP) failed");
+ }
// Activate page scanning mode which is required to fake a connection.
struct hci_dev_req dr = {0};
diff --git a/pkg/csource/generated.go b/pkg/csource/generated.go
index 867cfa183..334cbe167 100644
--- a/pkg/csource/generated.go
+++ b/pkg/csource/generated.go
@@ -5377,6 +5377,7 @@ static long syz_init_net_socket(volatile long domain, volatile long type, volati
#if SYZ_EXECUTOR || SYZ_VHCI_INJECTION
#include <errno.h>
#include <fcntl.h>
+#include <linux/rfkill.h>
#include <pthread.h>
#include <sys/epoll.h>
#include <sys/ioctl.h>
@@ -5485,6 +5486,22 @@ struct vhci_vendor_pkt {
static int vhci_fd = -1;
+void rfkill_unblock_all()
+{
+ int fd = open("/dev/rfkill", O_WRONLY);
+ if (fd < 0)
+ fail("open /dev/rfkill failed");
+ struct rfkill_event event = {0};
+ event.idx = 0;
+ event.type = RFKILL_TYPE_ALL;
+ event.op = RFKILL_OP_CHANGE_ALL;
+ event.soft = 0;
+ event.hard = 0;
+ if (write(fd, &event, sizeof(event)) < 0)
+ fail("write rfkill event failed\n");
+ close(fd);
+}
+
static void hci_send_event_packet(int fd, uint8 evt, void* data, size_t data_len)
{
struct iovec iv[3];
@@ -5621,8 +5638,16 @@ static void initialize_vhci()
pthread_t th;
if (pthread_create(&th, NULL, event_thread, NULL))
fail("pthread_create failed");
- if (ioctl(hci_sock, HCIDEVUP, vendor_pkt.id) && errno != EALREADY)
- fail("ioctl(HCIDEVUP) failed");
+ int ret = ioctl(hci_sock, HCIDEVUP, vendor_pkt.id);
+ if (ret) {
+ if (errno == ERFKILL) {
+ rfkill_unblock_all();
+ ret = ioctl(hci_sock, HCIDEVUP, vendor_pkt.id);
+ }
+
+ if (ret && errno != EALREADY)
+ fail("ioctl(HCIDEVUP) failed");
+ }
struct hci_dev_req dr = {0};
dr.dev_id = vendor_pkt.id;
dr.dev_opt = SCAN_PAGE;