• Davide Caratti's avatar
    net/sched: prepare TC actions to properly validate the control action · 85d0966f
    Davide Caratti authored
    - pass a pointer to struct tcf_proto in each actions's init() handler,
      to allow validating the control action, checking whether the chain
      exists and (eventually) refcounting it.
    - remove code that validates the control action after a successful call
      to the action's init() handler, and replace it with a test that forbids
      addition of actions having 'goto_chain' and NULL goto_chain pointer at
      the same time.
    - add tcf_action_check_ctrlact(), that will validate the control action
      and eventually allocate the action 'goto_chain' within the init()
      handler.
    - add tcf_action_set_ctrlact(), that will assign the control action and
      swap the current 'goto_chain' pointer with the new given one.
    
    This disallows 'goto_chain' on actions that don't initialize it properly
    in their init() handler, i.e. calling tcf_action_check_ctrlact() after
    successful IDR reservation and then calling tcf_action_set_ctrlact()
    to assign 'goto_chain' and 'tcf_action' consistently.
    
    By doing this, the kernel does not leak anymore refcounts when a valid
    'goto chain' handle is replaced in TC actions, causing kmemleak splats
    like the following one:
    
     # tc chain add dev dd0 chain 42 ingress protocol ip flower \
     > ip_proto tcp action drop
     # tc chain add dev dd0 chain 43 ingress protocol ip flower \
     > ip_proto udp action drop
     # tc filter add dev dd0 ingress matchall \
     > action gact goto chain 42 index 66
     # tc filter replace dev dd0 ingress matchall \
     > action gact goto chain 43 index 66
     # echo scan >/sys/kernel/debug/kmemleak
     <...>
     unreferenced object 0xffff93c0ee09f000 (size 1024):
     comm "tc", pid 2565, jiffies 4295339808 (age 65.426s)
     hex dump (first 32 bytes):
       00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
       00 00 00 00 08 00 06 00 00 00 00 00 00 00 00 00  ................
     backtrace:
       [<000000009b63f92d>] tc_ctl_chain+0x3d2/0x4c0
       [<00000000683a8d72>] rtnetlink_rcv_msg+0x263/0x2d0
       [<00000000ddd88f8e>] netlink_rcv_skb+0x4a/0x110
       [<000000006126a348>] netlink_unicast+0x1a0/0x250
       [<00000000b3340877>] netlink_sendmsg+0x2c1/0x3c0
       [<00000000a25a2171>] sock_sendmsg+0x36/0x40
       [<00000000f19ee1ec>] ___sys_sendmsg+0x280/0x2f0
       [<00000000d0422042>] __sys_sendmsg+0x5e/0xa0
       [<000000007a6c61f9>] do_syscall_64+0x5b/0x180
       [<00000000ccd07542>] entry_SYSCALL_64_after_hwframe+0x44/0xa9
       [<0000000013eaa334>] 0xffffffffffffffff
    
    Fixes: db50514f ("net: sched: add termination action to allow goto chain")
    Fixes: 97763dc0 ("net_sched: reject unknown tcfa_action values")
    Signed-off-by: default avatarDavide Caratti <dcaratti@redhat.com>
    Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
    85d0966f
act_pedit.c 11.6 KB