Skip to content
  1. May 24, 2018
    • Alexei Starovoitov's avatar
      net: add skeleton of bpfilter kernel module · d2ba09c1
      Alexei Starovoitov authored
      
      
      bpfilter.ko consists of bpfilter_kern.c (normal kernel module code)
      and user mode helper code that is embedded into bpfilter.ko
      
      The steps to build bpfilter.ko are the following:
      - main.c is compiled by HOSTCC into the bpfilter_umh elf executable file
      - with quite a bit of objcopy and Makefile magic the bpfilter_umh elf file
        is converted into bpfilter_umh.o object file
        with _binary_net_bpfilter_bpfilter_umh_start and _end symbols
        Example:
        $ nm ./bld_x64/net/bpfilter/bpfilter_umh.o
        0000000000004cf8 T _binary_net_bpfilter_bpfilter_umh_end
        0000000000004cf8 A _binary_net_bpfilter_bpfilter_umh_size
        0000000000000000 T _binary_net_bpfilter_bpfilter_umh_start
      - bpfilter_umh.o and bpfilter_kern.o are linked together into bpfilter.ko
      
      bpfilter_kern.c is a normal kernel module code that calls
      the fork_usermode_blob() helper to execute part of its own data
      as a user mode process.
      
      Notice that _binary_net_bpfilter_bpfilter_umh_start - end
      is placed into .init.rodata section, so it's freed as soon as __init
      function of bpfilter.ko is finished.
      As part of __init the bpfilter.ko does first request/reply action
      via two unix pipe provided by fork_usermode_blob() helper to
      make sure that umh is healthy. If not it will kill it via pid.
      
      Later bpfilter_process_sockopt() will be called from bpfilter hooks
      in get/setsockopt() to pass iptable commands into umh via bpfilter.ko
      
      If admin does 'rmmod bpfilter' the __exit code bpfilter.ko will
      kill umh as well.
      
      Signed-off-by: default avatarAlexei Starovoitov <ast@kernel.org>
      Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
      d2ba09c1
    • Alexei Starovoitov's avatar
      umh: introduce fork_usermode_blob() helper · 449325b5
      Alexei Starovoitov authored
      
      
      Introduce helper:
      int fork_usermode_blob(void *data, size_t len, struct umh_info *info);
      struct umh_info {
             struct file *pipe_to_umh;
             struct file *pipe_from_umh;
             pid_t pid;
      };
      
      that GPLed kernel modules (signed or unsigned) can use it to execute part
      of its own data as swappable user mode process.
      
      The kernel will do:
      - allocate a unique file in tmpfs
      - populate that file with [data, data + len] bytes
      - user-mode-helper code will do_execve that file and, before the process
        starts, the kernel will create two unix pipes for bidirectional
        communication between kernel module and umh
      - close tmpfs file, effectively deleting it
      - the fork_usermode_blob will return zero on success and populate
        'struct umh_info' with two unix pipes and the pid of the user process
      
      As the first step in the development of the bpfilter project
      the fork_usermode_blob() helper is introduced to allow user mode code
      to be invoked from a kernel module. The idea is that user mode code plus
      normal kernel module code are built as part of the kernel build
      and installed as traditional kernel module into distro specified location,
      such that from a distribution point of view, there is
      no difference between regular kernel modules and kernel modules + umh code.
      Such modules can be signed, modprobed, rmmod, etc. The use of this new helper
      by a kernel module doesn't make it any special from kernel and user space
      tooling point of view.
      
      Such approach enables kernel to delegate functionality traditionally done
      by the kernel modules into the user space processes (either root or !root) and
      reduces security attack surface of the new code. The buggy umh code would crash
      the user process, but not the kernel. Another advantage is that umh code
      of the kernel module can be debugged and tested out of user space
      (e.g. opening the possibility to run clang sanitizers, fuzzers or
      user space test suites on the umh code).
      In case of the bpfilter project such architecture allows complex control plane
      to be done in the user space while bpf based data plane stays in the kernel.
      
      Since umh can crash, can be oom-ed by the kernel, killed by the admin,
      the kernel module that uses them (like bpfilter) needs to manage life
      time of umh on its own via two unix pipes and the pid of umh.
      
      The exit code of such kernel module should kill the umh it started,
      so that rmmod of the kernel module will cleanup the corresponding umh.
      Just like if the kernel module does kmalloc() it should kfree() it
      in the exit code.
      
      Signed-off-by: default avatarAlexei Starovoitov <ast@kernel.org>
      Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
      449325b5
  2. May 23, 2018
  3. May 22, 2018