netdev.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH v2] netfilter: xt_owner: Add supplementary groups option
       [not found] <CGME20190508141219eucas1p1e5a899714747b497499976113ea9681f@eucas1p1.samsung.com>
@ 2019-05-08 14:12 ` Lukasz Pawelczyk
  2019-05-08 14:58   ` Eric Dumazet
  0 siblings, 1 reply; 10+ messages in thread
From: Lukasz Pawelczyk @ 2019-05-08 14:12 UTC (permalink / raw)
  To: Pablo Neira Ayuso, Jozsef Kadlecsik, Florian Westphal,
	David S. Miller, netfilter-devel, coreteam, netdev, linux-kernel
  Cc: Lukasz Pawelczyk, Lukasz Pawelczyk

The XT_SUPPL_GROUPS flag causes GIDs specified with XT_OWNER_GID to
be also checked in the supplementary groups of a process.

Signed-off-by: Lukasz Pawelczyk <l.pawelczyk@samsung.com>
---
 include/uapi/linux/netfilter/xt_owner.h |  1 +
 net/netfilter/xt_owner.c                | 23 ++++++++++++++++++++---
 2 files changed, 21 insertions(+), 3 deletions(-)

diff --git a/include/uapi/linux/netfilter/xt_owner.h b/include/uapi/linux/netfilter/xt_owner.h
index fa3ad84957d5..d646f0dc3466 100644
--- a/include/uapi/linux/netfilter/xt_owner.h
+++ b/include/uapi/linux/netfilter/xt_owner.h
@@ -8,6 +8,7 @@ enum {
 	XT_OWNER_UID    = 1 << 0,
 	XT_OWNER_GID    = 1 << 1,
 	XT_OWNER_SOCKET = 1 << 2,
+	XT_SUPPL_GROUPS = 1 << 3,
 };
 
 struct xt_owner_match_info {
diff --git a/net/netfilter/xt_owner.c b/net/netfilter/xt_owner.c
index 46686fb73784..283a1fb5cc52 100644
--- a/net/netfilter/xt_owner.c
+++ b/net/netfilter/xt_owner.c
@@ -91,11 +91,28 @@ owner_mt(const struct sk_buff *skb, struct xt_action_param *par)
 	}
 
 	if (info->match & XT_OWNER_GID) {
+		unsigned int i, match = false;
 		kgid_t gid_min = make_kgid(net->user_ns, info->gid_min);
 		kgid_t gid_max = make_kgid(net->user_ns, info->gid_max);
-		if ((gid_gte(filp->f_cred->fsgid, gid_min) &&
-		     gid_lte(filp->f_cred->fsgid, gid_max)) ^
-		    !(info->invert & XT_OWNER_GID))
+		struct group_info *gi = filp->f_cred->group_info;
+
+		if (gid_gte(filp->f_cred->fsgid, gid_min) &&
+		    gid_lte(filp->f_cred->fsgid, gid_max))
+			match = true;
+
+		if (!match && (info->match & XT_SUPPL_GROUPS) && gi) {
+			for (i = 0; i < gi->ngroups; ++i) {
+				kgid_t group = gi->gid[i];
+
+				if (gid_gte(group, gid_min) &&
+				    gid_lte(group, gid_max)) {
+					match = true;
+					break;
+				}
+			}
+		}
+
+		if (match ^ !(info->invert & XT_OWNER_GID))
 			return false;
 	}
 
-- 
2.20.1


^ permalink raw reply related	[flat|nested] 10+ messages in thread

* Re: [PATCH v2] netfilter: xt_owner: Add supplementary groups option
  2019-05-08 14:12 ` [PATCH v2] netfilter: xt_owner: Add supplementary groups option Lukasz Pawelczyk
@ 2019-05-08 14:58   ` Eric Dumazet
  2019-05-08 15:25     ` Lukasz Pawelczyk
  0 siblings, 1 reply; 10+ messages in thread
From: Eric Dumazet @ 2019-05-08 14:58 UTC (permalink / raw)
  To: Lukasz Pawelczyk, Pablo Neira Ayuso, Jozsef Kadlecsik,
	Florian Westphal, David S. Miller, netfilter-devel, coreteam,
	netdev, linux-kernel
  Cc: Lukasz Pawelczyk



On 5/8/19 10:12 AM, Lukasz Pawelczyk wrote:
> The XT_SUPPL_GROUPS flag causes GIDs specified with XT_OWNER_GID to
> be also checked in the supplementary groups of a process.
> 
> Signed-off-by: Lukasz Pawelczyk <l.pawelczyk@samsung.com>
> ---
>  include/uapi/linux/netfilter/xt_owner.h |  1 +
>  net/netfilter/xt_owner.c                | 23 ++++++++++++++++++++---
>  2 files changed, 21 insertions(+), 3 deletions(-)
> 
> diff --git a/include/uapi/linux/netfilter/xt_owner.h b/include/uapi/linux/netfilter/xt_owner.h
> index fa3ad84957d5..d646f0dc3466 100644
> --- a/include/uapi/linux/netfilter/xt_owner.h
> +++ b/include/uapi/linux/netfilter/xt_owner.h
> @@ -8,6 +8,7 @@ enum {
>  	XT_OWNER_UID    = 1 << 0,
>  	XT_OWNER_GID    = 1 << 1,
>  	XT_OWNER_SOCKET = 1 << 2,
> +	XT_SUPPL_GROUPS = 1 << 3,
>  };
>  
>  struct xt_owner_match_info {
> diff --git a/net/netfilter/xt_owner.c b/net/netfilter/xt_owner.c
> index 46686fb73784..283a1fb5cc52 100644
> --- a/net/netfilter/xt_owner.c
> +++ b/net/netfilter/xt_owner.c
> @@ -91,11 +91,28 @@ owner_mt(const struct sk_buff *skb, struct xt_action_param *par)
>  	}
>  
>  	if (info->match & XT_OWNER_GID) {
> +		unsigned int i, match = false;
>  		kgid_t gid_min = make_kgid(net->user_ns, info->gid_min);
>  		kgid_t gid_max = make_kgid(net->user_ns, info->gid_max);
> -		if ((gid_gte(filp->f_cred->fsgid, gid_min) &&
> -		     gid_lte(filp->f_cred->fsgid, gid_max)) ^
> -		    !(info->invert & XT_OWNER_GID))
> +		struct group_info *gi = filp->f_cred->group_info;
> +
> +		if (gid_gte(filp->f_cred->fsgid, gid_min) &&
> +		    gid_lte(filp->f_cred->fsgid, gid_max))
> +			match = true;
> +
> +		if (!match && (info->match & XT_SUPPL_GROUPS) && gi) {
> +			for (i = 0; i < gi->ngroups; ++i) {
> +				kgid_t group = gi->gid[i];
> +
> +				if (gid_gte(group, gid_min) &&
> +				    gid_lte(group, gid_max)) {
> +					match = true;
> +					break;
> +				}
> +			}
> +		}
> +
> +		if (match ^ !(info->invert & XT_OWNER_GID))
>  			return false;
>  	}
>  
> 

How can this be safe on SMP ?



^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [PATCH v2] netfilter: xt_owner: Add supplementary groups option
  2019-05-08 14:58   ` Eric Dumazet
