diff mbox

[2/3] Security: Implement disablenetwork semantics. (v4)

Message ID 20091227010650.GA12190@heat
State RFC, archived
Delegated to: David Miller
Headers show

Commit Message

Michael Stone Dec. 27, 2009, 1:06 a.m. UTC
Implement security_* hooks for socket_create, socket_bind, socket_connect,
socket_sendmsg, and ptrace_access_check which return -EPERM when called from a
process with networking restrictions. Exempt AF_UNIX sockets.

Signed-off-by: Michael Stone <michael@laptop.org>
---
  include/linux/disablenetwork.h |   22 +++++++++++
  security/Makefile              |    1 +
  security/disablenetwork.c      |   73 ++++++++++++++++++++++++++++++++++++++
  security/security.c            |   76 +++++++++++++++++++++++++++++++++++++---
  4 files changed, 167 insertions(+), 5 deletions(-)
  create mode 100644 include/linux/disablenetwork.h
  create mode 100644 security/disablenetwork.c

Comments

Tetsuo Handa Dec. 27, 2009, 1:20 a.m. UTC | #1
Michael Stone wrote:
> +int disablenetwork_security_socket_sendmsg(struct socket * sock,
> +					   struct msghdr * msg, int size)
> +{
> +	if (sock->sk->sk_family != PF_UNIX &&
> +		current->network &&
> +		(msg->msg_name != NULL || msg->msg_namelen != 0))
> +		return -EPERM;
> +	return 0;
> +}

I think we should accept msg->msg_name != NULL || msg->msg_namelen != 0
if the socket is connection oriented protocols (e.g. TCP).

struct sockaddr_in addr = { ... };
int fd = socket(PF_INET, SOCK_STREAM, 0);
connect(fd, (struct sockadr *) &addr, sizeof(addr));
prctl( ... );
sendmsg(fd, (struct sockadr *) &addr, sizeof(addr));
--
To unsubscribe from this list: send the line "unsubscribe netdev" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Serge E. Hallyn Dec. 30, 2009, 6:50 p.m. UTC | #2
Quoting Michael Stone (michael@laptop.org):
> Implement security_* hooks for socket_create, socket_bind, socket_connect,
> socket_sendmsg, and ptrace_access_check which return -EPERM when called from a
> process with networking restrictions. Exempt AF_UNIX sockets.
> 
> Signed-off-by: Michael Stone <michael@laptop.org>

Acked-by: Serge Hallyn <serue@us.ibm.com>

> ---
>   include/linux/disablenetwork.h |   22 +++++++++++
>   security/Makefile              |    1 +
>   security/disablenetwork.c      |   73 ++++++++++++++++++++++++++++++++++++++
>   security/security.c            |   76 +++++++++++++++++++++++++++++++++++++---
>   4 files changed, 167 insertions(+), 5 deletions(-)
>   create mode 100644 include/linux/disablenetwork.h
>   create mode 100644 security/disablenetwork.c
> 
> diff --git a/include/linux/disablenetwork.h b/include/linux/disablenetwork.h
> new file mode 100644
> index 0000000..8a7bcc2
> --- /dev/null
> +++ b/include/linux/disablenetwork.h
> @@ -0,0 +1,22 @@
> +#ifndef __LINUX_DISABLENETWORK_H
> +#define __LINUX_DISABLENETWORK_H
> +
> +#ifdef CONFIG_SECURITY_DISABLENETWORK
> +
> +int disablenetwork_security_socket_create(int family, int type,
> +					  int protocol, int kern);

Bleh, I think disablenetwork_socket_create() is long enough :)

