1. 16 Jan, 2019 1 commit
  2. 12 Jan, 2019 3 commits
    • Taehee Yoo's avatar
      net: bpfilter: disallow to remove bpfilter module while being used · 71a85084
      Taehee Yoo authored
      The bpfilter.ko module can be removed while functions of the bpfilter.ko
      are executing. so panic can occurred. in order to protect that, locks can
      be used. a bpfilter_lock protects routines in the
      __bpfilter_process_sockopt() but it's not enough because __exit routine
      can be executed concurrently.
      
      Now, the bpfilter_umh can not run in parallel.
      So, the module do not removed while it's being used and it do not
      double-create UMH process.
      The members of the umh_info and the bpfilter_umh_ops are protected by
      the bpfilter_umh_ops.lock.
      
      test commands:
         while :
         do
      	iptables -I FORWARD -m string --string ap --algo kmp &
      	modprobe -rv bpfilter &
         done
      
      splat looks like:
      [  298.623435] BUG: unable to handle kernel paging request at fffffbfff807440b
      [  298.628512] #PF error: [normal kernel read fault]
      [  298.633018] PGD 124327067 P4D 124327067 PUD 11c1a3067 PMD 119eb2067 PTE 0
      [  298.638859] Oops: 0000 [#1] SMP DEBUG_PAGEALLOC KASAN PTI
      [  298.638859] CPU: 0 PID: 2997 Comm: iptables Not tainted 4.20.0+ #154
      [  298.638859] RIP: 0010:__mutex_lock+0x6b9/0x16a0
      [  298.638859] Code: c0 00 00 e8 89 82 ff ff 80 bd 8f fc ff ff 00 0f 85 d9 05 00 00 48 8b 85 80 fc ff ff 48 bf 00 00 00 00 00 fc ff df 48 c1 e8 03 <80> 3c 38 00 0f 85 1d 0e 00 00 48 8b 85 c8 fc ff ff 49 39 47 58 c6
      [  298.638859] RSP: 0018:ffff88810e7777a0 EFLAGS: 00010202
      [  298.638859] RAX: 1ffffffff807440b RBX: ffff888111bd4d80 RCX: 0000000000000000
      [  298.638859] RDX: 1ffff110235ff806 RSI: ffff888111bd5538 RDI: dffffc0000000000
      [  298.638859] RBP: ffff88810e777b30 R08: 0000000080000002 R09: 0000000000000000
      [  298.638859] R10: 0000000000000000 R11: 0000000000000000 R12: fffffbfff168a42c
      [  298.638859] R13: ffff888111bd4d80 R14: ffff8881040e9a05 R15: ffffffffc03a2000
      [  298.638859] FS:  00007f39e3758700(0000) GS:ffff88811ae00000(0000) knlGS:0000000000000000
      [  298.638859] CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080050033
      [  298.638859] CR2: fffffbfff807440b CR3: 000000011243e000 CR4: 00000000001006f0
      [  298.638859] Call Trace:
      [  298.638859]  ? mutex_lock_io_nested+0x1560/0x1560
      [  298.638859]  ? kasan_kmalloc+0xa0/0xd0
      [  298.638859]  ? kmem_cache_alloc+0x1c2/0x260
      [  298.638859]  ? __alloc_file+0x92/0x3c0
      [  298.638859]  ? alloc_empty_file+0x43/0x120
      [  298.638859]  ? alloc_file_pseudo+0x220/0x330
      [  298.638859]  ? sock_alloc_file+0x39/0x160
      [  298.638859]  ? __sys_socket+0x113/0x1d0
      [  298.638859]  ? __x64_sys_socket+0x6f/0xb0
      [  298.638859]  ? do_syscall_64+0x138/0x560
      [  298.638859]  ? entry_SYSCALL_64_after_hwframe+0x49/0xbe
      [  298.638859]  ? __alloc_file+0x92/0x3c0
      [  298.638859]  ? init_object+0x6b/0x80
      [  298.638859]  ? cyc2ns_read_end+0x10/0x10
      [  298.638859]  ? cyc2ns_read_end+0x10/0x10
      [  298.638859]  ? hlock_class+0x140/0x140
      [  298.638859]  ? sched_clock_local+0xd4/0x140
      [  298.638859]  ? sched_clock_local+0xd4/0x140
      [  298.638859]  ? check_flags.part.37+0x440/0x440
      [  298.638859]  ? __lock_acquire+0x4f90/0x4f90
      [  298.638859]  ? set_rq_offline.part.89+0x140/0x140
      [ ... ]
      
      Fixes: d2ba09c1 ("net: add skeleton of bpfilter kernel module")
      Signed-off-by: default avatarTaehee Yoo <ap420073@gmail.com>
      Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
      71a85084
    • Taehee Yoo's avatar
      net: bpfilter: restart bpfilter_umh when error occurred · 61fbf593
      Taehee Yoo authored
      The bpfilter_umh will be stopped via __stop_umh() when the bpfilter
      error occurred.
      The bpfilter_umh() couldn't start again because there is no restart
      routine.
      
      The section of the bpfilter_umh_{start/end} is no longer .init.rodata
      because these area should be reused in the restart routine. hence
      the section name is changed to .bpfilter_umh.
      
      The bpfilter_ops->start() is restart callback. it will be called when
      bpfilter_umh is stopped.
      The stop bit means bpfilter_umh is stopped. this bit is set by both
      start and stop routine.
      
      Before this patch,
      Test commands:
         $ iptables -vnL
         $ kill -9 <pid of bpfilter_umh>
         $ iptables -vnL
         [  480.045136] bpfilter: write fail -32
         $ iptables -vnL
      
      All iptables commands will fail.
      
      After this patch,
      Test commands:
         $ iptables -vnL
         $ kill -9 <pid of bpfilter_umh>
         $ iptables -vnL
         $ iptables -vnL
      
      Now, all iptables commands will work.
      
      Fixes: d2ba09c1 ("net: add skeleton of bpfilter kernel module")
      Signed-off-by: default avatarTaehee Yoo <ap420073@gmail.com>
      Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
      61fbf593
    • Taehee Yoo's avatar
      net: bpfilter: use cleanup callback to release umh_info · 5b4cb650
      Taehee Yoo authored
      Now, UMH process is killed, do_exit() calls the umh_info->cleanup callback
      to release members of the umh_info.
      This patch makes bpfilter_umh's cleanup routine to use the
      umh_info->cleanup callback.
      Signed-off-by: default avatarTaehee Yoo <ap420073@gmail.com>
      Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
      5b4cb650
  3. 23 Oct, 2018 1 commit
  4. 18 Oct, 2018 1 commit
    • Taehee Yoo's avatar
      net: bpfilter: use get_pid_task instead of pid_task · 84258438
      Taehee Yoo authored
      pid_task() dereferences rcu protected tasks array.
      But there is no rcu_read_lock() in shutdown_umh() routine so that
      rcu_read_lock() is needed.
      get_pid_task() is wrapper function of pid_task. it holds rcu_read_lock()
      then calls pid_task(). if task isn't NULL, it increases reference count
      of task.
      
      test commands:
         %modprobe bpfilter
         %modprobe -rv bpfilter
      
      splat looks like:
      [15102.030932] =============================
      [15102.030957] WARNING: suspicious RCU usage
      [15102.030985] 4.19.0-rc7+ #21 Not tainted
      [15102.031010] -----------------------------
      [15102.031038] kernel/pid.c:330 suspicious rcu_dereference_check() usage!
      [15102.031063]
      	       other info that might help us debug this:
      
      [15102.031332]
      	       rcu_scheduler_active = 2, debug_locks = 1
      [15102.031363] 1 lock held by modprobe/1570:
      [15102.031389]  #0: 00000000580ef2b0 (bpfilter_lock){+.+.}, at: stop_umh+0x13/0x52 [bpfilter]
      [15102.031552]
                     stack backtrace:
      [15102.031583] CPU: 1 PID: 1570 Comm: modprobe Not tainted 4.19.0-rc7+ #21
      [15102.031607] Hardware name: To be filled by O.E.M. To be filled by O.E.M./Aptio CRB, BIOS 5.6.5 07/08/2015
      [15102.031628] Call Trace:
      [15102.031676]  dump_stack+0xc9/0x16b
      [15102.031723]  ? show_regs_print_info+0x5/0x5
      [15102.031801]  ? lockdep_rcu_suspicious+0x117/0x160
      [15102.031855]  pid_task+0x134/0x160
      [15102.031900]  ? find_vpid+0xf0/0xf0
      [15102.032017]  shutdown_umh.constprop.1+0x1e/0x53 [bpfilter]
      [15102.032055]  stop_umh+0x46/0x52 [bpfilter]
      [15102.032092]  __x64_sys_delete_module+0x47e/0x570
      [ ... ]
      
      Fixes: d2ba09c1 ("net: add skeleton of bpfilter kernel module")
      Signed-off-by: default avatarTaehee Yoo <ap420073@gmail.com>
      Acked-by: default avatarAlexei Starovoitov <ast@kernel.org>
      Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
      84258438
  5. 05 Oct, 2018 1 commit
  6. 24 Jul, 2018 1 commit
  7. 17 Jul, 2018 2 commits
  8. 28 Jun, 2018 2 commits
  9. 21 Jun, 2018 1 commit
  10. 20 Jun, 2018 2 commits
  11. 08 Jun, 2018 1 commit
    • Alexei Starovoitov's avatar
      bpfilter: fix race in pipe access · 66e58e0e
      Alexei Starovoitov authored
      syzbot reported the following crash
      [  338.293946] bpfilter: read fail -512
      [  338.304515] kasan: GPF could be caused by NULL-ptr deref or user memory access
      [  338.311863] general protection fault: 0000 [#1] SMP KASAN
      [  338.344360] RIP: 0010:__vfs_write+0x4a6/0x960
      [  338.426363] Call Trace:
      [  338.456967]  __kernel_write+0x10c/0x380
      [  338.460928]  __bpfilter_process_sockopt+0x1d8/0x35b
      [  338.487103]  bpfilter_mbox_request+0x4d/0xb0
      [  338.491492]  bpfilter_ip_get_sockopt+0x6b/0x90
      
      This can happen when multiple cpus trying to talk to user mode process
      via bpfilter_mbox_request(). One cpu grabs the mutex while another goes to
      sleep on the same mutex. Then former cpu sees that umh pipe is down and
      shuts down the pipes. Later cpu finally acquires the mutex and crashes
      on freed pipe.
      Fix the race by using info.pid as an indicator that umh and pipes are healthy
      and check it after acquiring the mutex.
      
      Fixes: d2ba09c1 ("net: add skeleton of bpfilter kernel module")
      Reported-by: syzbot+7ade6c94abb2774c0fee@syzkaller.appspotmail.com
      Signed-off-by: default avatarAlexei Starovoitov <ast@kernel.org>
      Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
      66e58e0e
  12. 07 Jun, 2018 1 commit
  13. 05 Jun, 2018 1 commit
  14. 29 May, 2018 2 commits
    • YueHaibing's avatar
      bpfilter: fix a build err · ae40832e
      YueHaibing authored
      gcc-7.3.0 report following err:
      
        HOSTCC  net/bpfilter/main.o
      In file included from net/bpfilter/main.c:9:0:
      ./include/uapi/linux/bpf.h:12:10: fatal error: linux/bpf_common.h: No such file or directory
       #include <linux/bpf_common.h>
      
      remove it by adding a include path.
      Fixes: d2ba09c1 ("net: add skeleton of bpfilter kernel module")
      Signed-off-by: default avatarYueHaibing <yuehaibing@huawei.com>
      Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
      ae40832e
    • Arnd Bergmann's avatar
      bpfilter: fix building without CONFIG_INET · d71dbdaa
      Arnd Bergmann authored
      bpfilter_process_sockopt is a callback that gets called from
      ip_setsockopt() and ip_getsockopt(). However, when CONFIG_INET is
      disabled, it never gets called at all, and assigning a function to the
      callback pointer results in a link failure:
      
      net/bpfilter/bpfilter_kern.o: In function `__stop_umh':
      bpfilter_kern.c:(.text.unlikely+0x3): undefined reference to `bpfilter_process_sockopt'
      net/bpfilter/bpfilter_kern.o: In function `load_umh':
      bpfilter_kern.c:(.init.text+0x73): undefined reference to `bpfilter_process_sockopt'
      
      Since there is no caller in this configuration, I assume we can
      simply make the assignment conditional.
      Signed-off-by: default avatarArnd Bergmann <arnd@arndb.de>
      Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
      d71dbdaa
  15. 24 May, 2018 2 commits
  16. 23 May, 2018 1 commit
    • 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