@ 2019-05-08 15:25     ` Lukasz Pawelczyk
  2019-05-08 15:41       ` Eric Dumazet
  0 siblings, 1 reply; 10+ messages in thread
From: Lukasz Pawelczyk @ 2019-05-08 15:25 UTC (permalink / raw)
  To: Eric Dumazet, Pablo Neira Ayuso, Jozsef Kadlecsik,
	Florian Westphal, David S. Miller, netfilter-devel, coreteam,
	netdev, linux-kernel
  Cc: Lukasz Pawelczyk

On Wed, 2019-05-08 at 07:58 -0700, Eric Dumazet wrote:
> 
> On 5/8/19 10:12 AM, Lukasz Pawelczyk wrote:
> > The XT_SUPPL_GROUPS flag causes GIDs specified with XT_OWNER_GID to
> > be also checked in the supplementary groups of a process.
> > 
> > Signed-off-by: Lukasz Pawelczyk <l.pawelczyk@samsung.com>
> > ---
> >  include/uapi/linux/netfilter/xt_owner.h |  1 +
> >  net/netfilter/xt_owner.c                | 23 ++++++++++++++++++++-
> > --
> >  2 files changed, 21 insertions(+), 3 deletions(-)
> > 
> > diff --git a/include/uapi/linux/netfilter/xt_owner.h
> > b/include/uapi/linux/netfilter/xt_owner.h
> > index fa3ad84957d5..d646f0dc3466 100644
> > --- a/include/uapi/linux/netfilter/xt_owner.h
> > +++ b/include/uapi/linux/netfilter/xt_owner.h
> > @@ -8,6 +8,7 @@ enum {
> >  	XT_OWNER_UID    = 1 << 0,
> >  	XT_OWNER_GID    = 1 << 1,
> >  	XT_OWNER_SOCKET = 1 << 2,
> > +	XT_SUPPL_GROUPS = 1 << 3,
> >  };
> >  
> >  struct xt_owner_match_info {
> > diff --git a/net/netfilter/xt_owner.c b/net/netfilter/xt_owner.c
> > index 46686fb73784..283a1fb5cc52 100644
> > --- a/net/netfilter/xt_owner.c
> > +++ b/net/netfilter/xt_owner.c
> > @@ -91,11 +91,28 @@ owner_mt(const struct sk_buff *skb, struct
> > xt_action_param *par)
> >  	}
> >  
> >  	if (info->match & XT_OWNER_GID) {
> > +		unsigned int i, match = false;
> >  		kgid_t gid_min = make_kgid(net->user_ns, info-
> > >gid_min);
> >  		kgid_t gid_max = make_kgid(net->user_ns, info-
> > >gid_max);
> > -		if ((gid_gte(filp->f_cred->fsgid, gid_min) &&
> > -		     gid_lte(filp->f_cred->fsgid, gid_max)) ^
> > -		    !(info->invert & XT_OWNER_GID))
> > +		struct group_info *gi = filp->f_cred->group_info;
> > +
> > +		if (gid_gte(filp->f_cred->fsgid, gid_min) &&
> > +		    gid_lte(filp->f_cred->fsgid, gid_max))
> > +			match = true;
> > +
> > +		if (!match && (info->match & XT_SUPPL_GROUPS) && gi) {
> > +			for (i = 0; i < gi->ngroups; ++i) {
> > +				kgid_t group = gi->gid[i];
> > +
> > +				if (gid_gte(group, gid_min) &&
> > +				    gid_lte(group, gid_max)) {
> > +					match = true;
> > +					break;
> > +				}
> > +			}
> > +		}
> > +
> > +		if (match ^ !(info->invert & XT_OWNER_GID))
> >  			return false;
> >  	}
> >  
> > 
> 
> How can this be safe on SMP ?
> 

