LKML Archive on lore.kernel.org help / color / mirror / Atom feed
From: Greg Kroah-Hartman <gregkh@linuxfoundation.org> To: linux-kernel@vger.kernel.org Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>, stable@vger.kernel.org, DaeRyong Jeong <threeearcat@gmail.com>, Byoungyoung Lee <byoungyoung@purdue.edu>, Willem de Bruijn <willemb@google.com>, "David S. Miller" <davem@davemloft.net> Subject: [PATCH 3.18 18/24] packet: fix bitfield update race Date: Fri, 27 Apr 2018 15:57:53 +0200 [thread overview] Message-ID: <20180427135632.336601010@linuxfoundation.org> (raw) In-Reply-To: <20180427135631.584839868@linuxfoundation.org> 3.18-stable review patch. If anyone has any objections, please let me know. ------------------ From: Willem de Bruijn <willemb@google.com> [ Upstream commit a6361f0ca4b25460f2cdf3235ebe8115f622901e ] Updates to the bitfields in struct packet_sock are not atomic. Serialize these read-modify-write cycles. Move po->running into a separate variable. Its writes are protected by po->bind_lock (except for one startup case at packet_create). Also replace a textual precondition warning with lockdep annotation. All others are set only in packet_setsockopt. Serialize these updates by holding the socket lock. Analogous to other field updates, also hold the lock when testing whether a ring is active (pg_vec). Fixes: 8dc419447415 ("[PACKET]: Add optional checksum computation for recvmsg") Reported-by: DaeRyong Jeong <threeearcat@gmail.com> Reported-by: Byoungyoung Lee <byoungyoung@purdue.edu> Signed-off-by: Willem de Bruijn <willemb@google.com> Signed-off-by: David S. Miller <davem@davemloft.net> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> --- net/packet/af_packet.c | 60 +++++++++++++++++++++++++++++++++++-------------- net/packet/internal.h | 10 ++++---- 2 files changed, 49 insertions(+), 21 deletions(-) --- a/net/packet/af_packet.c +++ b/net/packet/af_packet.c @@ -323,11 +323,11 @@ static void packet_pick_tx_queue(struct skb_set_queue_mapping(skb, queue_index); } -/* register_prot_hook must be invoked with the po->bind_lock held, +/* __register_prot_hook must be invoked through register_prot_hook * or from a context in which asynchronous accesses to the packet * socket is not possible (packet_create()). */ -static void register_prot_hook(struct sock *sk) +static void __register_prot_hook(struct sock *sk) { struct packet_sock *po = pkt_sk(sk); @@ -342,8 +342,13 @@ static void register_prot_hook(struct so } } -/* {,__}unregister_prot_hook() must be invoked with the po->bind_lock - * held. If the sync parameter is true, we will temporarily drop +static void register_prot_hook(struct sock *sk) +{ + lockdep_assert_held_once(&pkt_sk(sk)->bind_lock); + __register_prot_hook(sk); +} + +/* If the sync parameter is true, we will temporarily drop * the po->bind_lock and do a synchronize_net to make sure no * asynchronous packet processing paths still refer to the elements * of po->prot_hook. If the sync parameter is false, it is the @@ -353,6 +358,8 @@ static void __unregister_prot_hook(struc { struct packet_sock *po = pkt_sk(sk); + lockdep_assert_held_once(&po->bind_lock); + po->running = 0; if (po->fanout) @@ -2861,7 +2868,7 @@ static int packet_create(struct net *net if (proto) { po->prot_hook.type = proto; - register_prot_hook(sk); + __register_prot_hook(sk); } mutex_lock(&net->packet.sklist_lock); @@ -3352,12 +3359,18 @@ packet_setsockopt(struct socket *sock, i if (optlen != sizeof(val)) return -EINVAL; - if (po->rx_ring.pg_vec || po->tx_ring.pg_vec) - return -EBUSY; if (copy_from_user(&val, optval, sizeof(val))) return -EFAULT; - po->tp_loss = !!val; - return 0; + + lock_sock(sk); + if (po->rx_ring.pg_vec || po->tx_ring.pg_vec) { + ret = -EBUSY; + } else { + po->tp_loss = !!val; + ret = 0; + } + release_sock(sk); + return ret; } case PACKET_AUXDATA: { @@ -3368,7 +3381,9 @@ packet_setsockopt(struct socket *sock, i if (copy_from_user(&val, optval, sizeof(val))) return -EFAULT; + lock_sock(sk); po->auxdata = !!val; + release_sock(sk); return 0; } case PACKET_ORIGDEV: @@ -3380,7 +3395,9 @@ packet_setsockopt(struct socket *sock, i if (copy_from_user(&val, optval, sizeof(val))) return -EFAULT; + lock_sock(sk); po->origdev = !!val; + release_sock(sk); return 0; } case PACKET_VNET_HDR: @@ -3389,15 +3406,20 @@ packet_setsockopt(struct socket *sock, i if (sock->type != SOCK_RAW) return -EINVAL; - if (po->rx_ring.pg_vec || po->tx_ring.pg_vec) - return -EBUSY; if (optlen < sizeof(val)) return -EINVAL; if (copy_from_user(&val, optval, sizeof(val))) return -EFAULT; - po->has_vnet_hdr = !!val; - return 0; + lock_sock(sk); + if (po->rx_ring.pg_vec || po->tx_ring.pg_vec) { + ret = -EBUSY; + } else { + po->has_vnet_hdr = !!val; + ret = 0; + } + release_sock(sk); + return ret; } case PACKET_TIMESTAMP: { @@ -3428,11 +3450,17 @@ packet_setsockopt(struct socket *sock, i if (optlen != sizeof(val)) return -EINVAL; - if (po->rx_ring.pg_vec || po->tx_ring.pg_vec) - return -EBUSY; if (copy_from_user(&val, optval, sizeof(val))) return -EFAULT; - po->tp_tx_has_off = !!val; + + lock_sock(sk); + if (po->rx_ring.pg_vec || po->tx_ring.pg_vec) { + ret = -EBUSY; + } else { + po->tp_tx_has_off = !!val; + ret = 0; + } + release_sock(sk); return 0; } case PACKET_QDISC_BYPASS: --- a/net/packet/internal.h +++ b/net/packet/internal.h @@ -100,10 +100,12 @@ struct packet_sock { int copy_thresh; spinlock_t bind_lock; struct mutex pg_vec_lock; - unsigned int running:1, /* prot_hook is attached*/ - auxdata:1, + unsigned int running; /* bind_lock must be held */ + unsigned int auxdata:1, /* writer must hold sock lock */ origdev:1, - has_vnet_hdr:1; + has_vnet_hdr:1, + tp_loss:1, + tp_tx_has_off:1; int ifindex; /* bound device */ __be16 num; struct packet_mclist *mclist; @@ -111,8 +113,6 @@ struct packet_sock { enum tpacket_versions tp_version; unsigned int tp_hdrlen; unsigned int tp_reserve; - unsigned int tp_loss:1; - unsigned int tp_tx_has_off:1; unsigned int tp_tstamp; struct net_device __rcu *cached_dev; int (*xmit)(struct sk_buff *skb);
next prev parent reply other threads:[~2018-04-27 13:57 UTC|newest] Thread overview: 36+ messages / expand[flat|nested] mbox.gz Atom feed top 2018-04-27 13:57 [PATCH 3.18 00/24] 3.18.107-stable review Greg Kroah-Hartman 2018-04-27 13:57 ` [PATCH 3.18 01/24] cifs: do not allow creating sockets except with SMB1 posix exensions Greg Kroah-Hartman 2018-04-27 13:57 ` [PATCH 3.18 02/24] x86/tsc: Prevent 32bit truncation in calc_hpet_ref() Greg Kroah-Hartman 2018-04-27 13:57 ` [PATCH 3.18 03/24] ext4: fix deadlock between inline_data and ext4_expand_extra_isize_ea() Greg Kroah-Hartman 2018-04-27 13:57 ` [PATCH 3.18 04/24] ext4: bugfix for mmaped pages in mpage_release_unused_pages() Greg Kroah-Hartman 2018-04-27 13:57 ` [PATCH 3.18 05/24] ext4: dont update checksum of new initialized bitmaps Greg Kroah-Hartman 2018-04-27 13:57 ` [PATCH 3.18 06/24] perf: Return proper values for user stack errors Greg Kroah-Hartman 2018-04-27 13:57 ` [PATCH 3.18 07/24] mm/filemap.c: fix NULL pointer in page_cache_tree_insert() Greg Kroah-Hartman 2018-04-27 13:57 ` [PATCH 3.18 08/24] jbd2: fix use after free in kjournald2() Greg Kroah-Hartman 2018-04-27 13:57 ` [PATCH 3.18 09/24] bonding: do not set slave_dev npinfo before slave_enable_netpoll in bond_enslave Greg Kroah-Hartman 2018-04-27 13:57 ` [PATCH 3.18 10/24] KEYS: DNS: limit the length of option strings Greg Kroah-Hartman 2018-04-27 13:57 ` [PATCH 3.18 11/24] l2tp: check sockaddr length in pppol2tp_connect() Greg Kroah-Hartman 2018-04-27 13:57 ` [PATCH 3.18 12/24] tcp: dont read out-of-bounds opsize Greg Kroah-Hartman 2018-04-27 13:57 ` [PATCH 3.18 13/24] team: avoid adding twice the same option to the event list Greg Kroah-Hartman 2018-04-27 13:57 ` [PATCH 3.18 14/24] team: fix netconsole setup over team Greg Kroah-Hartman 2018-04-27 13:57 ` [PATCH 3.18 15/24] pppoe: check sockaddr length in pppoe_connect() Greg Kroah-Hartman 2018-04-27 13:57 ` [PATCH 3.18 16/24] llc: hold llc_sap before release_sock() Greg Kroah-Hartman 2018-04-27 13:57 ` [PATCH 3.18 17/24] llc: fix NULL pointer deref for SOCK_ZAPPED Greg Kroah-Hartman 2018-04-27 13:57 ` Greg Kroah-Hartman [this message] 2018-04-27 13:57 ` [PATCH 3.18 19/24] tcp: md5: reject TCP_MD5SIG or TCP_MD5SIG_EXT on established sockets Greg Kroah-Hartman 2018-04-27 13:57 ` [PATCH 3.18 20/24] net: af_packet: fix race in PACKET_{R|T}X_RING Greg Kroah-Hartman 2018-04-27 13:57 ` [PATCH 3.18 21/24] llc: delete timers synchronously in llc_sk_free() Greg Kroah-Hartman 2018-04-27 13:57 ` [PATCH 3.18 22/24] ipv6: add RTA_TABLE and RTA_PREFSRC to rtm_ipv6_policy Greg Kroah-Hartman 2018-04-27 13:57 ` [PATCH 3.18 23/24] scsi: mptsas: Disable WRITE SAME Greg Kroah-Hartman 2018-04-27 13:57 ` [PATCH 3.18 24/24] cdrom: information leak in cdrom_ioctl_media_changed() Greg Kroah-Hartman 2018-04-27 16:00 ` [PATCH 3.18 00/24] 3.18.107-stable review Dede Dindin Qudsy 2018-04-28 5:51 ` Greg Kroah-Hartman 2018-04-28 6:40 ` Harsh Shandilya 2018-04-27 18:12 ` Shuah Khan 2018-04-28 5:02 ` Greg Kroah-Hartman 2018-04-27 19:03 ` kernelci.org bot 2018-04-27 19:41 ` Theodore Y. Ts'o 2018-04-28 4:35 ` Greg Kroah-Hartman 2018-04-27 21:33 ` Harsh Shandilya 2018-04-28 5:02 ` Greg Kroah-Hartman 2018-04-28 14:24 ` Guenter Roeck
Reply instructions: You may reply publicly to this message via plain-text email using any one of the following methods: * Save the following mbox file, import it into your mail client, and reply-to-all from there: mbox Avoid top-posting and favor interleaved quoting: https://en.wikipedia.org/wiki/Posting_style#Interleaved_style * Reply using the --to, --cc, and --in-reply-to switches of git-send-email(1): git send-email \ --in-reply-to=20180427135632.336601010@linuxfoundation.org \ --to=gregkh@linuxfoundation.org \ --cc=byoungyoung@purdue.edu \ --cc=davem@davemloft.net \ --cc=linux-kernel@vger.kernel.org \ --cc=stable@vger.kernel.org \ --cc=threeearcat@gmail.com \ --cc=willemb@google.com \ /path/to/YOUR_REPLY https://kernel.org/pub/software/scm/git/docs/git-send-email.html * If your mail client supports setting the In-Reply-To header via mailto: links, try the mailto: linkBe sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox; as well as URLs for NNTP newsgroup(s).