diff mbox

[Yakkety,Xenial,SRU,1/1] UBUNTU: SAUCE: (no-up) xfrm: Ignore socket policies when rebuilding hash tables

Message ID 3a28ce75b5bdb16396cdef6b07b711bed03e07b5.1471551334.git.joseph.salisbury@canonical.com
State New
Headers show

Commit Message

Joseph Salisbury Aug. 18, 2016, 8:29 p.m. UTC
From: Tobias Brunner <tobias@strongswan.org>

BugLink: http://bugs.launchpad.net/bugs/1613787

Whenever thresholds are changed the hash tables are rebuilt.  This is
done by enumerating all policies and hashing and inserting them into
the right table according to the thresholds and direction.

Because socket policies are also contained in net->xfrm.policy_all but
no hash tables are defined for their direction (dir + XFRM_POLICY_MAX)
this causes a NULL or invalid pointer dereference after returning from
policy_hash_bysel() if the rebuild is done while any socket policies
are installed.

Since the rebuild after changing thresholds is scheduled this crash
could even occur if the userland sets thresholds seemingly before
installing any socket policies.

Fixes: 53c2e285f970 ("xfrm: Do not hash socket policies")

Signed-off-by: Joseph Salisbury <joseph.salisbury@canonical.com>
---
 net/xfrm/xfrm_policy.c | 4 ++++
 1 file changed, 4 insertions(+)

Comments

Tim Gardner Aug. 19, 2016, 2:28 p.m. UTC | #1
On 08/18/2016 02:29 PM, Joseph Salisbury wrote:
> From: Tobias Brunner <tobias@strongswan.org>
> 
> BugLink: http://bugs.launchpad.net/bugs/1613787
> 
> Whenever thresholds are changed the hash tables are rebuilt.  This is
> done by enumerating all policies and hashing and inserting them into
> the right table according to the thresholds and direction.
> 
> Because socket policies are also contained in net->xfrm.policy_all but
> no hash tables are defined for their direction (dir + XFRM_POLICY_MAX)
> this causes a NULL or invalid pointer dereference after returning from
> policy_hash_bysel() if the rebuild is done while any socket policies
> are installed.
> 
> Since the rebuild after changing thresholds is scheduled this crash
> could even occur if the userland sets thresholds seemingly before
> installing any socket policies.
> 
> Fixes: 53c2e285f970 ("xfrm: Do not hash socket policies")
> 
> Signed-off-by: Joseph Salisbury <joseph.salisbury@canonical.com>
> ---
>  net/xfrm/xfrm_policy.c | 4 ++++
>  1 file changed, 4 insertions(+)
> 
> diff --git a/net/xfrm/xfrm_policy.c b/net/xfrm/xfrm_policy.c
> index b5e665b..45f9cf9 100644
> --- a/net/xfrm/xfrm_policy.c
> +++ b/net/xfrm/xfrm_policy.c
> @@ -626,6 +626,10 @@ static void xfrm_hash_rebuild(struct work_struct *work)
>  
>  	/* re-insert all policies by order of creation */
>  	list_for_each_entry_reverse(policy, &net->xfrm.policy_all, walk.all) {
> +		if (xfrm_policy_id2dir(policy->index) >= XFRM_POLICY_MAX) {
> +			/* skip socket policies */
> +			continue;
> +		}
>  		newpos = NULL;
>  		chain = policy_hash_bysel(net, &policy->selector,
>  					  policy->family,
> 

This is now a cherry-pick from linux-next, commit
6916fb3b10b3cbe3b1f9f5b680675f53e4e299eb ('xfrm: Ignore socket policies
when rebuilding hash tables')
diff mbox

Patch

diff --git a/net/xfrm/xfrm_policy.c b/net/xfrm/xfrm_policy.c
index b5e665b..45f9cf9 100644
--- a/net/xfrm/xfrm_policy.c
+++ b/net/xfrm/xfrm_policy.c
@@ -626,6 +626,10 @@  static void xfrm_hash_rebuild(struct work_struct *work)
 
 	/* re-insert all policies by order of creation */
 	list_for_each_entry_reverse(policy, &net->xfrm.policy_all, walk.all) {
+		if (xfrm_policy_id2dir(policy->index) >= XFRM_POLICY_MAX) {
+			/* skip socket policies */
+			continue;
+		}
 		newpos = NULL;
 		chain = policy_hash_bysel(net, &policy->selector,
 					  policy->family,