From what I see after the group_info rework some time ago this struct
is never modified. It's replaced. Would get_group_info/put_group_info
around the code be enough?


-- 
Lukasz Pawelczyk
Samsung R&D Institute Poland
Samsung Electronics




^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [PATCH v2] netfilter: xt_owner: Add supplementary groups option
  2019-05-08 15:25     ` Lukasz Pawelczyk
@ 2019-05-08 15:41       ` Eric Dumazet
  2019-05-08 15:56         ` Lukasz Pawelczyk
  0 siblings, 1 reply; 10+ messages in thread
From: Eric Dumazet @ 2019-05-08 15:41 UTC (permalink / raw)
  To: Lukasz Pawelczyk, Eric Dumazet, Pablo Neira Ayuso,
	Jozsef Kadlecsik, Florian Westphal, David S. Miller,
	netfilter-devel, coreteam, netdev, linux-kernel
  Cc: Lukasz Pawelczyk



On 5/8/19 11:25 AM, Lukasz Pawelczyk wrote:
> On Wed, 2019-05-08 at 07:58 -0700, Eric Dumazet wrote:
>>
>> On 5/8/19 10:12 AM, Lukasz Pawelczyk wrote:
>>> The XT_SUPPL_GROUPS flag causes GIDs specified with XT_OWNER_GID to
>>> be also checked in the supplementary groups of a process.
>>>
>>> Signed-off-by: Lukasz Pawelczyk <l.pawelczyk@samsung.com>
>>> ---
>>>  include/uapi/linux/netfilter/xt_owner.h |  1 +
>>>  net/netfilter/xt_owner.c                | 23 ++++++++++++++++++++-
>>> --
>>>  2 files changed, 21 insertions(+), 3 deletions(-)
>>>
>>> diff --git a/include/uapi/linux/netfilter/xt_owner.h
>>> b/include/uapi/linux/netfilter/xt_owner.h
>>> index fa3ad84957d5..d646f0dc3466 100644
>>> --- a/include/uapi/linux/netfilter/xt_owner.h
>>> +++ b/include/uapi/linux/netfilter/xt_owner.h
>>> @@ -8,6 +8,7 @@ enum {
>>>  	XT_OWNER_UID    = 1 << 0,
>>>  	XT_OWNER_GID    = 1 << 1,
>>>  	XT_OWNER_SOCKET = 1 << 2,
>>> +	XT_SUPPL_GROUPS = 1 << 3,
>>>  };
>>>  
>>>  struct xt_owner_match_info {
>>> diff --git a/net/netfilter/xt_owner.c b/net/netfilter/xt_owner.c
>>> index 46686fb73784..283a1fb5cc52 100644
>>> --- a/net/netfilter/xt_owner.c
>>> +++ b/net/netfilter/xt_owner.c
>>> @@ -91,11 +91,28 @@ owner_mt(const struct sk_buff *skb, struct
>>> xt_action_param *par)
>>>  	}
>>>  
>>>  	if (info->match & XT_OWNER_GID) {
>>> +		unsigned int i, match = false;
>>>  		kgid_t gid_min = make_kgid(net->user_ns, info-
>>>> gid_min);
>>>  		kgid_t gid_max = make_kgid(net->user_ns, info-
>>>> gid_max);
>>> -		if ((gid_gte(filp->f_cred->fsgid, gid_min) &&
>>> -		     gid_lte(filp->f_cred->fsgid, gid_max)) ^
>>> -		    !(info->invert & XT_OWNER_GID))
>>> +		struct group_info *gi = filp->f_cred->group_info;
>>> +
>>> +		if (gid_gte(filp->f_cred->fsgid, gid_min) &&
>>> +		    gid_lte(filp->f_cred->fsgid, gid_max))
>>> +			match = true;
>>> +
>>> +		if (!match && (info->match & XT_SUPPL_GROUPS) && gi) {
>>> +			for (i = 0; i < gi->ngroups; ++i) {
>>> +				kgid_t group = gi->gid[i];
>>> +
>>> +				if (gid_gte(group, gid_min) &&
>>> +				    gid_lte(group, gid_max)) {
>>> +					match = true;
>>> +					break;
>>> +				}
>>> +			}
>>> +		}
>>> +
>>> +		if (match ^ !(info->invert & XT_OWNER_GID))
>>>  			return false;
>>>  	}
>>>  
>>>
>>
>> How can this be safe on SMP ?
>>
> 
> From what I see after the group_info rework some time ago this struct
> is never modified. It's replaced. Would get_group_info/put_group_info
> around the code be enough?

What prevents the data to be freed right after you fetch filp->f_cred->group_info ?



^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [PATCH v2] netfilter: xt_owner: Add supplementary groups option
  2019-05-08 15:41       ` Eric Dumazet
@ 2019-05-08 15:56         ` Lukasz Pawelczyk
  2019-05-08 16:53           ` Eric Dumazet
  0 siblings, 1 reply; 10+ messages in thread
From: Lukasz Pawelczyk @ 2019-05-08 15:56 UTC (permalink / raw)
  To: Eric Dumazet, Pablo Neira Ayuso, Jozsef Kadlecsik,
	Florian Westphal, David S. Miller, netfilter-devel, coreteam,
	netdev, linux-kernel
  Cc: Lukasz Pawelczyk