> +int disablenetwork_security_socket_bind(struct socket *sock,
> +				        struct sockaddr *address,
> +				        int addrlen);
> +int disablenetwork_security_socket_connect(struct socket *sock,
> +				           struct sockaddr *address,
> +					   int addrlen);
> +int disablenetwork_security_socket_sendmsg(struct socket *sock,
> +					   struct msghdr *msg,
> +					   int size);
> +int disablenetwork_security_ptrace_access_check(struct task_struct *child,
> +					        unsigned int mode);
> +
> +#endif /* CONFIG_SECURITY_DISABLENETWORK */
> +
> +#endif /* ! __LINUX_DISABLENETWORK_H */
> diff --git a/security/Makefile b/security/Makefile
> index da20a19..2f23b60 100644
> --- a/security/Makefile
> +++ b/security/Makefile
> @@ -20,6 +20,7 @@ obj-$(CONFIG_SECURITY_SMACK)		+= smack/built-in.o
>   obj-$(CONFIG_AUDIT)			+= lsm_audit.o
>   obj-$(CONFIG_SECURITY_TOMOYO)		+= tomoyo/built-in.o
>   obj-$(CONFIG_CGROUP_DEVICE)		+= device_cgroup.o
> +obj-$(CONFIG_SECURITY_DISABLENETWORK)	+= disablenetwork.o
>   
>   # Object integrity file lists
>   subdir-$(CONFIG_IMA)			+= integrity/ima
> diff --git a/security/disablenetwork.c b/security/disablenetwork.c
> new file mode 100644
> index 0000000..f45ddfc
> --- /dev/null
> +++ b/security/disablenetwork.c
> @@ -0,0 +1,73 @@
> +/*
> + * disablenetwork security hooks.
> + *
> + * Copyright (C) 2008-2009 Michael Stone <michael@laptop.org>
> + *
> + * Implements the disablenetwork discretionary access control logic underlying
> + * the prctl(PRCTL_SET_NETWORK, PR_NETWORK_OFF) interface.
> + *
> + * See Documentation/disablenetwork.txt for more information.
> + *
> + * This program is free software; you can redistribute it and/or
> + * modify it under the terms of the GNU General Public License as
> + * published by the Free Software Foundation, version 2 of the
> + * License.
> + */
> +
> +#include <linux/errno.h>
> +#include <linux/sched.h>
> +#include <net/sock.h>
> +#include <linux/socket.h>
> +#include <linux/disablenetwork.h>
> +
> +static inline int maybe_allow(void)
> +{
> +	if (current->network)
> +		return -EPERM;
> +	return 0;
> +}
> +
> +int disablenetwork_security_socket_create(int family, int type,
> +					  int protocol, int kern)
> +{
> +	if (family == AF_UNIX)
> +		return 0;
> +	return maybe_allow();
> +}
> +
> +int disablenetwork_security_socket_bind(struct socket * sock,
> +					struct sockaddr * address,
> +					int addrlen)
> +{
> +	if (address->sa_family == AF_UNIX)
> +		return 0;
> +	return maybe_allow();
> +}
> +
> +int disablenetwork_security_socket_connect(struct socket * sock,
> +					   struct sockaddr * address,
> +					   int addrlen)
> +{
> +	if (address->sa_family == AF_UNIX)
> +		return 0;
> +	return maybe_allow();
> +}
> +
> +int disablenetwork_security_socket_sendmsg(struct socket * sock,
> +					   struct msghdr * msg, int size)
> +{
> +	if (sock->sk->sk_family != PF_UNIX &&
> +		current->network &&
> +		(msg->msg_name != NULL || msg->msg_namelen != 0))
> +		return -EPERM;
> +	return 0;
> +}
> +
> +int disablenetwork_security_ptrace_access_check(struct task_struct *child,
> +                                                unsigned int mode)
> +{
> +	/* does current have networking restrictions not shared by child? */
> +	if (current->network & ~child->network)
> +		return -EPERM;
> +	return 0;
> +}
> diff --git a/security/security.c b/security/security.c
> index 24e060b..40ac615 100644
> --- a/security/security.c
> +++ b/security/security.c
> @@ -17,6 +17,7 @@
>   #include <linux/kernel.h>
>   #include <linux/security.h>
>   #include <linux/ima.h>
> +#include <linux/disablenetwork.h>
>   
>   /* Boot-time LSM user choice */
>   static __initdata char chosen_lsm[SECURITY_NAME_MAX + 1] =
> @@ -130,7 +131,20 @@ int register_security(struct security_operations *ops)
>   
>   int security_ptrace_access_check(struct task_struct *child, unsigned int mode)
>   {
> -	return security_ops->ptrace_access_check(child, mode);
> +	int ret = 0;
> +
> +	ret = security_ops->ptrace_access_check(child, mode);
> +	if (ret)
> +		goto out;
> +
> +#ifdef CONFIG_SECURITY_DISABLENETWORK
> +	ret = disablenetwork_security_ptrace_access_check(child, mode);
> +	if (ret)
> +		goto out;
> +#endif
> +
> +out:
> +	return ret;
>   }
>   
>   int security_ptrace_traceme(struct task_struct *parent)
> @@ -1054,7 +1068,20 @@ EXPORT_SYMBOL(security_unix_may_send);
>   
>   int security_socket_create(int family, int type, int protocol, int kern)
>   {
> -	return security_ops->socket_create(family, type, protocol, kern);
> +	int ret = 0;
> +
> +	ret = security_ops->socket_create(family, type, protocol, kern);
> +	if (ret)
> +		goto out;
> +
> +#ifdef CONFIG_SECURITY_DISABLENETWORK
> +	ret = disablenetwork_security_socket_create(family, type, protocol, kern);
> +	if (ret)
> +		goto out;
> +#endif
> +
> +out:
> +	return ret;
>   }
>   
>   int security_socket_post_create(struct socket *sock, int family,
> @@ -1066,12 +1093,38 @@ int security_socket_post_create(struct socket *sock, int family,
>   
>   int security_socket_bind(struct socket *sock, struct sockaddr *address, int addrlen)
>   {
> -	return security_ops->socket_bind(sock, address, addrlen);
> +	int ret = 0;
> +
> +	ret = security_ops->socket_bind(sock, address, addrlen);
> +	if (ret)
> +		goto out;
> +
> +#ifdef CONFIG_SECURITY_DISABLENETWORK
> +	ret = disablenetwork_security_socket_bind(sock, address, addrlen);
> +	if (ret)
> +		goto out;
> +#endif
> +
> +out:
> +	return ret;
>   }
>   
>   int security_socket_connect(struct socket *sock, struct sockaddr *address, int addrlen)
>   {
> -	return security_ops->socket_connect(sock, address, addrlen);
> +	int ret = 0;
> +
> +	ret = security_ops->socket_connect(sock, address, addrlen);
> +	if (ret)
> +		goto out;
> +
> +#ifdef CONFIG_SECURITY_DISABLENETWORK
> +	ret = disablenetwork_security_socket_connect(sock, address, addrlen);
> +	if (ret)
> +		goto out;
> +#endif
> +
> +out:
> +	return ret;
>   }
>   
>   int security_socket_listen(struct socket *sock, int backlog)
> @@ -1086,7 +1139,20 @@ int security_socket_accept(struct socket *sock, struct socket *newsock)
>   
>   int security_socket_sendmsg(struct socket *sock, struct msghdr *msg, int size)
>   {
> -	return security_ops->socket_sendmsg(sock, msg, size);
> +	int ret = 0;
> +
> +	ret = security_ops->socket_sendmsg(sock, msg, size);
> +	if (ret)
> +		goto out;
> +
> +#ifdef CONFIG_SECURITY_DISABLENETWORK
> +	ret = disablenetwork_security_socket_sendmsg(sock, msg, size);
> +	if (ret)
> +		goto out;
> +#endif
> +
> +out:
> +	return ret;
>   }
>   
>   int security_socket_recvmsg(struct socket *sock, struct msghdr *msg,
> -- 
> 1.6.6.rc2
--
To unsubscribe from this list: send the line "unsubscribe netdev" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Pavel Machek Jan. 1, 2010, 2:31 p.m. UTC | #3
> Quoting Michael Stone (michael@laptop.org):
> > Implement security_* hooks for socket_create, socket_bind, socket_connect,
> > socket_sendmsg, and ptrace_access_check which return -EPERM when called from a
> > process with networking restrictions. Exempt AF_UNIX sockets.
> > 
> > Signed-off-by: Michael Stone <michael@laptop.org>
> 
> Acked-by: Serge Hallyn <serue@us.ibm.com>

For the record: NAK, as it introduces security holes.
											Pavel
James Morris Jan. 10, 2010, 9:11 p.m. UTC | #4
On Fri, 1 Jan 2010, Pavel Machek wrote:

> > Quoting Michael Stone (michael@laptop.org):
> > > Implement security_* hooks for socket_create, socket_bind, socket_connect,
> > > socket_sendmsg, and ptrace_access_check which return -EPERM when called from a
> > > process with networking restrictions. Exempt AF_UNIX sockets.
> > > 
> > > Signed-off-by: Michael Stone <michael@laptop.org>
> > 
> > Acked-by: Serge Hallyn <serue@us.ibm.com>
> 
> For the record: NAK, as it introduces security holes.

Please elaborate.
Pavel Machek Jan. 10, 2010, 9:16 p.m. UTC | #5
On Mon 2010-01-11 08:11:55, James Morris wrote:
> On Fri, 1 Jan 2010, Pavel Machek wrote:
> 
> > > Quoting Michael Stone (michael@laptop.org):
> > > > Implement security_* hooks for socket_create, socket_bind, socket_connect,
> > > > socket_sendmsg, and ptrace_access_check which return -EPERM when called from a
> > > > process with networking restrictions. Exempt AF_UNIX sockets.
> > > > 
> > > > Signed-off-by: Michael Stone <michael@laptop.org>
> > > 
> > > Acked-by: Serge Hallyn <serue@us.ibm.com>
> > 
> > For the record: NAK, as it introduces security holes.
> 
> Please elaborate.

See the mailthread.

Allows user to disable suid program's access to network. That bypasses
audit, and will cause system-wide DoS if suid program decides to go
daemon.
									Pavel
James Morris Jan. 10, 2010, 9:44 p.m. UTC | #6
On Sun, 10 Jan 2010, Pavel Machek wrote:

> > > For the record: NAK, as it introduces security holes.
> > 
> > Please elaborate.
> 
> See the mailthread.

Yep, wading through several weeks of it..

> 
> Allows user to disable suid program's access to network. That bypasses
> audit, and will cause system-wide DoS if suid program decides to go
> daemon.

Ok.
Michael Stone Jan. 10, 2010, 9:54 p.m. UTC | #7
On Fri, 1 Jan 2010, Pavel Machek wrote:

> > > Quoting Michael Stone (michael@laptop.org):
> > > > Implement security_* hooks for socket_create, socket_bind, socket_connect,
> > > > socket_sendmsg, and ptrace_access_check which return -EPERM when called from a
> > > > process with networking restrictions. Exempt AF_UNIX sockets.
> > > > 
> > > > Signed-off-by: Michael Stone <michael@laptop.org>
> > > 
> > > Acked-by: Serge Hallyn <serue@us.ibm.com>
> > 
> > For the record: NAK, as it introduces security holes.
> 
> Please elaborate.

Pavel's position is that disablenetwork is likely to permit some attacker
somewhere to deny network access to some setuid app some day in a way that
violates some security policy.

He has mentioned specific concern over scenarios like:

   Alice configures PAM auth to 'fail open' by checking login credentials
   against a restrictive LDAP server and, if the server is unavailable, against
   a very permissive files database.

   Alice updates her kernel to a version with disablenetwork.

   Mallory calls disablenetwork, calls su -, and vanquishes all.

My position is that better isolation facilities like disablenetwork will
prevent far more grievous security faults than they (theoretically) cause.

What is your perspective on the matter?

Regards,

Michael
--
To unsubscribe from this list: send the line "unsubscribe netdev" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Pavel Machek Jan. 10, 2010, 9:58 p.m. UTC | #8
On Sun 2010-01-10 16:54:09, Michael Stone wrote:
> On Fri, 1 Jan 2010, Pavel Machek wrote:
> 
> >> > Quoting Michael Stone (michael@laptop.org):
> >> > > Implement security_* hooks for socket_create, socket_bind, socket_connect,
> >> > > socket_sendmsg, and ptrace_access_check which return -EPERM when called from a
> >> > > process with networking restrictions. Exempt AF_UNIX sockets.
> >> > > > > > Signed-off-by: Michael Stone <michael@laptop.org>
> >> > > > Acked-by: Serge Hallyn <serue@us.ibm.com>
> >> > For the record: NAK, as it introduces security holes.
> >
> >Please elaborate.
> 
> Pavel's position is that disablenetwork is likely to permit some attacker
> somewhere to deny network access to some setuid app some day in a way that
> violates some security policy.
> 
> He has mentioned specific concern over scenarios like:

Make that scenario 1.

>   Alice configures PAM auth to 'fail open' by checking login credentials
>   against a restrictive LDAP server and, if the server is unavailable, against
>   a very permissive files database.

Scenario 2:

Mallory calls disablenetwork, calls sendmail as the first user after
boot; sendmail can't deliver anything (its network is disabled), but
starts forking and taking requests for other users, DoSing the mail
delivery.

Scenario 3:

Mallory calls disablenetwork, then keeps hammering on su, knowing that
su can no longer send data to audit subsystem and so he will not get caught.

> My position is that better isolation facilities like disablenetwork will
> prevent far more grievous security faults than they (theoretically) cause.

You can trivialy make disablenetwork disable setuid exec, too. That
will introduce better isolation facilities, but not introduce any new
security problems.

For some reason, you don't want to do the obviously right thing.
									Pavel
Kyle Moffett Jan. 10, 2010, 10:18 p.m. UTC | #9
On Sun, Jan 10, 2010 at 16:54, Michael Stone <michael@laptop.org> wrote:
> On Fri, 1 Jan 2010, Pavel Machek wrote:
>> > > For the record: NAK, as it introduces security holes.
>>
>> Please elaborate.
>
> Pavel's position is that disablenetwork is likely to permit some attacker
> somewhere to deny network access to some setuid app some day in a way that
> violates some security policy.
>
> He has mentioned specific concern over scenarios like:
>
>  Alice configures PAM auth to 'fail open' by checking login credentials
>  against a restrictive LDAP server and, if the server is unavailable,
> against
>  a very permissive files database.
>
>  Alice updates her kernel to a version with disablenetwork.
>
>  Mallory calls disablenetwork, calls su -, and vanquishes all.

No, there is a *MUCH* bigger security issue here.  There are existing
PAM modules which lazily fork background processes to handle
authentication, authorization, logging, etc.  Now assume that one of
those PAM modules is hooked from /etc/pam.d/su.

(1) Mallory runs "disablenetwork su -"
(2) The PAM module lazily starts its background daemon with a
10-minute idle timeout.
(3) The daemon has network disabled, and so it is completely nonfunctional.
(4) The daemon automatically denies all logins because it cannot
communicate with the login server
(5) Alice tries to run "su -" from her regular terminal.
(6) Alice's "su" process communicates with the running daemon and
fails because "the network is down".

All of that software is perfectly reasonably designed... the daemon is
even fail-secure in the event that the network really is inaccessible.
 Unfortunately it lets Mallory easily DoS every superuser login on the
system without generating a single audit log.  The only process that
knows what he did is the one that cannot communicate with the remote
audit daemon.

Moreover, that DoS would continue until the 10-minute idle timeout
actually expired.  As Alice keeps trying to log in, it will keep
automatically extending the daemon's lifetime.

Now, you can try to claim "Nobody has it configured like that" or
"None of the standard Linux PAM modules do that"... but that does not
resolve the problem.  A sysadmin and part-time programmer (not knowing
about a little-documented "disablenetwork" feature) could very easily
write software like that and assume that it is secure.

The #1 rule for setuid binaries is that you DO NOT INHERIT ANYTHING.
Any kernel feature or setuid program which violates that rule is just
going to cause big security holes.  Security models must be either
obviously correct or mathematically provable (or both)... and this is
neither.

Cheers,
Kyle Moffett
--
To unsubscribe from this list: send the line "unsubscribe netdev" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Michael Stone Jan. 10, 2010, 10:40 p.m. UTC | #10
Pavel Machek wrote:

> You can trivialy make disablenetwork disable setuid exec, too. That
> will introduce better isolation facilities, but not introduce any new
> security problems.
> 
> For some reason, you don't want to do the obviously right thing.

I don't want to do it because it's not "obviously right" to me: I *have* setuid
programs that I want to be able to raise privileges when network-disabled.
I *don't have* any setuid programs that will be harmed by disablenetwork.

Examples of software that I want to be able to gain privileges normally include:

   rainbow, which requires privilege in order to add new accounts to the system
   and in order to call setuid() but which does not require networking
   privileges.

   qmail-queue, which uses setuid to deliver mail that it reads from fd 0 to
   local users

   and other old favorites like mount, fusermount, X, and, presumably, any audio
   software that wants to go realtime.

Kind regards,

Michael
--
To unsubscribe from this list: send the line "unsubscribe netdev" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
James Morris Jan. 10, 2010, 10:58 p.m. UTC | #11
On Sun, 10 Jan 2010, Michael Stone wrote:

> 
> Pavel's position is that disablenetwork is likely to permit some attacker
> somewhere to deny network access to some setuid app some day in a way that
> violates some security policy.
> 
> He has mentioned specific concern over scenarios like:
> 
>   Alice configures PAM auth to 'fail open' by checking login credentials
>   against a restrictive LDAP server and, if the server is unavailable, against
>   a very permissive files database.
> 
>   Alice updates her kernel to a version with disablenetwork.
> 
>   Mallory calls disablenetwork, calls su -, and vanquishes all.
> 
> My position is that better isolation facilities like disablenetwork will
> prevent far more grievous security faults than they (theoretically) cause.
> 
> What is your perspective on the matter?

Unexpected failure modes for privileged apps using security interfaces has 
already proven to be a problem (e.g. the sendmail capabilities bug), so it 
seems prudent to try and mitigate that as well. I don't think we need to 
look at this as an either-or situation -- it seems we can do both, and get 
something useful in its own right from the mitigation.
Michael Stone Jan. 10, 2010, 11:08 p.m. UTC | #12
Paraphrasing Kyle:

> Suppose there exist PAM modules which lazily fork background processes. Now
> assume that one of those PAM modules is hooked from /etc/pam.d/su, that the
> module fails closed when the network is unavailable, and that Mallory wins
> the race to start the daemon. Boom.

I'm not disagreeing that there are configurations of programs, written for
kernels without disablenetwork, which cease to be correct on kernels that
provide it. However, all this says to me is that people who need to use those
configurations probably shouldn't use disablenetwork. (Or that we haven't found
exactly the right semantics for disablenetwork yet.)

Let's keep working on it.

Michael
--
To unsubscribe from this list: send the line "unsubscribe netdev" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Bryan Donlan Jan. 10, 2010, 11:41 p.m. UTC | #13
On Sun, Jan 10, 2010 at 6:08 PM, Michael Stone <michael@laptop.org> wrote:
> Paraphrasing Kyle:
>
>> Suppose there exist PAM modules which lazily fork background processes.
>> Now
>> assume that one of those PAM modules is hooked from /etc/pam.d/su, that
>> the
>> module fails closed when the network is unavailable, and that Mallory wins
>> the race to start the daemon. Boom.
>
> I'm not disagreeing that there are configurations of programs, written for
> kernels without disablenetwork, which cease to be correct on kernels that
> provide it. However, all this says to me is that people who need to use
> those
> configurations probably shouldn't use disablenetwork. (Or that we haven't
> found
> exactly the right semantics for disablenetwork yet.)

With the semantics given, the choice for using disablenetwork is given
to the unprivileged process, not to the administrator or privileged
process, so people using these configurations have no choice - the
malicious local user can just use it anyway.

I still think requiring a drop of suid abilities would be best - if
the suid process wants to run in a no-network environment it can still
disablenetwork itself.
--
To unsubscribe from this list: send the line "unsubscribe netdev" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Tetsuo Handa Jan. 11, 2010, 1:07 a.m. UTC | #14
Michael Stone wrote:
> Examples of software that I want to be able to gain privileges normally include:
> 
>    rainbow, which requires privilege in order to add new accounts to the system
>    and in order to call setuid() but which does not require networking
>    privileges.

If the system is not using local files (i.e. /etc/passwd and /etc/shadow),
the process who wants to add new accounts to the system might need network
access (e.g. to LDAP server), doesn't it?
--
To unsubscribe from this list: send the line "unsubscribe netdev" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Michael Stone Jan. 11, 2010, 1:45 a.m. UTC | #15
Tetsuo Handa wrote:

>Michael Stone wrote:
>> Examples of software that I want to be able to gain privileges normally include:
>> 
>>    rainbow, which requires privilege in order to add new accounts to the system
>>    and in order to call setuid() but which does not require networking
>>    privileges.
>
> If the system is not using local files (i.e. /etc/passwd and /etc/shadow),
> the process who wants to add new accounts to the system might need network
> access (e.g. to LDAP server), doesn't it?

General purpose account manipulation tools might need network access but
rainbow handles all its account manipulations via state stored in
/var/spool/rainbow/2. This state is made available to the rest of the system
via libnss_rainbow.

Michael
--
To unsubscribe from this list: send the line "unsubscribe netdev" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Casey Schaufler Jan. 11, 2010, 1:46 a.m. UTC | #16
Tetsuo Handa wrote:
> Michael Stone wrote:
>   
>> Examples of software that I want to be able to gain privileges normally include:
>>
>>    rainbow, which requires privilege in order to add new accounts to the system
>>    and in order to call setuid() but which does not require networking
>>    privileges.
>>     
>
> If the system is not using local files (i.e. /etc/passwd and /etc/shadow),
> the process who wants to add new accounts to the system might need network
> access (e.g. to LDAP server), doesn't it?
>
>   

It's much worse than that. A user that has been network disabled
who tries using ls may find that it goes looking for the network
on each name lookup and has to wait for a timeout for each. Yet
another example of why Real Users hate security features with
such passion. Then, if there are local file entries that differ
from the "official" network account values when the library
functions finally fall back on the local values you get the wrong
names for file owners. Now we've made ls slow and untrustworthy
in the name of security.


--
To unsubscribe from this list: send the line "unsubscribe netdev" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Casey Schaufler Jan. 11, 2010, 1:50 a.m. UTC | #17
Bryan Donlan wrote:
> On Sun, Jan 10, 2010 at 6:08 PM, Michael Stone <michael@laptop.org> wrote:
>   
>> Paraphrasing Kyle:
>>
>>     
>>> Suppose there exist PAM modules which lazily fork background processes.
>>> Now
>>> assume that one of those PAM modules is hooked from /etc/pam.d/su, that
>>> the
>>> module fails closed when the network is unavailable, and that Mallory wins
>>> the race to start the daemon. Boom.
>>>       
>> I'm not disagreeing that there are configurations of programs, written for
>> kernels without disablenetwork, which cease to be correct on kernels that
>> provide it. However, all this says to me is that people who need to use
>> those
>> configurations probably shouldn't use disablenetwork. (Or that we haven't
>> found
>> exactly the right semantics for disablenetwork yet.)
>>     
>
> With the semantics given, the choice for using disablenetwork is given
> to the unprivileged process, not to the administrator or privileged
> process, so people using these configurations have no choice - the
> malicious local user can just use it anyway.
>
> I still think requiring a drop of suid abilities would be best - if
> the suid process wants to run in a no-network environment it can still
> disablenetwork itself.
>
>   

