linux/net
Marcelo Ricardo Leitner 779c19e0ac sctp: fix race on protocol/netns initialization
[ Upstream commit 8e2d61e0ae ]

Consider sctp module is unloaded and is being requested because an user
is creating a sctp socket.

During initialization, sctp will add the new protocol type and then
initialize pernet subsys:

        status = sctp_v4_protosw_init();
        if (status)
                goto err_protosw_init;

        status = sctp_v6_protosw_init();
        if (status)
                goto err_v6_protosw_init;

        status = register_pernet_subsys(&sctp_net_ops);

The problem is that after those calls to sctp_v{4,6}_protosw_init(), it
is possible for userspace to create SCTP sockets like if the module is
already fully loaded. If that happens, one of the possible effects is
that we will have readers for net->sctp.local_addr_list list earlier
than expected and sctp_net_init() does not take precautions while
dealing with that list, leading to a potential panic but not limited to
that, as sctp_sock_init() will copy a bunch of blank/partially
initialized values from net->sctp.

The race happens like this:

     CPU 0                           |  CPU 1
  socket()                           |
   __sock_create                     | socket()
    inet_create                      |  __sock_create
     list_for_each_entry_rcu(        |
        answer, &inetsw[sock->type], |
        list) {                      |   inet_create
      /* no hits */                  |
     if (unlikely(err)) {            |
      ...                            |
      request_module()               |
      /* socket creation is blocked  |
       * the module is fully loaded  |
       */                            |
       sctp_init                     |
        sctp_v4_protosw_init         |
         inet_register_protosw       |
          list_add_rcu(&p->list,     |
                       last_perm);   |
                                     |  list_for_each_entry_rcu(
                                     |     answer, &inetsw[sock->type],
        sctp_v6_protosw_init         |     list) {
                                     |     /* hit, so assumes protocol
                                     |      * is already loaded
                                     |      */
                                     |  /* socket creation continues
                                     |   * before netns is initialized
                                     |   */
        register_pernet_subsys       |

Simply inverting the initialization order between
register_pernet_subsys() and sctp_v4_protosw_init() is not possible
because register_pernet_subsys() will create a control sctp socket, so
the protocol must be already visible by then. Deferring the socket
creation to a work-queue is not good specially because we loose the
ability to handle its errors.

So, as suggested by Vlad, the fix is to split netns initialization in
two moments: defaults and control socket, so that the defaults are
already loaded by when we register the protocol, while control socket
initialization is kept at the same moment it is today.

Fixes: 4db67e8086 ("sctp: Make the address lists per network namespace")
Signed-off-by: Vlad Yasevich <vyasevich@gmail.com>
Signed-off-by: Marcelo Ricardo Leitner <marcelo.leitner@gmail.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Signed-off-by: Sasha Levin <sasha.levin@oracle.com>
History 2015-10-27 09:33:02 -04:00
..
6lowpan 6lowpan: Allow 6LoWPAN to be modular 2014-08-07 11:44:18 -07:00
9p 9p: forgetting to cancel request on interrupted zero-copy RPC 2015-08-04 14:41:41 -04:00
802 net: set name_assign_type in alloc_netdev() 2014-07-15 16:12:48 -07:00
8021q net: better IFF_XMIT_DST_RELEASE support 2014-10-07 13:22:11 -04:00
appletalk Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/net 2014-07-16 14:09:34 -07:00
atm net: better IFF_XMIT_DST_RELEASE support 2014-10-07 13:22:11 -04:00
ax25 net: Fix use after free by removing length arg from sk_data_ready callbacks. 2014-04-11 16:15:36 -04:00
batman-adv batman-adv: avoid NULL dereferences and fix if check 2015-01-27 08:29:33 -08:00
bluetooth Bluetooth: Fix valid Identity Address check 2015-03-06 14:52:44 -08:00
bridge bridge: mdb: fix double add notification 2015-09-28 18:57:00 -04:00
caif unix/caif: sk_socket can disappear when state is unlocked 2015-06-15 14:26:52 -04:00
can Revert "can: fix loss of CAN frames in raw_rcv" 2015-08-04 13:32:39 -04:00
ceph crush: ensuring at most num-rep osds are selected 2015-06-15 14:29:41 -04:00
core rtnetlink: verify IFLA_VF_INFO attributes before passing them to driver 2015-10-27 09:32:53 -04:00
dcb dcbnl : Disable software interrupts before taking dcb_lock 2014-11-16 14:50:52 -05:00
dccp Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/net 2014-10-18 09:31:37 -07:00
decnet af_decnet: Use time_after_eq 2014-08-22 12:23:11 -07:00
dns_resolver Merge commit 'v3.16' into next 2014-10-01 00:44:04 +10:00
dsa net: dsa: slave: Fix autoneg for phys on switch MDIO bus 2014-11-06 15:06:28 -05:00
ethernet net: Add function for parsing the header length out of linear ethernet frames 2014-09-05 17:47:02 -07:00
hsr net/hsr: Remove left-over never-true conditional code. 2014-07-11 15:04:40 -07:00
ieee802154 Merge tag 'master-2014-10-02' of git://git.kernel.org/pub/scm/linux/kernel/git/linville/wireless-next 2014-10-05 21:34:39 -04:00
ipv4 inet: frags: fix defragmented packet's IP header for af_packet 2015-09-28 18:57:01 -04:00
ipv6 net/ipv6: Correct PIM6 mrt_lock handling 2015-10-27 09:33:01 -04:00
ipx ipx: fix locking regression in ipx_sendmsg and ipx_recvmsg 2014-11-20 22:57:03 -05:00
irda net: irda: fix wait_until_sent poll timeout 2015-03-14 15:37:25 -04:00
iucv iucv: Convert pr_warning to pr_warn 2014-09-10 12:40:10 -07:00
key af_key: remove unnecessary break after return 2014-07-15 16:27:00 -07:00
l2tp l2tp: Refactor l2tp core driver to make use of the common UDP tunnel functions 2014-09-19 15:57:15 -04:00
lapb net/lapb: re-send packets on timeout 2013-09-23 16:52:45 -04:00
llc net_dma: simple removal 2014-09-28 07:05:16 -07:00
mac80211 mac80211: enable assoc check for mesh interfaces 2015-10-07 10:04:31 -04:00
mac802154 Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/net-next 2014-10-08 21:40:54 -04:00
mpls mpls: Allow mpls_gso to be built as module 2014-10-31 15:47:21 -04:00
netfilter netfilter: nf_tables: allow to change chain policy without hook if it exists 2015-07-13 08:50:05 -04:00
netlabel cipso: don't use IPCB() to locate the CIPSO IP option 2015-03-06 14:52:59 -08:00
netlink netlink, mmap: transform mmap skb into full skb on taps 2015-10-27 09:33:01 -04:00
netrom netrom: use linux/uaccess.h 2014-10-17 23:52:54 -04:00
nfc NFC: nci: Add support for proprietary RF Protocols 2014-09-24 02:02:24 +02:00
openvswitch vlan: introduce *vlan_hwaccel_push_inside helpers 2015-04-27 16:48:34 -04:00
packet packet: avoid out of bounds read in round robin fanout 2015-07-05 10:12:58 -04:00
phonet net: fix rcu access on phonet_routes 2014-10-06 18:16:30 -04:00
rds rds: fix an integer overflow test in rds_info_getsockopt() 2015-09-28 18:57:02 -04:00
rfkill net: rfkill: kernel-doc warning fixes 2014-10-09 11:16:15 +02:00
rose NET: ROSE: Don't dereference NULL neighbour pointer. 2015-07-05 10:12:48 -04:00
rxrpc rxrpc: bogus MSG_PEEK test in rxrpc_recvmsg() 2015-03-24 08:22:20 -04:00
sched net_sched: invoke ->attach() after setting dev->qdisc 2015-06-15 14:26:52 -04:00
sctp sctp: fix race on protocol/netns initialization 2015-10-27 09:33:02 -04:00
sunrpc SUNRPC: Fix a memory leak in the backchannel code 2015-07-03 23:02:23 -04:00
tipc net/tipc: initialize security state for new connection socket 2015-09-27 12:18:54 -04:00
unix unix/caif: sk_socket can disappear when state is unlocked 2015-06-15 14:26:52 -04:00
vmw_vsock vsock: Make transport the proto owner 2014-05-05 13:13:50 -04:00
wimax wimax: convert printk to pr_foo() 2014-10-07 20:28:44 -04:00
wireless cfg80211: wext: clear sinfo struct before calling driver 2015-07-03 12:34:46 -04:00
x25 net: Fix use after free by removing length arg from sk_data_ready callbacks. 2014-04-11 16:15:36 -04:00
xfrm xfrm: Override skb->mark with tunnel->parm.i_key in xfrm_input 2015-08-27 13:26:13 -04:00
compat.c net: compat: Update get_compat_msghdr() to match copy_msghdr_from_user() behaviour 2015-03-24 08:22:21 -04:00
Kconfig bpf: split eBPF out of NET 2014-10-27 19:09:59 -04:00
Makefile 6lowpan: introduce new net/6lowpan directory 2014-07-12 01:53:30 +02:00
nonet.c llseek: automatically add .llseek fop 2010-10-15 15:53:27 +02:00
socket.c net: socket: Fix the wrong returns for recvmsg and sendmsg 2015-07-03 12:34:30 -04:00
sysctl_net.c net: Update the sysctl permissions handler to test effective uid/gid 2013-10-07 15:57:56 -04:00