On Wed, 2019-05-08 at 08:41 -0700, Eric Dumazet wrote:
> 
> On 5/8/19 11:25 AM, Lukasz Pawelczyk wrote:
> > On Wed, 2019-05-08 at 07:58 -0700, Eric Dumazet wrote:
> > > On 5/8/19 10:12 AM, Lukasz Pawelczyk wrote:
> > > > The XT_SUPPL_GROUPS flag causes GIDs specified with
> > > > XT_OWNER_GID to
> > > > be also checked in the supplementary groups of a process.
> > > > 
> > > > Signed-off-by: Lukasz Pawelczyk <l.pawelczyk@samsung.com>
> > > > ---
> > > >  include/uapi/linux/netfilter/xt_owner.h |  1 +
> > > >  net/netfilter/xt_owner.c                | 23
> > > > ++++++++++++++++++++-
> > > > --
> > > >  2 files changed, 21 insertions(+), 3 deletions(-)
> > > > 
> > > > diff --git a/include/uapi/linux/netfilter/xt_owner.h
> > > > b/include/uapi/linux/netfilter/xt_owner.h
> > > > index fa3ad84957d5..d646f0dc3466 100644
> > > > --- a/include/uapi/linux/netfilter/xt_owner.h
> > > > +++ b/include/uapi/linux/netfilter/xt_owner.h
> > > > @@ -8,6 +8,7 @@ enum {
> > > >  	XT_OWNER_UID    = 1 << 0,
> > > >  	XT_OWNER_GID    = 1 << 1,
> > > >  	XT_OWNER_SOCKET = 1 << 2,
> > > > +	XT_SUPPL_GROUPS = 1 << 3,
> > > >  };
> > > >  
> > > >  struct xt_owner_match_info {
> > > > diff --git a/net/netfilter/xt_owner.c
> > > > b/net/netfilter/xt_owner.c
> > > > index 46686fb73784..283a1fb5cc52 100644
> > > > --- a/net/netfilter/xt_owner.c
> > > > +++ b/net/netfilter/xt_owner.c
> > > > @@ -91,11 +91,28 @@ owner_mt(const struct sk_buff *skb, struct
> > > > xt_action_param *par)
> > > >  	}
> > > >  
> > > >  	if (info->match & XT_OWNER_GID) {
> > > > +		unsigned int i, match = false;
> > > >  		kgid_t gid_min = make_kgid(net->user_ns, info-
> > > > > gid_min);
> > > >  		kgid_t gid_max = make_kgid(net->user_ns, info-
> > > > > gid_max);
> > > > -		if ((gid_gte(filp->f_cred->fsgid, gid_min) &&
> > > > -		     gid_lte(filp->f_cred->fsgid, gid_max)) ^
> > > > -		    !(info->invert & XT_OWNER_GID))
> > > > +		struct group_info *gi = filp->f_cred-
> > > > >group_info;
> > > > +
> > > > +		if (gid_gte(filp->f_cred->fsgid, gid_min) &&
> > > > +		    gid_lte(filp->f_cred->fsgid, gid_max))
> > > > +			match = true;
> > > > +
> > > > +		if (!match && (info->match & XT_SUPPL_GROUPS)
> > > > && gi) {
> > > > +			for (i = 0; i < gi->ngroups; ++i) {
> > > > +				kgid_t group = gi->gid[i];
> > > > +
> > > > +				if (gid_gte(group, gid_min) &&
> > > > +				    gid_lte(group, gid_max)) {
> > > > +					match = true;
> > > > +					break;
> > > > +				}
> > > > +			}
> > > > +		}
> > > > +
> > > > +		if (match ^ !(info->invert & XT_OWNER_GID))
> > > >  			return false;
> > > >  	}
> > > >  
> > > > 
> > > 
> > > How can this be safe on SMP ?
> > > 
> > 
> > From what I see after the group_info rework some time ago this
> > struct
> > is never modified. It's replaced. Would
> > get_group_info/put_group_info
> > around the code be enough?
> 
> What prevents the data to be freed right after you fetch filp-
> >f_cred->group_info ?

I think the get_group_info() I mentioned above would. group_info seems
to always be freed by put_group_info().


-- 
Lukasz Pawelczyk
Samsung R&D Institute Poland
Samsung Electronics




