aboutsummaryrefslogtreecommitdiffstats
path: root/executor/common_linux.h
diff options
context:
space:
mode:
authorFlorent Revest <revest@chromium.org>2026-02-20 14:01:26 +0100
committerFlorent Revest <revest@chromium.org>2026-02-26 08:54:32 +0000
commitcd152ea2d27f130f30f3d744e27dc398a8c463ee (patch)
tree675fa8b0e6760e466bb5c29307c655f271dbf6a9 /executor/common_linux.h
parente0f78d931aa9b1bb82117a1bd31e0583aef94708 (diff)
executor: fix up /dev/net/tun before opening it
We get various reports like: "SYZFAIL: tun: can't open /dev/net/tun": https://syzkaller.appspot.com/bug?extid=17b76f12c4893fc7b67b or like "SYZFAIL: tun: ioctl(TUNSETIFF) failed" https://syzkaller.appspot.com/bug?extid=49461b4cd5aa62f553fc Which look a lot like syzkaller manages to delete or replace /dev/net/tun and from there on consistently fail to open the device and complains with these SYZFAIL. This is an attempt to fix up the /dev/net/tun before we open it so we know we try to open the right file.
Diffstat (limited to 'executor/common_linux.h')
-rw-r--r--executor/common_linux.h25
1 files changed, 25 insertions, 0 deletions
diff --git a/executor/common_linux.h b/executor/common_linux.h
index 7c4fd9b68..c1368f292 100644
--- a/executor/common_linux.h
+++ b/executor/common_linux.h
@@ -639,6 +639,7 @@ static struct nlmsg nlmsg;
#include <stdbool.h>
#include <sys/ioctl.h>
#include <sys/stat.h>
+#include <sys/sysmacros.h>
#include <linux/if_ether.h>
#include <linux/if_tun.h>
@@ -665,12 +666,36 @@ static int tun_frags_enabled;
#endif
#endif
+// Sometimes, executors like to delete or replace /dev/net/tun and this causes
+// all further executors to fail. Let's make sure it's the right char device.
+static void correct_dev_net_tun(void)
+{
+ struct stat st;
+ if (stat("/dev/net/tun", &st) == 0) {
+ if (S_ISCHR(st.st_mode) && major(st.st_rdev) == 10 && minor(st.st_rdev) == 200)
+ return;
+ if (unlink("/dev/net/tun")) {
+ debug("tun: unlink(/dev/net/tun) failed: %d\n", errno);
+ }
+ }
+ if (mkdir("/dev/net", 0755) && errno != EEXIST) {
+ debug("tun: mkdir(/dev/net) failed: %d\n", errno);
+ }
+ if (mknod("/dev/net/tun", S_IFCHR | 0666, makedev(10, 200))) {
+ debug("tun: mknod(/dev/net/tun) failed: %d\n", errno);
+ }
+ if (chmod("/dev/net/tun", 0666)) {
+ debug("tun: chmod(/dev/net/tun) failed: %d\n", errno);
+ }
+}
+
static void initialize_tun(void)
{
#if SYZ_EXECUTOR
if (!flag_net_injection)
return;
#endif
+ correct_dev_net_tun();
tunfd = open("/dev/net/tun", O_RDWR | O_NONBLOCK);
if (tunfd == -1) {
#if SYZ_EXECUTOR