netfilter.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: ebiederm@xmission.com (Eric W. Biederman)
To: Marian Marinov <mm@1h.com>
Cc: Alin Dobre <alin.dobre@elastichosts.com>,
	containers@lists.linux-foundation.org, netfilter@vger.kernel.org,
	Jan Engelhardt <jengelh@medozas.de>
Subject: Re: Netfilter owner matching inside user namespace
Date: Thu, 22 May 2014 16:03:02 -0700	[thread overview]
Message-ID: <87k39dbemx.fsf@x220.int.ebiederm.org> (raw)
In-Reply-To: <537D706D.4010303@1h.com> (Marian Marinov's message of "Thu, 22 May 2014 06:35:09 +0300")

Marian Marinov <mm@1h.com> writes:

> On 05/22/2014 12:04 AM, Eric W. Biederman wrote:
>> Alin Dobre <alin.dobre@elastichosts.com> writes:
>> 
>>> Hello,
>>> 
>>> I am trying to run the following command inside an image using user namespaces via contain [1], a very simplistic
>>> implementation of linux containers: contain /path/to/image /bin/bash
>>> 
>>> Although the host kernel does have support for owner matching and it works with no errors, running the following
>>> iptables command inside the container: iptables -A OUTPUT -m owner --uid-owner root -j ACCEPT returns the error
>>> "Invalid argument".
>>> 
>>> The last commit for the netfilter xt_owner module is exactly Eric's basic support for user namespaces, but there
>>> might be some other recent changes either in the namespaces area or netfilter in general, which brought the
>>> module in an unusable state inside containers - at least for the above command usage.
>> 
>> The code says.
>> 
>> static int owner_check(const struct xt_mtchk_param *par) { struct xt_owner_match_info *info = par->matchinfo;
>> 
>> /* For now only allow adding matches from the initial user namespace */ if ((info->match &
>> (XT_OWNER_UID|XT_OWNER_GID)) && (current_user_ns() != &init_user_ns)) return -EINVAL; return 0; }
>> 
>> So it is not expected to work in user namespaces by design.
>> 
>>> I can try to send the image I used for testing to anyone who desires, but a handy shortcut should be "deboostrap
>>> trusty /path/to/image" and "chroot /path/to/image apt-get install iptables".
>>> 
>>> The host kernel is 3.14.4, iptables version on the host is 1.4.15 and inside the Ubuntu container is 1.4.18. I
>>> have tried with Ubuntu 13.* and Ubuntu 14.04, but I don't think the userspace has anything to do with this.
>>> 
>>> I can provide with any additional information needed.
>>> 
>>> Any insights on this?
>> 
>> As I recall this code largely matches directly on the values passed in from userspace.  Which in this case is a
>> problem because I would like to store kuids and kgids in the data structures and compare those.
>> 
>> I believe it would take some careful refactoring to allow massaging the data from the form the user supplied to
>> something more appropriate before we perform the match.
>> 
>> That is making this work is tricky so I punted and did not support it from inside a user namespace.
>> 
>
> Erik I have proposition about that... Please, tell me if I'm on the right track:
>
> diff --git a/net/netfilter/xt_owner.c b/net/netfilter/xt_owner.c
> index ca2e577..3682825 100644
> --- a/net/netfilter/xt_owner.c
> +++ b/net/netfilter/xt_owner.c
> @@ -33,6 +27,7 @@ owner_mt(const struct sk_buff *skb, struct xt_action_param *par)
>  {
>         const struct xt_owner_match_info *info = par->matchinfo;
>         const struct file *filp;
> + struct user_namespace *ns = get_current_cred()->user_ns;
>
>         if (skb->sk == NULL || skb->sk->sk_socket == NULL)
>                 return (info->match ^ info->invert) == 0;
> @@ -49,8 +44,8 @@ owner_mt(const struct sk_buff *skb, struct xt_action_param *par)
>                        (XT_OWNER_UID | XT_OWNER_GID)) == 0;
>
>         if (info->match & XT_OWNER_UID) {
> -           kuid_t uid_min = make_kuid(&init_user_ns, info->uid_min);
> -           kuid_t uid_max = make_kuid(&init_user_ns, info->uid_max);
> +         kuid_t uid_min = make_kuid(ns, info->uid_min);
> +         kuid_t uid_max = make_kuid(ns, info->uid_max);
>                 if ((uid_gte(filp->f_cred->fsuid, uid_min) &&
>                      uid_lte(filp->f_cred->fsuid, uid_max)) ^
>                     !(info->invert & XT_OWNER_UID))
> @@ -58,8 +53,8 @@ owner_mt(const struct sk_buff *skb, struct xt_action_param *par)
>         }
>
>         if (info->match & XT_OWNER_GID) {
> -           kgid_t gid_min = make_kgid(&init_user_ns, info->gid_min);
> -           kgid_t gid_max = make_kgid(&init_user_ns, info->gid_max);
> +         kgid_t gid_min = make_kgid(ns, info->gid_min);
> +         kgid_t gid_max = make_kgid(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))
>
> If the process has its own user and network namespaces, are the above changes enough?
>
> Since the rule is added to its own network namespace is it still a
> problem?


As I read the code the netfilter match does not need to be and I would
be highly surprised if it were called in the context of any specific
user process.   Which means we can not rely on current.

Check comes close to being the right place to change things, but check
doesn't change the data, only validates it :(

Eric

  reply	other threads:[~2014-05-22 23:03 UTC|newest]

Thread overview: 8+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2014-05-20 16:16 Netfilter owner matching inside user namespace Alin Dobre
2014-05-21 21:04 ` Eric W. Biederman
     [not found]   ` <877g5eg7wy.fsf-JOvCrm2gF+uungPnsOpG7nhyD016LWXt@public.gmane.org>
2014-05-22  3:35     ` Marian Marinov
2014-05-22 23:03       ` Eric W. Biederman [this message]
     [not found]       ` <537D706D.4010303-108MBtLGafw@public.gmane.org>
2014-05-25  7:39         ` [RFC][PATCH] net: Allow xt_owner in any " Eric W. Biederman
2014-05-26  8:28           ` Jan Engelhardt
     [not found]           ` <87vbsus3wb.fsf_-_-JOvCrm2gF+uungPnsOpG7nhyD016LWXt@public.gmane.org>
2014-05-29 13:39             ` Alin Dobre
2014-06-09 21:00           ` Alin Dobre

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=87k39dbemx.fsf@x220.int.ebiederm.org \
    --to=ebiederm@xmission.com \
    --cc=alin.dobre@elastichosts.com \
    --cc=containers@lists.linux-foundation.org \
    --cc=jengelh@medozas.de \
    --cc=mm@1h.com \
    --cc=netfilter@vger.kernel.org \
    /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: link
Be 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).