Stop. If you can count on the program to use the mechanisms you've
described correctly you can count on it to use exec, socket, and
bind correctly. You're only trading one set of behaviors for another.


--
To unsubscribe from this list: send the line "unsubscribe netdev" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Bryan Donlan Jan. 11, 2010, 2:15 a.m. UTC | #18
On Sun, Jan 10, 2010 at 8:50 PM, Casey Schaufler <casey@schaufler-ca.com> wrote:
> Bryan Donlan wrote:
>> On Sun, Jan 10, 2010 at 6:08 PM, Michael Stone <michael@laptop.org> wrote:
>>
>>> Paraphrasing Kyle:
>>>
>>>
>>>> Suppose there exist PAM modules which lazily fork background processes.
>>>> Now
>>>> assume that one of those PAM modules is hooked from /etc/pam.d/su, that
>>>> the
>>>> module fails closed when the network is unavailable, and that Mallory wins
>>>> the race to start the daemon. Boom.
>>>>
>>> I'm not disagreeing that there are configurations of programs, written for
>>> kernels without disablenetwork, which cease to be correct on kernels that
>>> provide it. However, all this says to me is that people who need to use
>>> those
>>> configurations probably shouldn't use disablenetwork. (Or that we haven't
>>> found
>>> exactly the right semantics for disablenetwork yet.)
>>>
>>
>> With the semantics given, the choice for using disablenetwork is given
>> to the unprivileged process, not to the administrator or privileged
>> process, so people using these configurations have no choice - the
>> malicious local user can just use it anyway.
>>
>> I still think requiring a drop of suid abilities would be best - if
>> the suid process wants to run in a no-network environment it can still
>> disablenetwork itself.
>>
>>
>
> Stop. If you can count on the program to use the mechanisms you've
> described correctly you can count on it to use exec, socket, and
> bind correctly. You're only trading one set of behaviors for another.

