Patch "ipsec: Fix aborted xfrm policy dump crash" 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
ipsec: Fix aborted xfrm policy dump crash
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:
ipsec-fix-aborted-xfrm-policy-dump-crash.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
1137b5e2529a8f5ca8ee709288ecba3e68044df2Mon Sep 17 00:00:00 2001
From: Herbert Xu <[email protected]>
Date: Thu, 19 Oct 2017 20:51:10 +0800
Subject: ipsec: Fix aborted xfrm policy dump crash
From: Herbert Xu <[email protected]>
commit 1137b5e2529a8f5ca8ee709288ecba3e68044df2 upstream.
An independent security researcher, Mohamed Ghannam, has reported this vulnerability to Beyond Security's SecuriTeam Secure Disclosure program.
The xfrm_dump_policy_done function expects xfrm_dump_policy to have been called at least once or it will crash. This can be triggered if a dump fails because the target socket's receive buffer is full.
This patch fixes it by using the cb->start mechanism to ensure that the initialisation is always done regardless of the buffer situation.
--- net/xfrm/xfrm_user.c | 25 +++++++++++++++---------- 1 file changed, 15 insertions(+), 10 deletions(-)
net/xfrm/xfrm_user.c +15 -10
@@ -1656,32 +1656,34 @@ static int dump_one_policy(struct xfrm_pstatic int xfrm_dump_policy_done (struct netlink_callback *cb) { -struct xfrm_policy_walk *walk = (struct xfrm_policy_walk *) &cb->args[1 ]; +struct xfrm_policy_walk *walk = (struct xfrm_policy_walk *)cb->args;struct net *net =sock_net (cb->skb->sk);xfrm_policy_walk_done (walk, net);return 0 ; } +static int xfrm_dump_policy_start (struct netlink_callback *cb) +{ +struct xfrm_policy_walk *walk = (struct xfrm_policy_walk *)cb->args; + +BUILD_BUG_ON (sizeof (*walk) >sizeof (cb->args)); + +xfrm_policy_walk_init (walk,XFRM_POLICY_TYPE_ANY ); +return 0 ; +} +static int xfrm_dump_policy (struct sk_buff *skb,struct netlink_callback *cb) {struct net *net =sock_net (skb->sk); -struct xfrm_policy_walk *walk = (struct xfrm_policy_walk *) &cb->args[1 ]; +struct xfrm_policy_walk *walk = (struct xfrm_policy_walk *)cb->args;struct xfrm_dump_info info; -BUILD_BUG_ON (sizeof (struct xfrm_policy_walk ) > -sizeof (cb->args) -sizeof (cb->args[0 ])); - info.in_skb = cb->skb; info.out_skb = skb; info.nlmsg_seq = cb->nlh->nlmsg_seq; info.nlmsg_flags =NLM_F_MULTI ; -if (!cb->args[0 ]) { - cb->args[0 ] =1 ; -xfrm_policy_walk_init (walk,XFRM_POLICY_TYPE_ANY ); - } - (void )xfrm_policy_walk (net, walk, dump_one_policy, &info);return skb->len;
@@ -2415,6 +2417,7 @@ static const struct nla_policy xfrma_spd static const struct xfrm_link { int (*doit)(struct sk_buff *, struct nlmsghdr *, struct nlattr **); + int (*start)(struct netlink_callback *); int (*dump)(struct sk_buff *, struct netlink_callback *); int (*done)(struct netlink_callback *); const struct nla_policy *nla_pol;
@@ -2428,6 +2431,7 @@ static const struct xfrm_link { [XFRM_MSG_NEWPOLICY - XFRM_MSG_BASE] = { .doit = xfrm_add_policy }, [XFRM_MSG_DELPOLICY - XFRM_MSG_BASE] = { .doit = xfrm_get_policy }, [XFRM_MSG_GETPOLICY - XFRM_MSG_BASE] = { .doit = xfrm_get_policy, + .start = xfrm_dump_policy_start, .dump = xfrm_dump_policy, .done = xfrm_dump_policy_done }, [XFRM_MSG_ALLOCSPI - XFRM_MSG_BASE] = { .doit = xfrm_alloc_userspi },
@@ -2479,6 +2483,7 @@ static int xfrm_user_rcv_msg(struct sk_b {struct netlink_dump_control c = { + .start = link->start, .dump = link->dump, .done = link->done, };
Patches currently in stable-queue which might be from [email protected] are
queue-4.9/ipsec-fix-aborted-xfrm-policy-dump-crash.patch