Re: [PATCH] Security: Add prctl(PR_{GET,SET}_NETWORK) interface.

From: AmÃrico Wang
Date: Thu Dec 17 2009 - 04:26:19 EST


On Wed, Dec 16, 2009 at 11:32 PM, Michael Stone <michael@xxxxxxxxxx> wrote:
> Daniel Bernstein has observed [1] that security-conscious userland processes
> may benefit from the ability to irrevocably remove their ability to create,
> bind, connect to, or send messages except in the case of previously connected
> sockets or AF_UNIX filesystem sockets. We provide this facility by implementing
> support for a new prctl(PR_SET_NETWORK) flag named PR_NETWORK_OFF.
>
> This facility is particularly attractive to security platforms like OLPC
> Bitfrost [2] and to isolation programs like Rainbow [3] and Plash [4].
>
> [1]: http://cr.yp.to/unix/disablenetwork.html
> [2]: http://wiki.laptop.org/go/OLPC_Bitfrost
> [3]: http://wiki.laptop.org/go/Rainbow
> [4]: http://plash.beasts.org/
>
> Signed-off-by: Michael Stone <michael@xxxxxxxxxx>
> ---
> Âinclude/linux/prctl.h     |  Â7 +++++++
> Âinclude/linux/prctl_network.h | Â Â7 +++++++
> Âinclude/linux/sched.h     |  Â2 ++
> Âkernel/Makefile        |  Â2 +-
> Âkernel/prctl_network.c    Â|  37 +++++++++++++++++++++++++++++++++++++
> Âkernel/sys.c         Â|  Â7 +++++++
> Â6 files changed, 61 insertions(+), 1 deletions(-)
> Âcreate mode 100644 include/linux/prctl_network.h
> Âcreate mode 100644 kernel/prctl_network.c
>
> diff --git a/include/linux/prctl.h b/include/linux/prctl.h
> index a3baeb2..4eb4110 100644
> --- a/include/linux/prctl.h
> +++ b/include/linux/prctl.h
> @@ -102,4 +102,11 @@
>
> Â#define PR_MCE_KILL_GET 34
>
> +/* Get/set process disable-network flags */
> +#define PR_SET_NETWORK 35
> +#define PR_GET_NETWORK 36
> +# define PR_NETWORK_ON Â Â Â Â0
> +# define PR_NETWORK_OFF Â Â Â 1
> +# define PR_NETWORK_ALL_FLAGS 1
> +
> Â#endif /* _LINUX_PRCTL_H */
> diff --git a/include/linux/prctl_network.h b/include/linux/prctl_network.h
> new file mode 100644
> index 0000000..2db83eb
> --- /dev/null
> +++ b/include/linux/prctl_network.h
> @@ -0,0 +1,7 @@
> +#ifndef _LINUX_PRCTL_NETWORK_H
> +#define _LINUX_PRCTL_NETWORK_H
> +
> +extern long prctl_get_network(void);
> +extern long prctl_set_network(unsigned long);
> +
> +#endif /* _LINUX_PRCTL_NETWORK_H */
> diff --git a/include/linux/sched.h b/include/linux/sched.h
> index 5c858f3..751d372 100644
> --- a/include/linux/sched.h
> +++ b/include/linux/sched.h
> @@ -1395,6 +1395,8 @@ struct task_struct {
> Â Â Â Âunsigned int sessionid;
> Â#endif
> Â Â Â Âseccomp_t seccomp;
> +/* Flags for limiting networking via prctl(PR_SET_NETWORK). */
> + Âunsigned long network;
>
> Â/* Thread group tracking */
> Â Â Â Âu32 parent_exec_id;
> diff --git a/kernel/Makefile b/kernel/Makefile
> index 864ff75..cafbff2 100644
> --- a/kernel/Makefile
> +++ b/kernel/Makefile
> @@ -10,7 +10,7 @@ obj-y   = sched.o fork.o exec_domain.o panic.o printk.o \
> Â Â Â Â Â Âkthread.o wait.o kfifo.o sys_ni.o posix-cpu-timers.o mutex.o \
> Â Â Â Â Â Âhrtimer.o rwsem.o nsproxy.o srcu.o semaphore.o \
> Â Â Â Â Â Ânotifier.o ksysfs.o pm_qos_params.o sched_clock.o cred.o \
> - Â Â Â Â Â async.o
> + Â Â Â Â Â async.o prctl_network.o
> Âobj-y += groups.o
>
> Âifdef CONFIG_FUNCTION_TRACER
> diff --git a/kernel/prctl_network.c b/kernel/prctl_network.c
> new file mode 100644
> index 0000000..d173716
> --- /dev/null
> +++ b/kernel/prctl_network.c
> @@ -0,0 +1,37 @@
> +/*
> + * linux/kernel/prctl_network.c
> + *
> + * Copyright 2009 ÂMichael Stone <michael@xxxxxxxxxx>
> + *
> + * Turn off a process's ability to access new networks.
> + * See Documentation/prctl_network.txt for details.
> + */
> +
> +#include <linux/prctl_network.h>
> +#include <linux/sched.h>
> +#include <linux/prctl.h>
> +
> +long prctl_get_network(void)
> +{
> + Â Â Â return current->network;
> +}
> +
> +long prctl_set_network(unsigned long network_flags)
> +{
> + Â Â Â long ret;
> +
> + Â Â Â /* only dropping access is permitted */
> + Â Â Â ret = -EPERM;
> + Â Â Â Âif (current->network & ~network_flags)
> + Â Â Â Â Â Â Â goto out;
> +
> + Â Â Â ret = -EINVAL;
> + Â Â Â if (network_flags & ~PR_NETWORK_ALL_FLAGS)
> + Â Â Â Â Â Â Â goto out;
> +
> + Â Â Â current->network = network_flags;
> + Â Â Â ret = 0;
> +
> +out:
> + Â Â Â return ret;
> +}


Sorry that I didn't follow the original disscusion.
Any reason why you introdce a new source file?
Why not just adding them to kernel/sys.c?


> diff --git a/kernel/sys.c b/kernel/sys.c
> index 20ccfb5..4eccc66 100644
> --- a/kernel/sys.c
> +++ b/kernel/sys.c
> @@ -35,6 +35,7 @@
> Â#include <linux/cpu.h>
> Â#include <linux/ptrace.h>
> Â#include <linux/fs_struct.h>
> +#include <linux/prctl_network.h>
>
> Â#include <linux/compat.h>
> Â#include <linux/syscalls.h>
> @@ -1576,6 +1577,12 @@ SYSCALL_DEFINE5(prctl, int, option, unsigned long, arg2, unsigned long, arg3,
> Â Â Â Â Â Â Â Â Â Â Â Âelse
> Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Âerror = PR_MCE_KILL_DEFAULT;
> Â Â Â Â Â Â Â Â Â Â Â Âbreak;
> + Â Â Â Â Â Â Â case PR_SET_NETWORK:
> + Â Â Â Â Â Â Â Â Â Â Â error = prctl_set_network(arg2);
> + Â Â Â Â Â Â Â Â Â Â Â break;
> + Â Â Â Â Â Â Â case PR_GET_NETWORK:
> + Â Â Â Â Â Â Â Â Â Â Â error = prctl_get_network();
> + Â Â Â Â Â Â Â Â Â Â Â break;
> Â Â Â Â Â Â Â Âdefault:
> Â Â Â Â Â Â Â Â Â Â Â Âerror = -EINVAL;
> Â Â Â Â Â Â Â Â Â Â Â Âbreak;
> --
> 1.5.6.5
>
> --
> To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
> the body of a message to majordomo@xxxxxxxxxxxxxxx
> More majordomo info at Âhttp://vger.kernel.org/majordomo-info.html
> Please read the FAQ at Âhttp://www.tux.org/lkml/
>
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/