tap: reference to KVA of an unloaded module causes kernel panic

Linux Kernel / Linux Kernel - Girish Moodalbail [oracle.com] - 28 October 2017 10:17 EDT

The commit 9a393b5d5988 ("tap: tap as an independent module") created a separate tap module that implements tap functionality and exports interfaces that will be used by macvtap and ipvtap modules to create create respective tap devices.

However, that patch introduced a regression wherein the modules macvtap and ipvtap can be removed (through modprobe -r) while there are applications using the respective /dev/tapX devices. These applications cause kernel to hold reference to /dev/tapX through 'struct cdev macvtap_cdev' and 'struct cdev ipvtap_dev' defined in macvtap and ipvtap modules respectively. So, when the application is later closed the kernel panics because we are referencing KVA that is present in the unloaded modules.

----------8<------- Example ----------8<----------$ sudo ip li add name mv0 link enp7s0 type macvtap $ sudo ip li show mv0 |grep mv0| awk -e '{print $1 $2}' 14:mv0@enp7s0: $ cat /dev/tap14 & $ lsmod |egrep -i 'tap|vlan' macvtap 16384 0 macvlan 24576 1 macvtap tap 24576 3 macvtap $ sudo modprobe -r macvtap $ fg cat /dev/tap14 ^C

<...system panics...> BUG: unable to handle kernel paging request at ffffffffa038c500 IP: cdev_put+0xf/0x30----------8<-----------------8<----------

The fix is to set cdev.owner to the module that creates the tap device (either macvtap or ipvtap). With this set, the operations (in fs/char_dev.c) on char device holds and releases the module through cdev_get() and cdev_put() and will not allow the module to unload prematurely.

Fixes: 9a393b5d5988ea4e (tap: tap as an independent module)

dea6e19f4ef7 tap: reference to KVA of an unloaded module causes kernel panic
drivers/net/ipvlan/ipvtap.c | 4 ++--
drivers/net/macvtap.c | 4 ++--
drivers/net/tap.c | 5 +++--
include/linux/if_tap.h | 4 ++--
4 files changed, 9 insertions(+), 8 deletions(-)

Upstream: git.kernel.org

  • Share