^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [PATCH v2] netfilter: xt_owner: Add supplementary groups option
  2019-05-08 15:56         ` Lukasz Pawelczyk
@ 2019-05-08 16:53           ` Eric Dumazet
  2019-05-09 10:47             ` Lukasz Pawelczyk
  0 siblings, 1 reply; 10+ messages in thread
From: Eric Dumazet @ 2019-05-08 16:53 UTC (permalink / raw)
  To: Lukasz Pawelczyk, Pablo Neira Ayuso, Jozsef Kadlecsik,
	Florian Westphal, David S. Miller, netfilter-devel, coreteam,
	netdev, linux-kernel
  Cc: Lukasz Pawelczyk



On 5/8/19 11:56 AM, Lukasz Pawelczyk wrote:
> On Wed, 2019-05-08 at 08:41 -0700, Eric Dumazet wrote:
>>
>> On 5/8/19 11:25 AM, Lukasz Pawelczyk wrote:
>>> On Wed, 2019-05-08 at 07:58 -0700, Eric Dumazet wrote:
>>>> On 5/8/19 10:12 AM, Lukasz Pawelczyk wrote:
>>>>> The XT_SUPPL_GROUPS flag causes GIDs specified with
>>>>> XT_OWNER_GID to
>>>>> be also checked in the supplementary groups of a process.
>>>>>
>>>>> Signed-off-by: Lukasz Pawelczyk <l.pawelczyk@samsung.com>
>>>>> ---
>>>>>  include/uapi/linux/netfilter/xt_owner.h |  1 +
>>>>>  net/netfilter/xt_owner.c                | 23
>>>>> ++++++++++++++++++++-
>>>>> --
>>>>>  2 files changed, 21 insertions(+), 3 deletions(-)
>>>>>
>>>>> diff --git a/include/uapi/linux/netfilter/xt_owner.h
>>>>> b/include/uapi/linux/netfilter/xt_owner.h
>>>>> index fa3ad84957d5..d646f0dc3466 100644
>>>>> --- a/include/uapi/linux/netfilter/xt_owner.h
>>>>> +++ b/include/uapi/linux/netfilter/xt_owner.h
>>>>> @@ -8,6 +8,7 @@ enum {
>>>>>  	XT_OWNER_UID    = 1 << 0,
>>>>>  	XT_OWNER_GID    = 1 << 1,
>>>>>  	XT_OWNER_SOCKET = 1 << 2,
>>>>> +	XT_SUPPL_GROUPS = 1 << 3,
>>>>>  };
>>>>>  
>>>>>  struct xt_owner_match_info {
>>>>> diff --git a/net/netfilter/xt_owner.c
>>>>> b/net/netfilter/xt_owner.c
>>>>> index 46686fb73784..283a1fb5cc52 100644
>>>>> --- a/net/netfilter/xt_owner.c
>>>>> +++ b/net/netfilter/xt_owner.c
>>>>> @@ -91,11 +91,28 @@ owner_mt(const struct sk_buff *skb, struct
>>>>> xt_action_param *par)
>>>>>  	}
>>>>>  
>>>>>  	if (info->match & XT_OWNER_GID) {
>>>>> +		unsigned int i, match = false;
>>>>>  		kgid_t gid_min = make_kgid(net->user_ns, info-
>>>>>> gid_min);
>>>>>  		kgid_t gid_max = make_kgid(net->user_ns, info-
>>>>>> gid_max);
>>>>> -		if ((gid_gte(filp->f_cred->fsgid, gid_min) &&
>>>>> -		     gid_lte(filp->f_cred->fsgid, gid_max)) ^
>>>>> -		    !(info->invert & XT_OWNER_GID))
>>>>> +		struct group_info *gi = filp->f_cred-
>>>>>> group_info;
>>>>> +
>>>>> +		if (gid_gte(filp->f_cred->fsgid, gid_min) &&
>>>>> +		    gid_lte(filp->f_cred->fsgid, gid_max))
>>>>> +			match = true;
>>>>> +
>>>>> +		if (!match && (info->match & XT_SUPPL_GROUPS)
>>>>> && gi) {
>>>>> +			for (i = 0; i < gi->ngroups; ++i) {
>>>>> +				kgid_t group = gi->gid[i];
>>>>> +
>>>>> +				if (gid_gte(group, gid_min) &&
>>>>> +				    gid_lte(group, gid_max)) {
>>>>> +					match = true;
>>>>> +					break;
>>>>> +				}
>>>>> +			}
>>>>> +		}
>>>>> +
>>>>> +		if (match ^ !(info->invert & XT_OWNER_GID))
>>>>>  			return false;
>>>>>  	}
>>>>>  
>>>>>
>>>>
>>>> How can this be safe on SMP ?
>>>>
>>>
>>> From what I see after the group_info rework some time ago this
>>> struct
>>> is never modified. It's replaced. Would
>>> get_group_info/put_group_info
>>> around the code be enough?
>>
>> What prevents the data to be freed right after you fetch filp-
>>> f_cred->group_info ?
> 
> I think the get_group_info() I mentioned above would. group_info seems
> to always be freed by put_group_info().

The data can be freed _before_ get_group_info() is attempted.

get_group_info() would do a use-after-free

You would need something like RCU protection over this stuff,
this is not really only a netfilter change.



^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [PATCH v2] netfilter: xt_owner: Add supplementary groups option
  2019-05-08 16:53           ` Eric Dumazet
