From: ebiederm@xmission.com (Eric W. Biederman)
To: Andy Lutomirski <luto@amacapital.net>
Cc: Linus Torvalds <torvalds@linux-foundation.org>,
"Jorge Boncompte \[DTI2\]" <jorge@dti2.net>,
Jiri Benc <jbenc@redhat.com>, David Miller <davem@davemloft.net>,
Vivek Goyal <vgoyal@redhat.com>, Simo Sorce <ssorce@redhat.com>,
"security\@kernel.org" <security@kernel.org>,
Network Development <netdev@vger.kernel.org>,
"Serge E. Hallyn" <serge@hallyn.com>,
Michael Kerrisk-manpages <mtk.manpages@gmail.com>
Subject: Re: [RFC][PATCH 2/1] netlink: Use the credential at the time the destination address was set.
Date: Mon, 26 May 2014 21:24:34 -0700 [thread overview]
Message-ID: <8738fvrgql.fsf@x220.int.ebiederm.org> (raw)
In-Reply-To: <CALCETrWDk4QBv=a8dvqymG8t7N_fDr7sEyyqu8s5+pVNnn1OQw@mail.gmail.com> (Andy Lutomirski's message of "Mon, 26 May 2014 10:19:56 -0700")
Andy Lutomirski <luto@amacapital.net> writes:
> On Sun, May 25, 2014 at 10:36 PM, Eric W. Biederman
> <ebiederm@xmission.com> wrote:
>>
>> When sending a message over a netlink socket and then checking to see if
>> the person is authorized to send the message it is important that we verify
>> both the sender of the message and the whoever it is that set the destination
>> of the message both have permission. Otherwise it becomes possible for an
>> unpriivleged user to set the message destination and trick an suid process
>> to write to the socket and change the network connection.
>>
>> For netlink sockets socket() sets the default destination address to 0 (the kernel)
>> so we need to remember the credentials when a socket is created.
>>
>> For netlink sockets connect() changes the default destination address so
>> we need to remember the credentials of the last changer of the default destination
>> with connect.
>>
>> This results is there always being a valid remembered credential on the socket
>> and so that credential is unconditionally freed in netlink_release().
>>
>> This change makes the semantics of the permission checks of netlink sockets
>> make sense,and removes the possibility of an unprivileged user getting access
>> to a root own socket and changing the destination address with connect.
>>
>> Signed-off-by: "Eric W. Biederman" <ebiederm@xmission.com>
>> ---
>>
>> This winds up continuig to grab credentials when socket() is called
>> because we actually set the destination address in socket() for netlink
>> sockets, but now we update those credentials when connect() is called.
>>
>> include/linux/netlink.h | 2 +-
>> net/netlink/af_netlink.c | 27 ++++++++++++++++++++++++---
>> net/netlink/af_netlink.h | 1 +
>> 3 files changed, 26 insertions(+), 4 deletions(-)
>>
>> diff --git a/include/linux/netlink.h b/include/linux/netlink.h
>> index f289d085f87f..4f4607c0a1a1 100644
>> --- a/include/linux/netlink.h
>> +++ b/include/linux/netlink.h
>> @@ -19,7 +19,7 @@ enum netlink_skb_flags {
>> NETLINK_SKB_MMAPED = 0x1, /* Packet data is mmaped */
>> NETLINK_SKB_TX = 0x2, /* Packet was sent by userspace */
>> NETLINK_SKB_DELIVERED = 0x4, /* Packet was delivered */
>> - NETLINK_SKB_DST = 0x8, /* Packet not socket destination */
>> + NETLINK_SKB_DST = 0x8, /* Dst set in sendto or sendmsg */
>> };
>>
>> struct netlink_skb_parms {
>> diff --git a/net/netlink/af_netlink.c b/net/netlink/af_netlink.c
>> index 15c731f03fa6..5b886ed6a648 100644
>> --- a/net/netlink/af_netlink.c
>> +++ b/net/netlink/af_netlink.c
>> @@ -1191,6 +1191,7 @@ static int __netlink_create(struct net *net, struct socket *sock,
>> mutex_init(nlk->cb_mutex);
>> }
>> init_waitqueue_head(&nlk->wait);
>> + nlk->cred = get_current_cred();
>> #ifdef CONFIG_NETLINK_MMAP
>> mutex_init(&nlk->pg_vec_lock);
>> #endif
>> @@ -1291,6 +1292,7 @@ static int netlink_release(struct socket *sock)
>> NETLINK_URELEASE, &n);
>> }
>>
>> + put_cred(nlk->cred);
>> module_put(nlk->module);
>>
>> netlink_table_grab();
>> @@ -1377,9 +1379,17 @@ retry:
>> bool __netlink_ns_capable(const struct netlink_skb_parms *nsp,
>> struct user_namespace *user_ns, int cap)
>> {
>> - return ((nsp->flags & NETLINK_SKB_DST) ||
>> - file_ns_capable(nsp->sk->sk_socket->file, user_ns, cap)) &&
>> - ns_capable(user_ns, cap);
>> + const struct cred *cred;
>> + bool capable;
>> +
>> + rcu_read_lock();
>> + cred = nlk_sk(nsp->sk)->cred;
>> + capable = ((nsp->flags & NETLINK_SKB_DST) ||
>> + security_capable(cred, user_ns, cap)) &&
>> + ns_capable(user_ns, cap);
>> + rcu_read_unlock();
>> +
>> + return capable;
>> }
>> EXPORT_SYMBOL(__netlink_ns_capable);
>>
>> @@ -1569,14 +1579,20 @@ static int netlink_connect(struct socket *sock, struct sockaddr *addr,
>> struct sock *sk = sock->sk;
>> struct netlink_sock *nlk = nlk_sk(sk);
>> struct sockaddr_nl *nladdr = (struct sockaddr_nl *)addr;
>> + const struct cred *old_cred;
>>
>> if (alen < sizeof(addr->sa_family))
>> return -EINVAL;
>>
>> if (addr->sa_family == AF_UNSPEC) {
>> + lock_sock(sk);
>> sk->sk_state = NETLINK_UNCONNECTED;
>> nlk->dst_portid = 0;
>> nlk->dst_group = 0;
>> + old_cred = nlk->cred;
>> + nlk->cred = get_current_cred();
>> + put_cred(old_cred);
>> + release_sock(sk);
>> return 0;
>
> I'm confused about the locking. Either lock_sock prevents concurrent
> sendmsg, in which case the rcu_read_lock should be unnecessary, or it
> doesn't, in which case I think this is racy, because sendmsg could see
> a cred and dst_whatever that don't match. Admittedly, exploiting that
> race is probably extremely difficult.
My intention was to prevent races during connect which can cause the
wrong cred to be freed, which could be pretty nasty.
The intention of the rcu bits was just to guarantee that the cred
doesn't get freed during the write.
As for mismatches. There is only an issue with write/send that does
not specify a destination address. Although I admit sendmsg differing
could be a problem as well.
Getting the races out of the send path without destroying performance
is beyond my imagination today. It would be nice if we could make the
locking simply that connect waits until sendmmsg and similar functions
are complete preventing races.
I hate interfaces where things can be set multiple times on a kernel
data structure the races are absolutely horrible.
> If the RCU protection is needed, shouldn't this use rcu_assign_pointer
> and rcu_dereference?
Yep that would be good.
Any chance you could pick this up. I am going to be busy for the next
couple of days.
Eric
next prev parent reply other threads:[~2014-05-27 4:25 UTC|newest]
Thread overview: 45+ messages / expand[flat|nested] mbox.gz Atom feed top
[not found] <CALCETrUaYhh6Dkzn0TMEUz-GEO9-6ObByk5d_xRViSMBbp5Pkg@mail.gmail.com>
[not found] ` <cover.1397840611.git.luto@amacapital.net>
[not found] ` <6daf425e2023266d52d181e4d2ee18747d4f1fa8.1397840611.git.luto@amacapital.net>
[not found] ` <87tx9nuxf6.fsf@x220.int.ebiederm.org>
[not found] ` <CALCETrUqNVRBse4rUeUKfgYt0d+9x1JrEHGcZ_DnWyq7W6Yyzw@mail.gmail.com>
[not found] ` <87r44qtabz.fsf@x220.int.ebiederm.org>
[not found] ` <CALCETrWzUQ7QjykT85ExDfX-+9eDD-D-dcxofUMPvLK=ia9arg@mail.gmail.com>
[not found] ` <87r44qrt8v.fsf_-_@x220.int.ebiederm.org>
2014-04-22 21:13 ` [PATCH 0/6]: Preventing abuse when passing file descriptors Eric W. Biederman
2014-04-22 21:14 ` [PATCH 1/6] netlink: Rename netlink_capable netlink_allowed Eric W. Biederman
2014-04-22 21:15 ` [PATCH 2/6] net: Move the permission check in sock_diag_put_filterinfo to packet_diag_dump Eric W. Biederman
2014-04-22 21:15 ` [PATCH 3/6] net: Fix ns_capable check in packet_diag_dump Eric W. Biederman
2014-04-22 21:16 ` [PATCH 4/6] net: Add variants of capable for use on on sockets Eric W. Biederman
2014-04-22 21:16 ` [PATCH 5/6] net: Add variants of capable for use on netlink messages Eric W. Biederman
2014-04-22 21:17 ` [PATCH 6/6] net: Use netlink_ns_capable to verify the permisions of " Eric W. Biederman
2014-04-23 19:32 ` [PATCH 0/6]: Preventing abuse when passing file descriptors David Miller
2014-04-23 21:24 ` [PATCH 0/5]: " Eric W. Biederman
2014-04-23 21:25 ` [PATCH 1/5] netlink: Rename netlink_capable netlink_allowed Eric W. Biederman
2014-04-23 21:26 ` [PATCH 2/5] net: Move the permission check in sock_diag_put_filterinfo to packet_diag_dump Eric W. Biederman
2014-04-23 21:26 ` [PATCH 3/5] net: Add variants of capable for use on on sockets Eric W. Biederman
2014-04-23 21:28 ` [PATCH 4/5] net: Add variants of capable for use on netlink messages Eric W. Biederman
2014-04-23 21:29 ` [PATCH 5/5] net: Use netlink_ns_capable to verify the permisions of " Eric W. Biederman
2014-05-07 22:18 ` Jorge Boncompte [DTI2]
2014-05-07 22:26 ` Andy Lutomirski
2014-05-07 22:52 ` David Miller
2014-05-07 23:01 ` Andy Lutomirski
2014-05-07 23:34 ` Linus Torvalds
2014-05-07 23:45 ` Andy Lutomirski
2014-05-22 15:05 ` Jiri Benc
2014-05-23 23:25 ` Eric W. Biederman
2014-05-23 23:51 ` Linus Torvalds
2014-05-24 22:34 ` David Miller
2014-05-25 5:38 ` [RFC][PATCH] netlink: Only check file credentials for implicit destinations Eric W. Biederman
2014-05-25 16:50 ` Andy Lutomirski
2014-05-25 23:44 ` Eric W. Biederman
2014-05-26 0:32 ` Linus Torvalds
2014-05-26 5:36 ` [RFC][PATCH 2/1] netlink: Use the credential at the time the destination address was set Eric W. Biederman
2014-05-26 17:19 ` Andy Lutomirski
2014-05-27 4:24 ` Eric W. Biederman [this message]
2014-05-26 13:39 ` [RFC][PATCH] netlink: Only check file credentials for implicit destinations Willy Tarreau
2014-05-26 8:38 ` Michael Kerrisk (man-pages)
2014-05-25 5:45 ` [PATCH 5/5] net: Use netlink_ns_capable to verify the permisions of netlink messages Eric W. Biederman
2014-05-25 16:27 ` Andy Lutomirski
2014-05-08 21:29 ` Stephen Hemminger
2014-05-08 21:32 ` Andy Lutomirski
[not found] ` <CA+55aFzOHZcw2o6Cq6rSddSBDZvhgzYToBruak9SLCHxx-fA3Q@mail.gmail.com>
2014-05-08 21:49 ` Andy Lutomirski
2014-05-08 22:07 ` Stephen Hemminger
2014-05-08 21:54 ` David Miller
2014-05-07 23:45 ` David Miller
2014-05-08 21:21 ` Stephen Hemminger
2014-05-08 21:52 ` David Miller
2014-05-08 21:54 ` Andy Lutomirski
2014-04-24 17:45 ` [PATCH 0/5]: Preventing abuse when passing file descriptors David Miller
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=8738fvrgql.fsf@x220.int.ebiederm.org \
--to=ebiederm@xmission.com \
--cc=davem@davemloft.net \
--cc=jbenc@redhat.com \
--cc=jorge@dti2.net \
--cc=luto@amacapital.net \
--cc=mtk.manpages@gmail.com \
--cc=netdev@vger.kernel.org \
--cc=security@kernel.org \
--cc=serge@hallyn.com \
--cc=ssorce@redhat.com \
--cc=torvalds@linux-foundation.org \
--cc=vgoyal@redhat.com \
/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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.