I don't think there's any argument that a program designed with
disablenetwork in mind will have no problems with disablenetwork
existing. The only concern is when a malicious (or ill-conceived)
program disables network access, then invokes a naive setuid program.

What I meant by the above is is, by my reading Michael suggests that
systems where there are setuid programs that grossly misbehave without
network access should simply not use disablenetwork; however my point
is that there is no such choice available to the administrator. In the
proposed APIs, disablenetwork is always available, and any untrusted
user can push it on all setuid programs in the system.

There were also suggestions of setuid programs that might themselves
want to drop network access; but one can simply have said setuid
program drop network access after it's executed, rather than relying
on the (untrusted anyway!) invoker to do so. So there's no need to
have it set by the caller, and indeed this may be undesirable because
the suid program will need to drop it again _anyway_ since it can't
assume the caller really did drop it. And of course, since this suid
program is asking for its network access to be disabled, it is
presumably prepared to deal with the consequences.

Finally, if there is a need for an untrusted program to invoke a
set-uid program, this can always be emulated by making a request over
a unix domain socket. Since presumably the program that used the
disablenetwork facility is designed around said disablenetwork
facility, it's not much of a burden to expect it use such a facility
in the unlikely case that there's a program that can't be trusted to
use the network, but does need to make some privileged operations.

In short:

* If network access is restored over suid, then we can leak data over
ping or any number of other routes, so that's right out.
* If network access is denied over suid, there are concerns of denial
of service in certain configurations.
* If suid is denied entirely, we have no denial of service or
information leak concerns via the suid mechanism (since the mechanism
is completely unusable). And if we really do need to execute something
at an elevated privilege, we can ask a helper daemon to do it on our
behalf.
--
To unsubscribe from this list: send the line "unsubscribe netdev" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Pavel Machek Jan. 11, 2010, 11:53 a.m. UTC | #19
Hi!

> * If network access is restored over suid, then we can leak data over
> ping or any number of other routes, so that's right out.

ACK.

> * If network access is denied over suid, there are concerns of denial
> of service in certain configurations.

So that should be right out, too.

> * If suid is denied entirely, we have no denial of service or
> information leak concerns via the suid mechanism (since the mechanism
> is completely unusable). And if we really do need to execute something
> at an elevated privilege, we can ask a helper daemon to do it on our
> behalf.

Yes please. This is the obvious solution.
									Pavel
Pavel Machek Jan. 11, 2010, 12:01 p.m. UTC | #20
Hi!

> >You can trivialy make disablenetwork disable setuid exec, too. That
> >will introduce better isolation facilities, but not introduce any new
> >security problems.
> >
> >For some reason, you don't want to do the obviously right thing.
> 
> I don't want to do it because it's not "obviously right" to me: I *have* 
> setuid
> programs that I want to be able to raise privileges when network-disabled.
> I *don't have* any setuid programs that will be harmed by disablenetwork.

Well, I do not have any desire to use disablenetwork, but I do not
want my users to use it and DoS sendmail.

> Examples of software that I want to be able to gain privileges normally 
> include:

You'll have to make sure those are not accessed from the
disablenetworked parts, I'd say. Pre-existing unix domain socket
should be the way to go.

>   rainbow, which requires privilege in order to add new accounts to the 
>   system
>   and in order to call setuid() but which does not require networking
>   privileges.
> 
>   qmail-queue, which uses setuid to deliver mail that it reads from fd 0 to
>   local users
> 
>   and other old favorites like mount, fusermount, X, and, presumably, any 
>   audio
>   software that wants to go realtime.

mount certainly wants network access for NFS.
									Pavel
Serge E. Hallyn Jan. 11, 2010, 5:49 p.m. UTC | #21
Quoting Michael Stone (michael@laptop.org):
> Tetsuo Handa wrote:
> 
> >Michael Stone wrote:
> >>Examples of software that I want to be able to gain privileges normally include:
> >>
> >>   rainbow, which requires privilege in order to add new accounts to the system
> >>   and in order to call setuid() but which does not require networking
> >>   privileges.
> >
> >If the system is not using local files (i.e. /etc/passwd and /etc/shadow),
> >the process who wants to add new accounts to the system might need network
> >access (e.g. to LDAP server), doesn't it?
> 
> General purpose account manipulation tools might need network access but
> rainbow handles all its account manipulations via state stored in
> /var/spool/rainbow/2. This state is made available to the rest of the system
> via libnss_rainbow.
> 
> Michael

Michael, I'm sorry, I should go back and search the thread for the
answer, but don't have time right now - do you really need
disablenetwork to be available to unprivileged users?  Or is it ok
to require CAP_SETPCAP (same thing required for dropping privs from
bounding set)?  Surely rainbow could be started either with that
capability, or even from a smaller, easier-to-audit wrapper that
has the capability, calls disablenetwork, then launches rainbow?

-serge
--
To unsubscribe from this list: send the line "unsubscribe netdev" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Valdis Kl ē tnieks Jan. 12, 2010, 2:54 a.m. UTC | #22
On Sun, 10 Jan 2010 22:58:48 +0100, Pavel Machek said:

> Scenario 2:
> 
> Mallory calls disablenetwork, calls sendmail as the first user after
> boot; sendmail can't deliver anything (its network is disabled), but
> starts forking and taking requests for other users, DoSing the mail
> delivery.

You need to be root to start sendmail as a daemon.  If Mallory is getting
a root shell before your /etc/rc.d scripts have started sendmail, you
have bigger problems.

> Scenario 3:
> 
> Mallory calls disablenetwork, then keeps hammering on su, knowing that
> su can no longer send data to audit subsystem and so he will not get caught.

I assume you mean syslog, not audit.  And it still won't work.