@ 2019-05-09 10:47             ` Lukasz Pawelczyk
  2019-05-09 11:29               ` Jan Engelhardt
  2019-05-09 11:57               ` Eric Dumazet
  0 siblings, 2 replies; 10+ messages in thread
From: Lukasz Pawelczyk @ 2019-05-09 10:47 UTC (permalink / raw)
  To: Eric Dumazet, Pablo Neira Ayuso, Jozsef Kadlecsik,
	Florian Westphal, David S. Miller, netfilter-devel, coreteam,
	netdev, linux-kernel
  Cc: Lukasz Pawelczyk

On Wed, 2019-05-08 at 09:53 -0700, Eric Dumazet wrote:
> 
> On 5/8/19 11:56 AM, Lukasz Pawelczyk wrote:
> > On Wed, 2019-05-08 at 08:41 -0700, Eric Dumazet wrote:
> > > On 5/8/19 11:25 AM, Lukasz Pawelczyk wrote:
> > > > On Wed, 2019-05-08 at 07:58 -0700, Eric Dumazet wrote:
> > > > > On 5/8/19 10:12 AM, Lukasz Pawelczyk wrote:
> > > > > > The XT_SUPPL_GROUPS flag causes GIDs specified with
> > > > > > XT_OWNER_GID to
> > > > > > be also checked in the supplementary groups of a process.
> > > > > > 
> > > > > > Signed-off-by: Lukasz Pawelczyk <l.pawelczyk@samsung.com>
> > > > > > ---
> > > > > >  include/uapi/linux/netfilter/xt_owner.h |  1 +
> > > > > >  net/netfilter/xt_owner.c                | 23
> > > > > > ++++++++++++++++++++-
> > > > > > --
> > > > > >  2 files changed, 21 insertions(+), 3 deletions(-)
> > > > > > 
> > > > > > diff --git a/include/uapi/linux/netfilter/xt_owner.h
> > > > > > b/include/uapi/linux/netfilter/xt_owner.h
> > > > > > index fa3ad84957d5..d646f0dc3466 100644
> > > > > > --- a/include/uapi/linux/netfilter/xt_owner.h
> > > > > > +++ b/include/uapi/linux/netfilter/xt_owner.h
> > > > > > @@ -8,6 +8,7 @@ enum {
> > > > > >  	XT_OWNER_UID    = 1 << 0,
> > > > > >  	XT_OWNER_GID    = 1 << 1,
> > > > > >  	XT_OWNER_SOCKET = 1 << 2,
> > > > > > +	XT_SUPPL_GROUPS = 1 << 3,
> > > > > >  };
> > > > > >  
> > > > > >  struct xt_owner_match_info {
> > > > > > diff --git a/net/netfilter/xt_owner.c
> > > > > > b/net/netfilter/xt_owner.c
> > > > > > index 46686fb73784..283a1fb5cc52 100644
> > > > > > --- a/net/netfilter/xt_owner.c
> > > > > > +++ b/net/netfilter/xt_owner.c
> > > > > > @@ -91,11 +91,28 @@ owner_mt(const struct sk_buff *skb,
> > > > > > struct
> > > > > > xt_action_param *par)
> > > > > >  	}
> > > > > >  
> > > > > >  	if (info->match & XT_OWNER_GID) {
> > > > > > +		unsigned int i, match = false;
> > > > > >  		kgid_t gid_min = make_kgid(net->user_ns, info-
> > > > > > > gid_min);
> > > > > >  		kgid_t gid_max = make_kgid(net->user_ns, info-
> > > > > > > gid_max);
> > > > > > -		if ((gid_gte(filp->f_cred->fsgid, gid_min) &&
> > > > > > -		     gid_lte(filp->f_cred->fsgid, gid_max)) ^
> > > > > > -		    !(info->invert & XT_OWNER_GID))
> > > > > > +		struct group_info *gi = filp->f_cred-
> > > > > > > group_info;
> > > > > > +
> > > > > > +		if (gid_gte(filp->f_cred->fsgid, gid_min) &&
> > > > > > +		    gid_lte(filp->f_cred->fsgid, gid_max))
> > > > > > +			match = true;
> > > > > > +
> > > > > > +		if (!match && (info->match & XT_SUPPL_GROUPS)
> > > > > > && gi) {
> > > > > > +			for (i = 0; i < gi->ngroups; ++i) {
> > > > > > +				kgid_t group = gi->gid[i];
> > > > > > +
> > > > > > +				if (gid_gte(group, gid_min) &&
> > > > > > +				    gid_lte(group, gid_max)) {
> > > > > > +					match = true;
> > > > > > +					break;
> > > > > > +				}
> > > > > > +			}
> > > > > > +		}
> > > > > > +
> > > > > > +		if (match ^ !(info->invert & XT_OWNER_GID))
> > > > > >  			return false;
> > > > > >  	}
> > > > > >  
> > > > > > 
> > > > > 
> > > > > How can this be safe on SMP ?
> > > > > 
> > > > 
> > > > From what I see after the group_info rework some time ago this
> > > > struct
> > > > is never modified. It's replaced. Would
> > > > get_group_info/put_group_info
> > > > around the code be enough?
> > > 
> > > What prevents the data to be freed right after you fetch filp-
> > > > f_cred->group_info ?
> > 
> > I think the get_group_info() I mentioned above would. group_info
> > seems
> > to always be freed by put_group_info().
> 
> The data can be freed _before_ get_group_info() is attempted.
> 
> get_group_info() would do a use-after-free
> 
> You would need something like RCU protection over this stuff,
> this is not really only a netfilter change.
> 

sk_socket keeps reference to f_cred. f_cred keeps reference to
group_info. As long as f_cred is alive and it doesn't seem to be the
issue in the owner_mt() function, group_info should be alive as well as
far as I can see. Its refcount will go down only when f_cred is freed
(put_cred_rcu()).

If there is something I'm missing please correct me.


-- 
Lukasz Pawelczyk
Samsung R&D Institute Poland
Samsung Electronics




^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [PATCH v2] netfilter: xt_owner: Add supplementary groups option
  2019-05-09 10:47             ` Lukasz Pawelczyk
@ 2019-05-09 11:29               ` Jan Engelhardt
  2019-05-09 11:57               ` Eric Dumazet
  1 sibling, 0 replies; 10+ messages in thread
From: Jan Engelhardt @ 2019-05-09 11:29 UTC (permalink / raw)
  To: Lukasz Pawelczyk
  Cc: Eric Dumazet, Pablo Neira Ayuso, Jozsef Kadlecsik,
	Florian Westphal, David S. Miller, netfilter-devel, coreteam,
	netdev, linux-kernel, Lukasz Pawelczyk


