Author: markj
Date: Fri Sep  4 00:12:28 2020
New Revision: 365319
URL: https://svnweb.freebsd.org/changeset/base/365319

Log:
  Add emulation support for the Linux kcov(4) ioctl API.
  
  This makes it possible to run an unmodified Linux syzkaller executor
  against the Linuxulator, and have it gather code coverage information.
  
  Sponsored by: The FreeBSD Foundation

Modified:
  head/sys/compat/lindebugfs/lindebugfs.c
  head/sys/compat/linsysfs/linsysfs.c
  head/sys/compat/linux/linux_ioctl.c
  head/sys/compat/linux/linux_ioctl.h

Modified: head/sys/compat/lindebugfs/lindebugfs.c
==============================================================================
--- head/sys/compat/lindebugfs/lindebugfs.c     Fri Sep  4 00:11:01 2020        
(r365318)
+++ head/sys/compat/lindebugfs/lindebugfs.c     Fri Sep  4 00:12:28 2020        
(r365319)
@@ -299,6 +299,9 @@ debugfs_init(PFS_INIT_ARGS)
 {
 
        debugfs_root = pi->pi_root;
+
+       (void)debugfs_create_symlink("kcov", NULL, "/dev/kcov");
+
        return (0);
 }
 

Modified: head/sys/compat/linsysfs/linsysfs.c
==============================================================================
--- head/sys/compat/linsysfs/linsysfs.c Fri Sep  4 00:11:01 2020        
(r365318)
+++ head/sys/compat/linsysfs/linsysfs.c Fri Sep  4 00:12:28 2020        
(r365319)
@@ -624,6 +624,8 @@ linsysfs_init(PFS_INIT_ARGS)
        struct pfs_node *net;
        struct pfs_node *power_supply;
        struct pfs_node *devdir, *chardev;
+       struct pfs_node *kernel;
+       struct pfs_node *debug;
        devclass_t devclass;
        device_t dev;
 
@@ -671,6 +673,11 @@ linsysfs_init(PFS_INIT_ARGS)
 
        linsysfs_listcpus(cpu);
        linsysfs_listnics(net);
+
+       /* /sys/kernel */
+       kernel = pfs_create_dir(root, "kernel", NULL, NULL, NULL, 0);
+       /* /sys/kernel/debug, mountpoint for lindebugfs. */
+       debug = pfs_create_dir(kernel, "debug", NULL, NULL, NULL, 0);
 
        return (0);
 }

Modified: head/sys/compat/linux/linux_ioctl.c
==============================================================================
--- head/sys/compat/linux/linux_ioctl.c Fri Sep  4 00:11:01 2020        
(r365318)
+++ head/sys/compat/linux/linux_ioctl.c Fri Sep  4 00:12:28 2020        
(r365319)
@@ -50,6 +50,7 @@ __FBSDID("$FreeBSD$");
 #include <sys/filio.h>
 #include <sys/jail.h>
 #include <sys/kbio.h>
+#include <sys/kcov.h>
 #include <sys/kernel.h>
 #include <sys/linker_set.h>
 #include <sys/lock.h>
@@ -117,6 +118,7 @@ static linux_ioctl_function_t linux_ioctl_v4l2;
 static linux_ioctl_function_t linux_ioctl_special;
 static linux_ioctl_function_t linux_ioctl_fbsd_usb;
 static linux_ioctl_function_t linux_ioctl_evdev;
+static linux_ioctl_function_t linux_ioctl_kcov;
 
 static struct linux_ioctl_handler cdrom_handler =
 { linux_ioctl_cdrom, LINUX_IOCTL_CDROM_MIN, LINUX_IOCTL_CDROM_MAX };
@@ -146,6 +148,8 @@ static struct linux_ioctl_handler fbsd_usb =
 { linux_ioctl_fbsd_usb, FBSD_LUSB_MIN, FBSD_LUSB_MAX };
 static struct linux_ioctl_handler evdev_handler =
 { linux_ioctl_evdev, LINUX_IOCTL_EVDEV_MIN, LINUX_IOCTL_EVDEV_MAX };
+static struct linux_ioctl_handler kcov_handler =
+{ linux_ioctl_kcov, LINUX_KCOV_MIN, LINUX_KCOV_MAX };
 
 DATA_SET(linux_ioctl_handler_set, cdrom_handler);
 DATA_SET(linux_ioctl_handler_set, vfat_handler);
@@ -161,6 +165,7 @@ DATA_SET(linux_ioctl_handler_set, video_handler);
 DATA_SET(linux_ioctl_handler_set, video2_handler);
 DATA_SET(linux_ioctl_handler_set, fbsd_usb);
 DATA_SET(linux_ioctl_handler_set, evdev_handler);
+DATA_SET(linux_ioctl_handler_set, kcov_handler);
 
 /*
  * Keep sorted by low.
@@ -3570,6 +3575,38 @@ linux_ioctl_evdev(struct thread *td, struct linux_ioct
                args->cmd = (args->cmd & ~IOC_DIRMASK) | IOC_INOUT;
 
        return (sys_ioctl(td, (struct ioctl_args *)args));
+}
+
+static int
+linux_ioctl_kcov(struct thread *td, struct linux_ioctl_args *args)
+{
+       int error;
+
+       error = 0;
+       switch (args->cmd & 0xffff) {
+       case LINUX_KCOV_INIT_TRACE:
+               args->cmd = KIOSETBUFSIZE;
+               break;
+       case LINUX_KCOV_ENABLE:
+               args->cmd = KIOENABLE;
+               if (args->arg == 0)
+                       args->arg = KCOV_MODE_TRACE_PC;
+               else if (args->arg == 1)
+                       args->arg = KCOV_MODE_TRACE_CMP;
+               else
+                       error = EINVAL;
+               break;
+       case LINUX_KCOV_DISABLE:
+               args->cmd = KIODISABLE;
+               break;
+       default:
+               error = ENOTTY;
+               break;
+       }
+
+       if (error == 0)
+               error = sys_ioctl(td, (struct ioctl_args *)args);
+       return (error);
 }
 
 /*

Modified: head/sys/compat/linux/linux_ioctl.h
==============================================================================
--- head/sys/compat/linux/linux_ioctl.h Fri Sep  4 00:11:01 2020        
(r365318)
+++ head/sys/compat/linux/linux_ioctl.h Fri Sep  4 00:12:28 2020        
(r365319)
@@ -762,6 +762,17 @@
 #define LINUX_IOCTL_EVDEV_MAX          0x45ff
 #define LINUX_IOCTL_EVDEV_CLK          LINUX_CLOCK_REALTIME |  \
            LINUX_CLOCK_MONOTONIC |LINUX_CLOCK_BOOTTIME
+
+/*
+ * kcov(4) shims
+ */
+#define        LINUX_KCOV_MIN                  0x6300
+#define        LINUX_KCOV_MAX                  0x63ff
+#define        LINUX_KCOV_INIT_TRACE           0x6301
+#define        LINUX_KCOV_ENABLE               0x6364
+#define        LINUX_KCOV_DISABLE              0x6365
+#define        LINUX_KCOV_REMOTE_ENABLE        0x6366
+
 /*
  * Pluggable ioctl handlers
  */
_______________________________________________
svn-src-head@freebsd.org mailing list
https://lists.freebsd.org/mailman/listinfo/svn-src-head
To unsubscribe, send any mail to "svn-src-head-unsubscr...@freebsd.org"

Reply via email to