% strace /usr/bin/logger test message
...
socket(PF_FILE, SOCK_DGRAM|SOCK_CLOEXEC, 0) = 1
connect(1, {sa_family=AF_FILE, path="/dev/log"}, 110) = 0
sendto(1, "<13>Jan 11 21:49:25 logger: test"..., 40, MSG_NOSIGNAL, NULL, 0) = 40
close(1)                                = 0

su's complaint will get written to /dev/log which isn't interfered with
by the disablenetwork patch - and then syslogd will forward over the net
if configured to do so.
Valdis Kl ē tnieks Jan. 12, 2010, 3:19 a.m. UTC | #23
On Sun, 10 Jan 2010 17:46:49 PST, Casey Schaufler said:
> It's much worse than that. A user that has been network disabled
> who tries using ls may find that it goes looking for the network
> on each name lookup and has to wait for a timeout for each.

Ya know Casey - I learned back in 1986 or so that if you set up a SunOS 3.2
cluster using Yellow Pages, professors who managed to unplug the AUI cable
on the back of their Sun 3/50 would notice things blowing chunks.  I have to
admit that 24 years ago I told them "Well don't do that then", and I have
to say the same thing for anybody running a login shell network-disabled.

Now, a more subtle point is that a *program* may call getuserbyname() or
getuserbyuid() and be surprised when it times out - but that's a
different issue than a network-deprived user calling /bin/ls.

>          Then, if there are local file entries that differ
> from the "official" network account values when the library
> functions finally fall back on the local values you get the wrong
> names for file owners.

The sysadmin who set that up already had the bullet in the chamber and
the gun pointed at their feet.  This is another "we knew better a quarter
century ago" issue - SunOS allowed '+:' at the end of /etc/passwd to merge
in the YP database, and Sun actively discouraged the sort of "local userid
overlaps the YP userid space" misconfiguration you mention.
Casey Schaufler Jan. 12, 2010, 4:01 a.m. UTC | #24
Valdis.Kletnieks@vt.edu wrote:
> On Sun, 10 Jan 2010 17:46:49 PST, Casey Schaufler said:
>   
>> It's much worse than that. A user that has been network disabled
>> who tries using ls may find that it goes looking for the network
>> on each name lookup and has to wait for a timeout for each.
>>     
>
> Ya know Casey - I learned back in 1986 or so that if you set up a SunOS 3.2
> cluster using Yellow Pages, professors who managed to unplug the AUI cable
> on the back of their Sun 3/50 would notice things blowing chunks.  I have to
> admit that 24 years ago I told them "Well don't do that then", and I have
> to say the same thing for anybody running a login shell network-disabled.
>
> Now, a more subtle point is that a *program* may call getuserbyname() or
> getuserbyuid() and be surprised when it times out - but that's a
> different issue than a network-deprived user calling /bin/ls.
>   

I was working at Sun when YP was introduced and was probably the
first person who had to explain what would happen if the network
got disconnected to "security experts". They weren't real happy
then, and shouldn't be happier now. If anything, today's computer
users are less well adapted to dealing with applications that
behave differently when the network is unexpectedly absent because
both the user and the programmer assume that the network will be
there because it always is. They would never set up a situation
where the network would be missing and the programs they use/write
are unlikely to handle the situation. Lazy kids.

>>          Then, if there are local file entries that differ
>> from the "official" network account values when the library
>> functions finally fall back on the local values you get the wrong
>> names for file owners.
>>     
>
> The sysadmin who set that up already had the bullet in the chamber and
> the gun pointed at their feet.  This is another "we knew better a quarter
> century ago" issue - SunOS allowed '+:' at the end of /etc/passwd to merge
> in the YP database, and Sun actively discouraged the sort of "local userid
> overlaps the YP userid space" misconfiguration you mention.
>
>   

Sysadmins are so busy fixing Sanborn-Oxley compliance issues (funded)
that they are perfectly happy to put loaded guns in their pants as far
as (unfunded) "real" security is concerned. Sure we knew better. We
knew how to do lots of things back then that the Linux community is
relearning today. Knowing better isn't going to help the current
generation, as wisdom (like you and I have) can only be passed along
by experience and exposure to the wise. I like secure systems myself,
but I certainly understand why so many people don't.

--
To unsubscribe from this list: send the line "unsubscribe netdev" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Michael Stone Jan. 12, 2010, 6:10 a.m. UTC | #25
Serge Hallyn wrote:
> Michael, I'm sorry, I should go back and search the thread for the
> answer, but don't have time right now - do you really need
> disablenetwork to be available to unprivileged users? 

Rainbow can only drop the networking privileges when we know at app launch time
(e.g. based on a manifest or from the human operator) that privileges can be
dropped. Unfortunately, most of the really interesting uses of disablenetwork
happen *after* rainbow has dropped privilege and handed control the app.
Therefore, having an API which can be used by at least some low-privilege
processes is important to me.

> is it ok to require CAP_SETPCAP (same thing required for dropping privs from
> bounding set)?  

Let me try to restate your idea:

   We can make disablenetwork safer by permitting its use only where explicitly
   permitted by some previously privileged ancestor. The securebits facility
   described in 

     http://lwn.net/Articles/280279/

   may be a good framework in which to implement this control.

Did I understand correctly? If so, then yes, this approach seems like it would
work for me.

Regards, and thanks very much for your help,

Michael
--
To unsubscribe from this list: send the line "unsubscribe netdev" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Pavel Machek Jan. 12, 2010, 7:59 a.m. UTC | #26
> On Sun, 10 Jan 2010 22:58:48 +0100, Pavel Machek said:
> 
> > Scenario 2:
> > 
> > Mallory calls disablenetwork, calls sendmail as the first user after
> > boot; sendmail can't deliver anything (its network is disabled), but
> > starts forking and taking requests for other users, DoSing the mail
> > delivery.
> 
> You need to be root to start sendmail as a daemon.

Well, maybe, but mailer system where first user starts is as a daemon
makes sense... same for authentication system, etc. And it was okay
before disablenetwork come.
									Pavel
Valdis Kl ē tnieks Jan. 12, 2010, 2:28 p.m. UTC | #27
On Tue, 12 Jan 2010 08:59:27 +0100, Pavel Machek said:

> Well, maybe, but mailer system where first user starts is as a daemon
> makes sense...

Does it?  How do you get port 25 open for listening if the first user isn't
root?  Most *actual* schemes to "launch at first use" that require privs for
something have used inetd or similar - that program exists for a *reason*.
Serge E. Hallyn Jan. 12, 2010, 3:52 p.m. UTC | #28
Quoting Michael Stone (michael@laptop.org):
> Serge Hallyn wrote:
> >Michael, I'm sorry, I should go back and search the thread for the
> >answer, but don't have time right now - do you really need
> >disablenetwork to be available to unprivileged users?
> 
> Rainbow can only drop the networking privileges when we know at app launch time
> (e.g. based on a manifest or from the human operator) that privileges can be
> dropped. Unfortunately, most of the really interesting uses of disablenetwork
> happen *after* rainbow has dropped privilege and handed control the app.
> Therefore, having an API which can be used by at least some low-privilege
> processes is important to me.
> 
> >is it ok to require CAP_SETPCAP (same thing required for dropping privs from
> >bounding set)?
> 
> Let me try to restate your idea:
> 
>   We can make disablenetwork safer by permitting its use only where explicitly
>   permitted by some previously privileged ancestor. The securebits facility
>   described in
> 
>     http://lwn.net/Articles/280279/
> 
>   may be a good framework in which to implement this control.
> 
> Did I understand correctly? If so, then yes, this approach seems like it would
> work for me.

That is a little more than I was saying this time though I think I
suggested it earlier.

But really I don't think anyone would care to separate a system into
some processes allowed to do unprivileged disablenetwork and other
processes not allowed to, so a (root-owned mode 644) sysctl seems just
as useful.

> Regards, and thanks very much for your help,
> 
> Michael
> --
> To unsubscribe from this list: send the line "unsubscribe linux-security-module" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html
--
To unsubscribe from this list: send the line "unsubscribe netdev" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Pavel Machek Jan. 14, 2010, 9:22 a.m. UTC | #29
> On Tue, 12 Jan 2010 08:59:27 +0100, Pavel Machek said:
> 
> > Well, maybe, but mailer system where first user starts is as a daemon
> > makes sense...
> 
> Does it?  How do you get port 25 open for listening if the first user isn't
> root?  Most *actual* schemes to "launch at first use" that require privs for
> something have used inetd or similar - that program exists for a
> *reason*.

Remember sendmail is setuid root... so it already has the permissions.

Except that proposed disablenetwork would take network connectivity
even from setuid apps.
									Pavel