On Thursday 2019-05-09 12:47, Lukasz Pawelczyk wrote:
>> > > > > > index fa3ad84957d5..d646f0dc3466 100644
>> > > > > > --- a/include/uapi/linux/netfilter/xt_owner.h
>> > > > > > +++ b/include/uapi/linux/netfilter/xt_owner.h
>> > > > > > @@ -8,6 +8,7 @@ enum {
>> > > > > >  	XT_OWNER_UID    = 1 << 0,
>> > > > > >  	XT_OWNER_GID    = 1 << 1,
>> > > > > >  	XT_OWNER_SOCKET = 1 << 2,
>> > > > > > +	XT_SUPPL_GROUPS = 1 << 3,

In keeping with the naming, this should be something like
XT_OWNER_SUPPL_GROUPS.

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [PATCH v2] netfilter: xt_owner: Add supplementary groups option
  2019-05-09 10:47             ` Lukasz Pawelczyk
  2019-05-09 11:29               ` Jan Engelhardt
@ 2019-05-09 11:57               ` Eric Dumazet
  2019-05-09 12:01                 ` Lukasz Pawelczyk
  1 sibling, 1 reply; 10+ messages in thread
From: Eric Dumazet @ 2019-05-09 11:57 UTC (permalink / raw)
  To: Lukasz Pawelczyk, Eric Dumazet, Pablo Neira Ayuso,
	Jozsef Kadlecsik, Florian Westphal, David S. Miller,
	netfilter-devel, coreteam, netdev, linux-kernel
  Cc: Lukasz Pawelczyk



On 5/9/19 6:47 AM, Lukasz Pawelczyk wrote:
> On Wed, 2019-05-08 at 09:53 -0700, Eric Dumazet wrote:
>>
>> On 5/8/19 11:56 AM, Lukasz Pawelczyk wrote:
>>> On Wed, 2019-05-08 at 08:41 -0700, Eric Dumazet wrote:
>>>> On 5/8/19 11:25 AM, Lukasz Pawelczyk wrote:
>>>>> On Wed, 2019-05-08 at 07:58 -0700, Eric Dumazet wrote:
>>>>>> On 5/8/19 10:12 AM, Lukasz Pawelczyk wrote:
>>>>>>> The XT_SUPPL_GROUPS flag causes GIDs specified with
>>>>>>> XT_OWNER_GID to
>>>>>>> be also checked in the supplementary groups of a process.
>>>>>>>
>>>>>>> Signed-off-by: Lukasz Pawelczyk <l.pawelczyk@samsung.com>
>>>>>>> ---
>>>>>>>  include/uapi/linux/netfilter/xt_owner.h |  1 +
>>>>>>>  net/netfilter/xt_owner.c                | 23
>>>>>>> ++++++++++++++++++++-
>>>>>>> --
>>>>>>>  2 files changed, 21 insertions(+), 3 deletions(-)
>>>>>>>
>>>>>>> diff --git a/include/uapi/linux/netfilter/xt_owner.h
>>>>>>> b/include/uapi/linux/netfilter/xt_owner.h
>>>>>>> index fa3ad84957d5..d646f0dc3466 100644
>>>>>>> --- a/include/uapi/linux/netfilter/xt_owner.h
>>>>>>> +++ b/include/uapi/linux/netfilter/xt_owner.h
>>>>>>> @@ -8,6 +8,7 @@ enum {
>>>>>>>  	XT_OWNER_UID    = 1 << 0,
>>>>>>>  	XT_OWNER_GID    = 1 << 1,
>>>>>>>  	XT_OWNER_SOCKET = 1 << 2,
>>>>>>> +	XT_SUPPL_GROUPS = 1 << 3,
>>>>>>>  };
>>>>>>>  
>>>>>>>  struct xt_owner_match_info {
>>>>>>> diff --git a/net/netfilter/xt_owner.c
>>>>>>> b/net/netfilter/xt_owner.c
>>>>>>> index 46686fb73784..283a1fb5cc52 100644
>>>>>>> --- a/net/netfilter/xt_owner.c
>>>>>>> +++ b/net/netfilter/xt_owner.c
>>>>>>> @@ -91,11 +91,28 @@ owner_mt(const struct sk_buff *skb,
>>>>>>> struct
>>>>>>> xt_action_param *par)
>>>>>>>  	}
>>>>>>>  
>>>>>>>  	if (info->match & XT_OWNER_GID) {
>>>>>>> +		unsigned int i, match = false;
>>>>>>>  		kgid_t gid_min = make_kgid(net->user_ns, info-
>>>>>>>> gid_min);
>>>>>>>  		kgid_t gid_max = make_kgid(net->user_ns, info-
>>>>>>>> gid_max);
>>>>>>> -		if ((gid_gte(filp->f_cred->fsgid, gid_min) &&
>>>>>>> -		     gid_lte(filp->f_cred->fsgid, gid_max)) ^
>>>>>>> -		    !(info->invert & XT_OWNER_GID))
>>>>>>> +		struct group_info *gi = filp->f_cred-
>>>>>>>> group_info;
>>>>>>> +
>>>>>>> +		if (gid_gte(filp->f_cred->fsgid, gid_min) &&
>>>>>>> +		    gid_lte(filp->f_cred->fsgid, gid_max))
>>>>>>> +			match = true;
>>>>>>> +
>>>>>>> +		if (!match && (info->match & XT_SUPPL_GROUPS)
>>>>>>> && gi) {
>>>>>>> +			for (i = 0; i < gi->ngroups; ++i) {
>>>>>>> +				kgid_t group = gi->gid[i];
>>>>>>> +
>>>>>>> +				if (gid_gte(group, gid_min) &&
>>>>>>> +				    gid_lte(group, gid_max)) {
>>>>>>> +					match = true;
>>>>>>> +					break;
>>>>>>> +				}
>>>>>>> +			}
>>>>>>> +		}
>>>>>>> +
>>>>>>> +		if (match ^ !(info->invert & XT_OWNER_GID))
>>>>>>>  			return false;
>>>>>>>  	}
>>>>>>>  
>>>>>>>
>>>>>>
>>>>>> How can this be safe on SMP ?
>>>>>>
>>>>>
>>>>> From what I see after the group_info rework some time ago this
>>>>> struct
>>>>> is never modified. It's replaced. Would
>>>>> get_group_info/put_group_info
>>>>> around the code be enough?
>>>>
>>>> What prevents the data to be freed right after you fetch filp-
>>>>> f_cred->group_info ?
>>>
>>> I think the get_group_info() I mentioned above would. group_info
>>> seems
>>> to always be freed by put_group_info().
>>
>> The data can be freed _before_ get_group_info() is attempted.
>>
>> get_group_info() would do a use-after-free
>>
>> You would need something like RCU protection over this stuff,
>> this is not really only a netfilter change.
>>
> 
> sk_socket keeps reference to f_cred. f_cred keeps reference to
> group_info. As long as f_cred is alive and it doesn't seem to be the
> issue in the owner_mt() function, group_info should be alive as well as
> far as I can see. Its refcount will go down only when f_cred is freed
> (put_cred_rcu()).
> 
> If there is something I'm missing please correct me.

The problem is that you can´t clearly explain why the code is safe :/

Why would get_group_info() be needed then ?

You need to explain this in the changelog, so that future bug hunters do not have
to guess.

Note to netfilter maintainers : 

owner_mt() reads sk->sk_socket multiple times, this looks racy to me.

(sock_orphan() could be done in the middle from another cpu)


diff --git a/net/netfilter/xt_owner.c b/net/netfilter/xt_owner.c
index 46686fb73784bf71c79282e87e3f01f2c0411f5c..6adfb992bfe1765c57430b4bb98212786086d379 100644
--- a/net/netfilter/xt_owner.c
+++ b/net/netfilter/xt_owner.c
@@ -66,8 +66,10 @@ owner_mt(const struct sk_buff *skb, struct xt_action_param *par)
        const struct file *filp;
        struct sock *sk = skb_to_full_sk(skb);
        struct net *net = xt_net(par);
+       struct socket *sock;
 
-       if (!sk || !sk->sk_socket || !net_eq(net, sock_net(sk)))
+       sock = sk ? READ_ONCE(sk->sk_socket) : NULL;
+       if (!sock || !net_eq(net, sock_net(sk)))
                return (info->match ^ info->invert) == 0;
        else if (info->match & info->invert & XT_OWNER_SOCKET)
                /*
@@ -76,7 +78,7 @@ owner_mt(const struct sk_buff *skb, struct xt_action_param *par)
                 */
                return false;
 
-       filp = sk->sk_socket->file;
+       filp = sock->file;
        if (filp == NULL)
                return ((info->match ^ info->invert) &
                       (XT_OWNER_UID | XT_OWNER_GID)) == 0;

^ permalink raw reply related	[flat|nested] 10+ messages in thread

* Re: [PATCH v2] netfilter: xt_owner: Add supplementary groups option
  2019-05-09 11:57               ` Eric Dumazet
@ 2019-05-09 12:01                 ` Lukasz Pawelczyk
  0 siblings, 0 replies; 10+ messages in thread
From: Lukasz Pawelczyk @ 2019-05-09 12:01 UTC (permalink / raw)
  To: Eric Dumazet, Pablo Neira Ayuso, Jozsef Kadlecsik,
	Florian Westphal, David S. Miller, netfilter-devel, coreteam,
	netdev, linux-kernel
  Cc: Lukasz Pawelczyk

On Thu, 2019-05-09 at 04:57 -0700, Eric Dumazet wrote:
> sk_socket keeps reference to f_cred. f_cred keeps reference to
> > group_info. As long as f_cred is alive and it doesn't seem to be
> > the
> > issue in the owner_mt() function, group_info should be alive as
> > well as
> > far as I can see. Its refcount will go down only when f_cred is
> > freed
> > (put_cred_rcu()).
> > 
> > If there is something I'm missing please correct me.
> 
> The problem is that you can´t clearly explain why the code is safe :/
> 
> Why would get_group_info() be needed then ?

Originally I though it wouldn't, that's why I did not include it in the
patch. Your question made me doubt that for a second. I also got
confused a little because the group_info code looked completely
different a while back, it got reworked and simplified.

> 
> You need to explain this in the changelog, so that future bug hunters
> do not have
> to guess.

Ok, I will.

-- 
Lukasz Pawelczyk
Samsung R&D Institute Poland
Samsung Electronics




^ permalink raw reply	[flat|nested] 10+ messages in thread

end of thread, other threads:[~2019-05-09 12:01 UTC | newest]

Thread overview: 10+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
     [not found] <CGME20190508141219eucas1p1e5a899714747b497499976113ea9681f@eucas1p1.samsung.com>
2019-05-08 14:12 ` [PATCH v2] netfilter: xt_owner: Add supplementary groups option Lukasz Pawelczyk
2019-05-08 14:58   ` Eric Dumazet
2019-05-08 15:25     ` Lukasz Pawelczyk
2019-05-08 15:41       ` Eric Dumazet
2019-05-08 15:56         ` Lukasz Pawelczyk
2019-05-08 16:53           ` Eric Dumazet
2019-05-09 10:47             ` Lukasz Pawelczyk
2019-05-09 11:29               ` Jan Engelhardt
2019-05-09 11:57               ` Eric Dumazet
2019-05-09 12:01                 ` Lukasz Pawelczyk

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).