Patch "af_key: Add lock to key dump" has been added to the 4.9-stable tree
Subsystems (3)
This is a note to let you know that I've just added the patch titled
af_key: Add lock to key dump
to the 4.9-stable tree which can be found at:
http://www.kernel.org/git/?p=linux/kernel/git/stable/stable-queue.git;a=summary
The filename of the patch is:
af_key-add-lock-to-key-dump.patch
and it can be found in the queue-4.9 subdirectory.
If you, or anyone else, feels it should not be added to the stable tree, please let <[email protected]> know about it.
Quoted 1 line
From
89e357d83c06b6fac581c3ca7f0ee3ae7e67109eMon Sep 17 00:00:00 2001
From: Yuejie Shi <[email protected]>
Date: Fri, 31 Mar 2017 15:10:20 +0800
Subject: af_key: Add lock to key dump
From: Yuejie Shi <[email protected]>
commit 89e357d83c06b6fac581c3ca7f0ee3ae7e67109e upstream.
A dump may come in the middle of another dump, modifying its dump structure members. This race condition will result in NULL pointer dereference in kernel. So add a lock to prevent that race.
--- net/key/af_key.c | 46 ++++++++++++++++++++++++++++++++++++++-------- 1 file changed, 38 insertions(+), 8 deletions(-)
net/key/af_key.c +38 -8
@@ -63,6 +63,7 @@ struct pfkey_sock { } u;struct sk_buff *skb; } dump; +struct mutex dump_lock; }; static int parse_sockaddr_pair(struct sockaddr *sa, int ext_len,
@@ -143,6 +144,7 @@ static int pfkey_create(struct net *net, {struct netns_pfkey *net_pfkey =net_generic (net, pfkey_net_id);struct sock *sk; +struct pfkey_sock *pfk;int err;if (!ns_capable (net->user_ns,CAP_NET_ADMIN ))
@@ -157,6 +159,9 @@ static int pfkey_create(struct net *net,if (sk ==NULL ) goto out; + pfk =pfkey_sk (sk); +mutex_init (&pfk->dump_lock); + sock->ops = &pfkey_ops;sock_init_data (sock, sk);
@@ -285,13 +290,23 @@ static int pfkey_do_dump(struct pfkey_sostruct sadb_msg *hdr;int rc; +mutex_lock (&pfk->dump_lock); +if (!pfk->dump.dump) { + rc =0 ; + goto out; + } + rc = pfk->dump.dump (pfk); -if (rc == -ENOBUFS ) -return 0 ; +if (rc == -ENOBUFS ) { + rc =0 ; + goto out; + }if (pfk->dump.skb) { -if (!pfkey_can_dump (&pfk->sk)) -return 0 ; +if (!pfkey_can_dump (&pfk->sk)) { + rc =0 ; + goto out; + } hdr = (struct sadb_msg *) pfk->dump.skb->data; hdr->sadb_msg_seq =0 ;
@@ -302,6 +317,9 @@ static int pfkey_do_dump(struct pfkey_so }pfkey_terminate_dump (pfk); + +out: +mutex_unlock (&pfk->dump_lock);return rc; }
@@ -1806,19 +1824,26 @@ static int pfkey_dump(struct sock *sk, sstruct xfrm_address_filter *filter =NULL ;struct pfkey_sock *pfk =pfkey_sk (sk); -if (pfk->dump.dump !=NULL ) +mutex_lock (&pfk->dump_lock); +if (pfk->dump.dump !=NULL ) { +mutex_unlock (&pfk->dump_lock);return -EBUSY ; + } proto =pfkey_satype2proto (hdr->sadb_msg_satype); -if (proto ==0 ) +if (proto ==0 ) { +mutex_unlock (&pfk->dump_lock);return -EINVAL ; + }if (ext_hdrs[SADB_X_EXT_FILTER -1 ]) {struct sadb_x_filter *xfilter = ext_hdrs[SADB_X_EXT_FILTER -1 ]; filter =kmalloc (sizeof (*filter),GFP_KERNEL ); -if (filter ==NULL ) +if (filter ==NULL ) { +mutex_unlock (&pfk->dump_lock);return -ENOMEM ; + }memcpy (&filter->saddr, &xfilter->sadb_x_filter_saddr,sizeof (xfrm_address_t));
@@ -1834,6 +1859,7 @@ static int pfkey_dump(struct sock *sk, s pfk->dump.dump = pfkey_dump_sa; pfk->dump.done = pfkey_dump_sa_done;xfrm_state_walk_init (&pfk->dump.u.state, proto, filter); +mutex_unlock (&pfk->dump_lock);return pfkey_do_dump (pfk); }
@@ -2693,14 +2719,18 @@ static int pfkey_spddump(struct sock *sk {struct pfkey_sock *pfk =pfkey_sk (sk); -if (pfk->dump.dump !=NULL ) +mutex_lock (&pfk->dump_lock); +if (pfk->dump.dump !=NULL ) { +mutex_unlock (&pfk->dump_lock);return -EBUSY ; + } pfk->dump.msg_version = hdr->sadb_msg_version; pfk->dump.msg_portid = hdr->sadb_msg_pid; pfk->dump.dump = pfkey_dump_sp; pfk->dump.done = pfkey_dump_sp_done;xfrm_policy_walk_init (&pfk->dump.u.policy,XFRM_POLICY_TYPE_MAIN ); +mutex_unlock (&pfk->dump_lock);return pfkey_do_dump (pfk); }
Patches currently in stable-queue which might be from [email protected] are
queue-4.9/af_key-add-lock-to-key-dump.patch