Pavel Machek Jan. 14, 2010, 9:23 a.m. UTC | #30
> Quoting Michael Stone (michael@laptop.org):
> > Serge Hallyn wrote:
> > >Michael, I'm sorry, I should go back and search the thread for the
> > >answer, but don't have time right now - do you really need
> > >disablenetwork to be available to unprivileged users?
> > 
> > Rainbow can only drop the networking privileges when we know at app launch time
> > (e.g. based on a manifest or from the human operator) that privileges can be
> > dropped. Unfortunately, most of the really interesting uses of disablenetwork
> > happen *after* rainbow has dropped privilege and handed control the app.
> > Therefore, having an API which can be used by at least some low-privilege
> > processes is important to me.
> > 
> > >is it ok to require CAP_SETPCAP (same thing required for dropping privs from
> > >bounding set)?
> > 
> > Let me try to restate your idea:
> > 
> >   We can make disablenetwork safer by permitting its use only where explicitly
> >   permitted by some previously privileged ancestor. The securebits facility
> >   described in
> > 
> >     http://lwn.net/Articles/280279/
> > 
> >   may be a good framework in which to implement this control.
> > 
> > Did I understand correctly? If so, then yes, this approach seems like it would
> > work for me.
> 
> That is a little more than I was saying this time though I think I
> suggested it earlier.
> 
> But really I don't think anyone would care to separate a system into
> some processes allowed to do unprivileged disablenetwork and other
> processes not allowed to, so a (root-owned mode 644) sysctl seems just
> as useful.

Global solution like that is always wrong. (And we have better
solution available.)
									Pavel
Serge E. Hallyn Jan. 14, 2010, 3 p.m. UTC | #31
Quoting Pavel Machek (pavel@ucw.cz):
> > Quoting Michael Stone (michael@laptop.org):
> > > Serge Hallyn wrote:
> > > >Michael, I'm sorry, I should go back and search the thread for the
> > > >answer, but don't have time right now - do you really need
> > > >disablenetwork to be available to unprivileged users?
> > > 
> > > Rainbow can only drop the networking privileges when we know at app launch time
> > > (e.g. based on a manifest or from the human operator) that privileges can be
> > > dropped. Unfortunately, most of the really interesting uses of disablenetwork
> > > happen *after* rainbow has dropped privilege and handed control the app.
> > > Therefore, having an API which can be used by at least some low-privilege
> > > processes is important to me.
> > > 
> > > >is it ok to require CAP_SETPCAP (same thing required for dropping privs from
> > > >bounding set)?
> > > 
> > > Let me try to restate your idea:
> > > 
> > >   We can make disablenetwork safer by permitting its use only where explicitly
> > >   permitted by some previously privileged ancestor. The securebits facility
> > >   described in
> > > 
> > >     http://lwn.net/Articles/280279/
> > > 
> > >   may be a good framework in which to implement this control.
> > > 
> > > Did I understand correctly? If so, then yes, this approach seems like it would
> > > work for me.
> > 
> > That is a little more than I was saying this time though I think I
> > suggested it earlier.
> > 
> > But really I don't think anyone would care to separate a system into
> > some processes allowed to do unprivileged disablenetwork and other
> > processes not allowed to, so a (root-owned mode 644) sysctl seems just
> > as useful.
> 
> Global solution like that is always wrong. (And we have better
> solution available.)

All right, so Michael suggested securebits, I personally feel prctl would
be more appropriate, but in any case the suggestion then is:

foo_enable_disablenet() is either prctl(PR_ALLOW_DISABLENET) or
prctl(PR_SET_SECUREBITS, (1 << PR_ALLOW_DISABLENET) | (1 << PR_ALLOW_DISABLENET_LOCK))
and it requires privilege (CAP_NET_ADMIN presumably) to make this call.

prctl(PR_SET_DISABLENETWORK), or whatever Michael was using, does not
require privilege, but requires that foo_enable_disablenet() have been
previously called by a privileged app.

-serge
--
To unsubscribe from this list: send the line "unsubscribe netdev" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Michael Stone Jan. 14, 2010, 4:36 p.m. UTC | #32
> Quoting Pavel Machek (pavel@ucw.cz):
> > > Quoting Michael Stone (michael@laptop.org):
> > > > Serge Hallyn wrote:
> > > > >Michael, I'm sorry, I should go back and search the thread for the
> > > > >answer, but don't have time right now - do you really need
> > > > >disablenetwork to be available to unprivileged users?
> > > > 
> > > > Rainbow can only drop the networking privileges when we know at app launch time
> > > > (e.g. based on a manifest or from the human operator) that privileges can be
> > > > dropped. Unfortunately, most of the really interesting uses of disablenetwork
> > > > happen *after* rainbow has dropped privilege and handed control the app.
> > > > Therefore, having an API which can be used by at least some low-privilege
> > > > processes is important to me.
> > > > 
> > > > >is it ok to require CAP_SETPCAP (same thing required for dropping privs from
> > > > >bounding set)?
> > > > 
> > > > Let me try to restate your idea:
> > > > 
> > > >   We can make disablenetwork safer by permitting its use only where explicitly
> > > >   permitted by some previously privileged ancestor. The securebits facility
> > > >   described in
> > > > 
> > > >     http://lwn.net/Articles/280279/
> > > > 
> > > >   may be a good framework in which to implement this control.
> > > > 
> > > > Did I understand correctly? If so, then yes, this approach seems like it would
> > > > work for me.
> > > 
> > > That is a little more than I was saying this time though I think I
> > > suggested it earlier.
> > > 
> > > But really I don't think anyone would care to separate a system into
> > > some processes allowed to do unprivileged disablenetwork and other
> > > processes not allowed to, so a (root-owned mode 644) sysctl seems just
> > > as useful.
> > 
> > Global solution like that is always wrong. (And we have better
> > solution available.)
> 
> All right, so Michael suggested securebits, I personally feel prctl would
> be more appropriate.

I'm happy with either approach so I'll prepare patches based on Serge's
suggestion first.

Regards,

Michael
--
To unsubscribe from this list: send the line "unsubscribe netdev" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Serge E. Hallyn Jan. 14, 2010, 4:47 p.m. UTC | #33
Quoting Michael Stone (michael@laptop.org):
> >Quoting Pavel Machek (pavel@ucw.cz):
> >> > Quoting Michael Stone (michael@laptop.org):
> >> > > Serge Hallyn wrote:
> >> > > >Michael, I'm sorry, I should go back and search the thread for the
> >> > > >answer, but don't have time right now - do you really need
> >> > > >disablenetwork to be available to unprivileged users?
> >> > > > > > Rainbow can only drop the networking privileges when
> >we know at app launch time
> >> > > (e.g. based on a manifest or from the human operator) that privileges can be
> >> > > dropped. Unfortunately, most of the really interesting uses of disablenetwork
> >> > > happen *after* rainbow has dropped privilege and handed control the app.
> >> > > Therefore, having an API which can be used by at least some low-privilege
> >> > > processes is important to me.
> >> > > > > > >is it ok to require CAP_SETPCAP (same thing required
> >for dropping privs from
> >> > > >bounding set)?
> >> > > > > > Let me try to restate your idea:
> >> > > > > >   We can make disablenetwork safer by permitting its
> >use only where explicitly
> >> > >   permitted by some previously privileged ancestor. The securebits facility
> >> > >   described in
> >> > > > > >     http://lwn.net/Articles/280279/
> >> > > > > >   may be a good framework in which to implement this
> >control.
> >> > > > > > Did I understand correctly? If so, then yes, this
> >approach seems like it would
> >> > > work for me.
> >> > > > That is a little more than I was saying this time though I
> >think I
> >> > suggested it earlier.
> >> > > > But really I don't think anyone would care to separate a
> >system into
> >> > some processes allowed to do unprivileged disablenetwork and other
> >> > processes not allowed to, so a (root-owned mode 644) sysctl seems just
> >> > as useful.
> >> > Global solution like that is always wrong. (And we have better
> >> solution available.)
> >
> >All right, so Michael suggested securebits, I personally feel prctl would
> >be more appropriate.
> 
> I'm happy with either approach so I'll prepare patches based on Serge's
> suggestion first.

Ah - but I worry that if you do that Alan or others will object.  Where do
you plan to store the disablenet_allowed bit?  You can use security_prctl()
to keep the code out of sys_prctl(), but you still have the question of
whether you add a bit to the task struct, use task->security and not stack
with selinux, use a thread flag, or try to enable stacking of task->security.

To me securebits are all about capability hacks, but their name is more
generic than that :), so maybe they are appropriate after all.  Andrew Morgan,
would you object to using securebits to store the fact that a privileged
process has said "from now on an unprivileged process may call disablenetwork"?

