[Devel] Re: [RFC][patch 2/3] network security hooks

Serge E. Hallyn serue at us.ibm.com
Wed Sep 5 09:04:08 PDT 2007


Quoting dlezcano at fr.ibm.com (dlezcano at fr.ibm.com):
> From: Daniel Lezcano <dlezcano at fr.ibm.com>
> 
> After all, the network security hooks are placed exactly at the places we need.
> This patch plugs the network security hooks with network container subsystem.
> 
> The hooks always do nothing when they are called from a process running inside
> the root container.
> 
> The security hooks are not activated by default when the root container is created,
> I let the first child container to do that, that ensure correct kernel initialization.
> 
> Signed-off-by: Daniel Lezcano <dlezcano at fr.ibm.com>
> 
> 
> ---
>  kernel/container_network.c |  148 +++++++++++++++++++++++++++++++++++++++++++++
>  1 file changed, 148 insertions(+)
> 
> Index: 2.6-mm/kernel/container_network.c
> ===================================================================
> --- 2.6-mm.orig/kernel/container_network.c
> +++ 2.6-mm/kernel/container_network.c
> @@ -11,6 +11,7 @@
>  #include <linux/ctype.h>
>  #include <linux/list.h>
>  #include <linux/spinlock.h>
> +#include <linux/security.h>
> 
>  struct network {
>  	struct container_subsys_state css;
> @@ -28,12 +29,21 @@
>  	.ipv4_list_lock = __RW_LOCK_UNLOCKED(top_network.ipv4_list_lock),
>  };
> 
> +static int security_registered;
> +static int secondary;
> +
>  struct container_subsys network_subsys;
> 
>  enum container_filetype {
>  	FILE_IPV4,
>  };
> 
> +static inline struct network *task_network(struct task_struct *task)
> +{
> +	return container_of(task_subsys_state(task, network_subsys_id),
> +			    struct network, css);
> +}
> +
>  static inline struct network *container_network(struct container *container)
>  {
>  	return container_of(
> @@ -41,6 +51,125 @@
>  		struct network, css);
>  }
> 
> +static int network_socket_create(int family, int type, int protocol, int kern)
> +{
> +	struct network *network;
> +
> +	network = task_network(current);
> +	if (!network || network == &top_network)

I'm not sure that's the way to go here is it?  Maybe you want to allow a
CAP_NET_ADMIN process in top_network to drop a network address so that
if it does a bind(INADDR_ANY) it won't get connections for vserver1?

> +		return 0;
> +
> +	return 0;
> +}
> +
> +static int network_socket_post_create(struct socket *sock, int family,
> +				      int type, int protocol, int kern)
> +{
> +	struct network *network;
> +
> +	network = task_network(current);
> +	if (!network || network == &top_network)
> +		return 0;
> +
> +	return 0;
> +}
> +
> +static int network_socket_bind(struct socket *sock,
> +			       struct sockaddr *address,
> +			       int addrlen)
> +{
> +	struct network *network;
> +
> +	network = task_network(current);
> +	if (!network || network == &top_network)
> +		return 0;
> +
> +	return 0;
> +}
> +
> +static int network_socket_connect(struct socket * sock,
> +				  struct sockaddr * address,
> +				  int addrlen)
> +{
> +	struct network *network;
> +
> +	network = task_network(current);
> +	if (!network || network == &top_network)
> +		return 0;
> +
> +	return 0;
> +}
> +
> +static int network_socket_listen(struct socket * sock, int backlog)
> +{
> +	struct network *network;
> +
> +	network = task_network(current);
> +	if (!network || network == &top_network)
> +		return 0;
> +
> +	return 0;
> +}
> +
> +static int network_socket_accept(struct socket *sock,
> +				 struct socket *newsock)
> +{
> +	struct network *network;
> +
> +	network = task_network(current);
> +	if (!network || network == &top_network)
> +		return 0;
> +
> +	return 0;
> +}
> +
> +static void network_socket_post_accept(struct socket *sock,
> +				       struct socket *newsock)
> +{
> +	struct network *network;
> +
> +	network = task_network(current);
> +	if (!network || network == &top_network)
> +		return;
> +}
> +
> +static int network_socket_sendmsg(struct socket *sock,
> +				  struct msghdr *msg, int size)
> +{
> +	struct network *network;
> +
> +	network = task_network(current);
> +	if (!network || network == &top_network)
> +		return 0;
> +
> +	return 0;
> +}
> +
> +static int network_socket_recvmsg(struct socket *sock,
> +				  struct msghdr *msg, int size,
> +				  int flags)
> +{
> +	struct network *network;
> +
> +	network = task_network(current);
> +	if (!network || network == &top_network)
> +		return 0;
> +
> +	return 0;
> +}
> +
> +static struct security_operations network_security_ops = {
> +	.socket_create = network_socket_create,
> +	.socket_post_create = network_socket_post_create,
> +	.socket_bind = network_socket_bind,
> +	.socket_connect = network_socket_connect,
> +	.socket_listen = network_socket_listen,
> +	.socket_accept = network_socket_accept,
> +	.socket_post_accept = network_socket_post_accept,
> +	.socket_sendmsg = network_socket_sendmsg,
> +	.socket_recvmsg = network_socket_recvmsg,
> +};
> +
>  static struct container_subsys_state *network_create(struct container_subsys *ss,
>  						     struct container *container)
>  {
> @@ -61,6 +190,25 @@
>  	INIT_LIST_HEAD(&network->ipv4_list);
>  	network->ipv4_list_lock = __RW_LOCK_UNLOCKED(network->ipv4_list_lock);
> 
> +	/*
> +	 * register the network security hooks only one time
> +	 * after the root container is created, the first non
> +	 * root container has the assignment to register the
> +	 * security hooks
> +	 *
> +	 */
> +	if (!security_registered) {
> +		if (register_security(&network_security_ops)) {
> +			if (mod_reg_security(KBUILD_MODNAME,
> +					     &network_security_ops)) {
> +				kfree(network);
> +				return ERR_PTR(-EINVAL);
> +			}
> +			secondary = 1;
> +		}
> +		security_registered = 1;
> +	}
> +
>  	return &network->css;
>  }

This is an unusual way to do this...  Usually one registers the lsm
hooks at module load.  Though I can't think of any reason it's
particularly bad, other than the register_security() might have
succeeded when you are first loaded and might fail later.

Congratulations, I think you're the first to do this  :)

Note, you don't ever unregister yourself, so there is no point in
defining 'secondary'.

-serge
_______________________________________________
Containers mailing list
Containers at lists.linux-foundation.org
https://lists.linux-foundation.org/mailman/listinfo/containers




More information about the Devel mailing list