-serge
--
To unsubscribe from this list: send the line "unsubscribe netdev" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Serge E. Hallyn Jan. 14, 2010, 5:36 p.m. UTC | #34
Quoting Michael Stone (michael@laptop.org):
> Quoting Michael Stone (michael@laptop.org):
> 
> >Ah - but I worry that if you do that Alan or others will object.  Where do
> >you plan to store the disablenet_allowed bit?
> 
> If using prctl directly, I would store the bit in the task->network bitfield
> introduced by the earlier patches.
> 
> >You can use security_prctl() to keep the code out of sys_prctl().
> 
> I don't understand this suggestion; can you clarify? (Also, for what it's
> worth: I intended to put the check for CAP_SETPCAP in prctl_set_network().)
> 
> >but you still have the question of whether you add a bit to the task struct,
> >use task->security and not stack with selinux, use a thread flag, or try to
> >enable stacking of task->security.
> 
> For this revision of the patch, I will use the same approach as the previous
> patches (conditionally compiled task->network).
> 
> Michael
> 
> P.S. - Patches to follow tonight or tomorrow.

Cool I'll just wait for the patches  :)

thanks,
-serge
--
To unsubscribe from this list: send the line "unsubscribe netdev" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Michael Stone Jan. 15, 2010, 8:10 a.m. UTC | #35
As promised, here are patches implementing and documenting a CAP_SETPCAP-gated
"enable" bit along with a couple of other tweaks discussed earlier in the
thread. For ease of development and review, the following four patches extend
the disablenetwork (v4) patch series rather than replacing it. 

Enjoy,

Michael
--
To unsubscribe from this list: send the line "unsubscribe netdev" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Kyle Moffett Jan. 17, 2010, 6:01 a.m. UTC | #36
On Fri, Jan 15, 2010 at 03:10, Michael Stone <michael@laptop.org> wrote:
> As promised, here are patches implementing and documenting a CAP_SETPCAP-gated
> "enable" bit along with a couple of other tweaks discussed earlier in the
> thread. For ease of development and review, the following four patches
> extend the disablenetwork (v4) patch series rather than replacing it.

To be honest, I'm still not convinced that this is the right way to
approach your problem.  I think you would be much better off with
something analogous to the stripped-down SELinux policy I sent in an
earlier email (150 lines, give or take).  By using the appropriate
SELinux hooks you can obtain the *exact* same enforcement, but without
adding any code to the kernel.

I have some time this week to split out my SELinux policy build
machinery; I will pull out a standalone set of files to build the
policy and do some extra testing on one of my bog-standard Debian
boxes and then send it all out again.

Cheers,
Kyle Moffett
--
To unsubscribe from this list: send the line "unsubscribe netdev" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Kyle Moffett Jan. 17, 2010, 9:17 p.m. UTC | #37
On Sun, Jan 17, 2010 at 13:07, Michael Stone <michael@laptop.org> wrote:
> Kyle Moffett wrote:
>> I have some time this week to split out my SELinux policy build
>> machinery; I will pull out a standalone set of files to build the
>> policy and do some extra testing on one of my bog-standard Debian
>> boxes and then send it all out again.
>
> Questions:
>
>  1) Your patch seems to rely on a chunk of custom policy. Can this chunk of
>     policy coexist without modification with pre-existing policies like the
>     ones Fedora ships?
>
>     If I understand correctly, the answer is "not as it is written today", for
>     a couple of reasons:

Essentially, yes, the policy that I gave is an extremely limited
system.  If you wanted to constrain your application as installed on a
standard Fedora system, that would involve getting a much more
detailed policy merged in the selinux-refpolicy project.  The plusses
are that such a policy would protect against far more complex attacks
than simple network data exposure, however the policy to protect
against such attacks is far more complex as well.

Basically, I wrote that sample policy as a completely standalone
example of how to use the SELinux machinery to enforce a limited
arbitrary set of restrictions based on your stated requirements.

There has been some partially-stalled work to create a "userspace
policy server" and "hierarchical policy", essentially a mechanism by
which a program (running under a specific type) could sub-divide
itself into additional types bounded by the constraints on the
original type.  Unfortunately I haven't had a chance to look into it
in quite a while, so things may have changed significantly.


>  2) How can an application author test whether or not the contexts defined by
>     this policy are defined in the currently loaded policy?

The standard method for adding SELinux support to an application is
pretty much the same method that you use to enhance security in the
absence of SELinux:  Divide your program into multiple executables
with discrete DAC-enforced privileges (a la postfix).

Then the SELinux policy simply places a different label on each
executable (and via a type_transition rule on the process which is
*started* from that executable).  Each label is then neatly bound by
least-privilege type-based allow rules.


>  3) Your policy relies on defining new roles for objects, regular processes,
>     and network disabled processes. This is definitely a nice reuse of SELinux
>     machinery. Unfortunately, I'm not sure how, as an app author, I'm supposed
>     to use it.
>
> [...code for using dyntransition...]

You can do it that way, although I would certainly suggest an
appropriate config file somewhere to specify what label the software
should attempt to transition to.  The SELinux libraries have some code
for performing dynamic transitions, although as I indicated most
processes don't use them.

Really the preferred way to take advantage of SELinux is simply to
divide the program tasks securely across multiple executables and then
use the SELinux policy to lock them down individually.


>  4) If I understand correctly, the policy you specified actually restricts
>     network access by blacklisting various socket calls by protocol stack.
>     Thus, AF_UNIX socket calls are unrestricted while TCP bind() and connect()
>     and UDP bind(), connect(), and sendto() are restricted.
>
>     I'm uncomfortable with a design based on protocol blacklisting because I
>     think that it is likely to break silently whenever someone adds a new
>     protocol (e.g. SCTP) to the kernel.
>
>     Presumably, though, this is fairly straightforward to fix?

Yes, it's pretty easy to change specifically which access-vectors you
restrict.  If localhost-based accesses are OK, then you could use the
netif and peer-based access controls (possibly with a couple of
optional iptables rules).  That would simply restrict your ability to
send packets out of the computer, regardless of what protocol they
use.

Alternatively there are SELinux mechanisms in recent kernels to
influence whether or not "unknown" access-vectors are allowed (IE:
Those which the kernel understands but the policy does not).

>  5) If I understand correctly, your policy restricts all uses of sendto()
>     including sendto() on previously connected UDP sockets. Unfortunately,
>     this restriction is too strong: the ability to sendto() on previously
>     connected sockets UDP is a design goal.
>     How might we address this problem?

See above, simply restrict with network peer controls.


>  6) Can SELinux be turned on at all on kernels which do not support POSIX
>     extended attributes?

My understanding is that the kernel always supported extended
attributes, but that some filesystems may have support turned off.
You can certainly turn on SELinux on such a system, but you would be
unable to label things on a per-file basis.


>  7) Can you point me toward any measurements on what it costs (specifically in
>     terms of memory and disk usage) to add basic SELinux support plus this
>     policy to an embedded kernel and OS distro which doesn't presently ship
>     any SELinux-related material like, e.g., the distros for the Linksys
>     WRT54G and for the XO?

I don't have such measurements offhand.  If you are shipping a
pre-built policy and do not include any of the tools needed to reload
or modify it then all you really need is an /sbin/init which can mount
/selinux and copy a binary policy file to a virtual file therein.  The
actual dev tools are rather unfortunately large and slow right now,
especially with the full reference policy.

Cheers,
Kyle Moffett
--
To unsubscribe from this list: send the line "unsubscribe netdev" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Valdis Kl ē tnieks Jan. 18, 2010, 12:54 p.m. UTC | #38
On Thu, 14 Jan 2010 10:22:51 +0100, Pavel Machek said:
> > On Tue, 12 Jan 2010 08:59:27 +0100, Pavel Machek said:
> > 
> > > Well, maybe, but mailer system where first user starts is as a daemon
> > > makes sense...
> > 
> > Does it?  How do you get port 25 open for listening if the first user isn't
> > root?  Most *actual* schemes to "launch at first use" that require privs fo
r
> > something have used inetd or similar - that program exists for a
> > *reason*.
> 
> Remember sendmail is setuid root... so it already has the permissions.

Actually, the sendmail setuid bit was removed quite some time ago:

8.12.0/8.12.0   2001/09/08
        *NOTICE*: The default installation of sendmail does not use
                set-user-ID root anymore.  You need to create a new user and
                a new group before installing sendmail (both called smmsp by
                default).  The installation process tries to install
                /etc/mail/submit.cf and creates /var/spool/clientmqueue by
                default.  Please see sendmail/SECURITY for details.

Wow.  2001. And people *still* think it's setuid. ;)

(Interestingly enough, the capabilities bug came *later*:

8.12.1/8.12.1   2001/10/01
        SECURITY: Check whether dropping group privileges actually succeeded
                to avoid possible compromises of the mail system by
                supplying bogus data.  Add configuration options for
                different set*gid() calls to reset saved gid.  Problem
                found by Michal Zalewski.

and was mostly an issue because the same problem existed in pre-8.12 sendmails
that were still setuid and hadn't upgraded yet...
Andrew G. Morgan Jan. 18, 2010, 3:56 p.m. UTC | #39
On Mon, Jan 18, 2010 at 4:54 AM,  <Valdis.Kletnieks@vt.edu> wrote:
> (Interestingly enough, the capabilities bug came *later*:
>
> 8.12.1/8.12.1   2001/10/01
>        SECURITY: Check whether dropping group privileges actually succeeded
>                to avoid possible compromises of the mail system by
>                supplying bogus data.  Add configuration options for
>                different set*gid() calls to reset saved gid.  Problem
>                found by Michal Zalewski.
>
> and was mostly an issue because the same problem existed in pre-8.12 sendmails
> that were still setuid and hadn't upgraded yet...
>
>

I think the above was 'a' sendmail bug. 'The' capabilities bug came before that:

http://userweb.kernel.org/~morgan/sendmail-capabilities-war-story.html

Cheers

Andrew
--
To unsubscribe from this list: send the line "unsubscribe netdev" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
diff mbox

Patch

diff --git a/include/linux/disablenetwork.h b/include/linux/disablenetwork.h
new file mode 100644
index 0000000..8a7bcc2
--- /dev/null
+++ b/include/linux/disablenetwork.h
@@ -0,0 +1,22 @@ 
+#ifndef __LINUX_DISABLENETWORK_H
+#define __LINUX_DISABLENETWORK_H
+
+#ifdef CONFIG_SECURITY_DISABLENETWORK
+
+int disablenetwork_security_socket_create(int family, int type,
+					  int protocol, int kern);
+int disablenetwork_security_socket_bind(struct socket *sock,
+				        struct sockaddr *address,
+				        int addrlen);
+int disablenetwork_security_socket_connect(struct socket *sock,
+				           struct sockaddr *address,
+					   int addrlen);
+int disablenetwork_security_socket_sendmsg(struct socket *sock,
+					   struct msghdr *msg,
+					   int size);
+int disablenetwork_security_ptrace_access_check(struct task_struct *child,
+					        unsigned int mode);
+
+#endif /* CONFIG_SECURITY_DISABLENETWORK */
+
+#endif /* ! __LINUX_DISABLENETWORK_H */
diff --git a/security/Makefile b/security/Makefile
index da20a19..2f23b60 100644
--- a/security/Makefile
+++ b/security/Makefile
@@ -20,6 +20,7 @@  obj-$(CONFIG_SECURITY_SMACK)		+= smack/built-in.o
  obj-$(CONFIG_AUDIT)			+= lsm_audit.o
  obj-$(CONFIG_SECURITY_TOMOYO)		+= tomoyo/built-in.o
  obj-$(CONFIG_CGROUP_DEVICE)		+= device_cgroup.o
+obj-$(CONFIG_SECURITY_DISABLENETWORK)	+= disablenetwork.o
  
  # Object integrity file lists
  subdir-$(CONFIG_IMA)			+= integrity/ima
diff --git a/security/disablenetwork.c b/security/disablenetwork.c
new file mode 100644
index 0000000..f45ddfc
--- /dev/null
+++ b/security/disablenetwork.c
@@ -0,0 +1,73 @@ 
+/*
+ * disablenetwork security hooks.
+ *
+ * Copyright (C) 2008-2009 Michael Stone <michael@laptop.org>
+ *
+ * Implements the disablenetwork discretionary access control logic underlying
+ * the prctl(PRCTL_SET_NETWORK, PR_NETWORK_OFF) interface.
+ *
+ * See Documentation/disablenetwork.txt for more information.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation, version 2 of the
+ * License.
+ */
+
+#include <linux/errno.h>
+#include <linux/sched.h>
+#include <net/sock.h>
+#include <linux/socket.h>
+#include <linux/disablenetwork.h>
+
+static inline int maybe_allow(void)
+{
+	if (current->network)
+		return -EPERM;
+	return 0;
+}
+
+int disablenetwork_security_socket_create(int family, int type,
+					  int protocol, int kern)
+{
+	if (family == AF_UNIX)
+		return 0;
+	return maybe_allow();
+}
+
+int disablenetwork_security_socket_bind(struct socket * sock,
+					struct sockaddr * address,
+					int addrlen)
+{
+	if (address->sa_family == AF_UNIX)
+		return 0;
+	return maybe_allow();
+}
+
+int disablenetwork_security_socket_connect(struct socket * sock,
+					   struct sockaddr * address,
+					   int addrlen)
+{
+	if (address->sa_family == AF_UNIX)
+		return 0;
+	return maybe_allow();
+}
+
+int disablenetwork_security_socket_sendmsg(struct socket * sock,
+					   struct msghdr * msg, int size)
+{
+	if (sock->sk->sk_family != PF_UNIX &&
+		current->network &&
+		(msg->msg_name != NULL || msg->msg_namelen != 0))
+		return -EPERM;
+	return 0;
+}
+
+int disablenetwork_security_ptrace_access_check(struct task_struct *child,
+                                                unsigned int mode)
+{
+	/* does current have networking restrictions not shared by child? */
+	if (current->network & ~child->network)
+		return -EPERM;
+	return 0;
+}
diff --git a/security/security.c b/security/security.c
index 24e060b..40ac615 100644
--- a/security/security.c
+++ b/security/security.c
@@ -17,6 +17,7 @@ 
  #include <linux/kernel.h>
  #include <linux/security.h>
  #include <linux/ima.h>
+#include <linux/disablenetwork.h>
  
  /* Boot-time LSM user choice */
  static __initdata char chosen_lsm[SECURITY_NAME_MAX + 1] =
@@ -130,7 +131,20 @@  int register_security(struct security_operations *ops)
  
  int security_ptrace_access_check(struct task_struct *child, unsigned int mode)
  {
-	return security_ops->ptrace_access_check(child, mode);
+	int ret = 0;
+
+	ret = security_ops->ptrace_access_check(child, mode);
+	if (ret)
+		goto out;
+
+#ifdef CONFIG_SECURITY_DISABLENETWORK
+	ret = disablenetwork_security_ptrace_access_check(child, mode);
+	if (ret)
+		goto out;
+#endif
+
+out:
+	return ret;
  }
  
  int security_ptrace_traceme(struct task_struct *parent)
@@ -1054,7 +1068,20 @@  EXPORT_SYMBOL(security_unix_may_send);
  
  int security_socket_create(int family, int type, int protocol, int kern)
  {
-	return security_ops->socket_create(family, type, protocol, kern);
+	int ret = 0;
+
+	ret = security_ops->socket_create(family, type, protocol, kern);
+	if (ret)
+		goto out;
+
+#ifdef CONFIG_SECURITY_DISABLENETWORK
+	ret = disablenetwork_security_socket_create(family, type, protocol, kern);
+	if (ret)
+		goto out;
+#endif
+
+out:
+	return ret;
  }
  
  int security_socket_post_create(struct socket *sock, int family,
@@ -1066,12 +1093,38 @@  int security_socket_post_create(struct socket *sock, int family,
  
  int security_socket_bind(struct socket *sock, struct sockaddr *address, int addrlen)
  {
-	return security_ops->socket_bind(sock, address, addrlen);
+	int ret = 0;
+
+	ret = security_ops->socket_bind(sock, address, addrlen);
+	if (ret)
+		goto out;
+
+#ifdef CONFIG_SECURITY_DISABLENETWORK
+	ret = disablenetwork_security_socket_bind(sock, address, addrlen);
+	if (ret)
+		goto out;
+#endif
+
+out:
+	return ret;
  }
  
  int security_socket_connect(struct socket *sock, struct sockaddr *address, int addrlen)
  {
-	return security_ops->socket_connect(sock, address, addrlen);
+	int ret = 0;
+
+	ret = security_ops->socket_connect(sock, address, addrlen);
+	if (ret)
+		goto out;
+
+#ifdef CONFIG_SECURITY_DISABLENETWORK
+	ret = disablenetwork_security_socket_connect(sock, address, addrlen);
+	if (ret)
+		goto out;
+#endif
+
+out:
+	return ret;
  }
  
  int security_socket_listen(struct socket *sock, int backlog)
@@ -1086,7 +1139,20 @@  int security_socket_accept(struct socket *sock, struct socket *newsock)
  
  int security_socket_sendmsg(struct socket *sock, struct msghdr *msg, int size)
  {
-	return security_ops->socket_sendmsg(sock, msg, size);
+	int ret = 0;
+
+	ret = security_ops->socket_sendmsg(sock, msg, size);
+	if (ret)
+		goto out;
+
+#ifdef CONFIG_SECURITY_DISABLENETWORK
+	ret = disablenetwork_security_socket_sendmsg(sock, msg, size);
+	if (ret)
+		goto out;
+#endif
+
+out:
+	return ret;
  }
  
  int security_socket_recvmsg(struct socket *sock, struct msghdr *msg,