[PATCH] skb hooks

From: James Morris (jmorrisat_private)
Date: Sat Jul 21 2001 - 05:53:35 PDT

  • Next message: Greg KH: "Re: Names vs. Inodes"

    Below is an initial patch which adds lifecyle hooks to the sk_buff data
    structure used throughout the networking code.
    
    The purpose of these hooks is to facilitate the use of an opaque security
    context associated with each skb.
    
    These per-skb security contexts may be used for a number of purposes
    including:
    
    - Propagating security labels between network layers.
    - Maintaining general state across network layers to allow late
      access/audit calls to me made (e.g. may need to allow matching of both
      user and IP address on an incoming packet at the transport layer, after
      the network headers have been pulled out of the skb).
    - Tracking security state as packets are encapsulated and decapsulated
      (e.g. processing nested security associations on a packet).
    
    Note that the skb_ops calls are not themselves meant to be used for
    access/audit purposes, they just help an LSM module maintain the security
    context of an skb throughout it's lifecycle.
    
    A blank/default security context would be generated for the skb upon
    alloc_security(), then the security context would be maintained and used
    semantically by other types of network security ops.
    
    The following is a brief description of the skb_ops calls:
    
    alloc_security
    	Called when a new skb is allocated, LSM module may return failure
            if it cannot allocate a security context under OOM.
    
    clone
    copy
    	Called when an skb is cloned or copied.  The module will need to
            determine what kind of copying is needed for the associated
            security context and do it, as well as manage any reference
            counts.
    
    fragment
    	Called when an skb is being fragmented, with the original and new
            (fragment) skbs as arguments.  The module again will need to copy
            any security context and/or manage reference counts.
    
    encapsulate
    decapsulate
    	Called when an skb is being encapsulated or decapsulated, for
            situations such as IPIP tunneling and security association
            processing.
    
    free_security
    	Called when an skb is about to die.  The module should free any
            associated security context as well.
    
    This patch only contains protocol-specific hooks for IPv4 (and also needs
    to be audited to make sure nothing was missed).
    
    
    - James
    -- 
    James Morris
    <jmorrisat_private>
    
    diff -urN --exclude BitKeeper --exclude SCCS --exclude ChangeSet lsm/include/linux/security.h lsm-w2/include/linux/security.h
    --- lsm/include/linux/security.h	Sat Jul 21 15:07:21 2001
    +++ lsm-w2/include/linux/security.h	Sat Jul 21 22:07:37 2001
    @@ -124,6 +124,17 @@
     struct socket_security_ops {
     };
    
    +struct sk_buff;
    +struct skb_security_ops {
    +	int (* alloc_security)		(struct sk_buff *skb);
    +	void (* clone)			(struct sk_buff *newskb, const struct sk_buff *oldskb);
    +	void (* copy)			(struct sk_buff *newskb, const struct sk_buff *oldskb);
    +	void (* fragment)		(struct sk_buff *newskb, const struct sk_buff *oldskb);
    +	void (* decapsulate)		(struct sk_buff *skb);
    +	void (* encapsulate)		(struct sk_buff *skb);
    +	void (* free_security)		(struct sk_buff *skb);
    +};
    +
     struct module_security_ops {
      	int  (* create_module)		(const char *name_user, size_t size);
      	int  (* init_module)		(const char *name_user, struct module *mod_user);
    @@ -197,6 +208,7 @@
     	struct file_security_ops	* file_ops;
     	struct task_security_ops	* task_ops;
     	struct socket_security_ops	* socket_ops;
    +	struct skb_security_ops		* skb_ops;
     	struct module_security_ops 	* module_ops;
     	struct ipc_security_ops		* ipc_ops;
     	struct msg_msg_security_ops	* msg_msg_ops;
    diff -urN --exclude BitKeeper --exclude SCCS --exclude ChangeSet lsm/include/linux/skbuff.h lsm-w2/include/linux/skbuff.h
    --- lsm/include/linux/skbuff.h	Sat Jun 30 22:04:37 2001
    +++ lsm-w2/include/linux/skbuff.h	Sat Jul 21 22:07:41 2001
    @@ -213,6 +213,8 @@
     #ifdef CONFIG_NET_SCHED
            __u32           tc_index;               /* traffic control index */
     #endif
    +
    +	void		*security_context;	/* for LSM */
     };
    
     #define SK_WMEM_MAX	65535
    diff -urN --exclude BitKeeper --exclude SCCS --exclude ChangeSet lsm/kernel/capability_plug.c lsm-w2/kernel/capability_plug.c
    --- lsm/kernel/capability_plug.c	Sat Jul 21 15:07:21 2001
    +++ lsm-w2/kernel/capability_plug.c	Sat Jul 21 22:21:07 2001
    @@ -325,6 +325,14 @@
     static int cap_sem_semctl		(struct sem_array *sma, int semid, int cmd) {return 0;}
     static int cap_sem_semop		(struct sem_array *sma, int semid, struct sembuf *sops, unsigned nsops, int alter) {return 0;}
    
    +static int cap_skb_alloc_security	(struct sk_buff *skb) {return 0;}
    +static void cap_skb_clone		(struct sk_buff *newskb, const struct sk_buff *oldskb) {return;}
    +static void cap_skb_copy		(struct sk_buff *newskb, const struct sk_buff *oldskb) {return;}
    +static void cap_skb_fragment		(struct sk_buff *newskb, const struct sk_buff *oldskb) {return;}
    +static void cap_skb_decapsulate		(struct sk_buff *skb) {return;}
    +static void cap_skb_encapsulate		(struct sk_buff *skb) {return;}
    +static void cap_skb_free_security	(struct sk_buff *skb) {return;}
    +
     static int cap_register			(const char *name, struct security_operations *ops)	{return -EINVAL;}
     static int cap_unregister		(const char *name, struct security_operations *ops)	{return -EINVAL;}
    
    @@ -404,6 +412,16 @@
    
     static struct socket_security_ops cap_socket_ops = {};
    
    +static struct skb_security_ops cap_skb_ops = {
    +	alloc_security:	cap_skb_alloc_security,
    +	clone:		cap_skb_clone,
    +	copy:		cap_skb_copy,
    +	fragment:	cap_skb_fragment,
    +	decapsulate:	cap_skb_decapsulate,
    +	encapsulate:	cap_skb_encapsulate,
    +	free_security:	cap_skb_free_security,
    +};
    +
     static struct module_security_ops cap_module_ops = {
     	create_module:	cap_module_create_module,
     	init_module:	cap_module_init_module,
    @@ -475,6 +493,7 @@
     	file_ops:		&cap_file_ops,
     	task_ops:		&cap_task_ops,
     	socket_ops:		&cap_socket_ops,
    +	skb_ops:		&cap_skb_ops,
     	module_ops:		&cap_module_ops,
     	ipc_ops:		&cap_ipc_ops,
     	msg_msg_ops:		&cap_msg_ops,
    diff -urN --exclude BitKeeper --exclude SCCS --exclude ChangeSet lsm/kernel/security.c lsm-w2/kernel/security.c
    --- lsm/kernel/security.c	Sat Jul 21 15:07:21 2001
    +++ lsm-w2/kernel/security.c	Sat Jul 21 22:08:37 2001
    @@ -162,6 +162,14 @@
     static int dummy_sem_semctl		(struct sem_array *sma, int semid, int cmd)	{return 0;}
     static int dummy_sem_semop		(struct sem_array *sma, int semid, struct sembuf *sops, unsigned nsops, int alter) {return 0;}
    
    +static int dummy_skb_alloc_security	(struct sk_buff *skb) {return 0;}
    +static void dummy_skb_clone		(struct sk_buff *newskb, const struct sk_buff *oldskb) {return;}
    +static void dummy_skb_copy		(struct sk_buff *newskb, const struct sk_buff *oldskb) {return;}
    +static void dummy_skb_fragment		(struct sk_buff *newskb, const struct sk_buff *oldskb) {return;}
    +static void dummy_skb_decapsulate	(struct sk_buff *skb) {return;}
    +static void dummy_skb_encapsulate	(struct sk_buff *skb) {return;}
    +static void dummy_skb_free_security	(struct sk_buff *skb) {return;}
    +
     static int dummy_register		(const char *name, struct security_operations *ops)	{return -EINVAL;}
     static int dummy_unregister		(const char *name, struct security_operations *ops)	{return -EINVAL;}
    
    @@ -239,6 +247,16 @@
    
     static struct socket_security_ops dummy_socket_ops = {};
    
    +static struct skb_security_ops dummy_skb_ops = {
    +	alloc_security:	dummy_skb_alloc_security,
    +	clone:		dummy_skb_clone,
    +	copy:		dummy_skb_copy,
    +	fragment:	dummy_skb_fragment,
    +	decapsulate:	dummy_skb_decapsulate,
    +	encapsulate:	dummy_skb_encapsulate,
    +	free_security:	dummy_skb_free_security,
    +};
    +
     static struct module_security_ops dummy_module_ops = {
     	create_module:	dummy_module_create_module,
     	init_module:	dummy_module_init_module,
    @@ -310,6 +328,7 @@
     	file_ops:		&dummy_file_ops,
     	task_ops:		&dummy_task_ops,
     	socket_ops:		&dummy_socket_ops,
    +	skb_ops:		&dummy_skb_ops,
     	ipc_ops:		&dummy_ipc_ops,
     	module_ops:		&dummy_module_ops,
     	msg_msg_ops:		&dummy_msg_msg_ops,
    @@ -380,6 +399,7 @@
     	    !ops->file_ops ||
     	    !ops->task_ops ||
     	    !ops->socket_ops ||
    +	    !ops->skb_ops ||
     	    !ops->module_ops ||
     	    !ops->ipc_ops ||
     	    !ops->msg_msg_ops ||
    diff -urN --exclude BitKeeper --exclude SCCS --exclude ChangeSet lsm/net/core/skbuff.c lsm-w2/net/core/skbuff.c
    --- lsm/net/core/skbuff.c	Thu Jun 28 04:02:01 2001
    +++ lsm-w2/net/core/skbuff.c	Sat Jul 21 22:25:23 2001
    @@ -51,6 +51,7 @@
     #include <linux/cache.h>
     #include <linux/init.h>
     #include <linux/highmem.h>
    +#include <linux/security.h>
    
     #include <net/ip.h>
     #include <net/protocol.h>
    @@ -191,6 +192,11 @@
     	if (data == NULL)
     		goto nodata;
    
    +	if (security_ops->skb_ops->alloc_security(skb)) {
    +		kfree(data);
    +		goto nodata;
    +	}
    +
     	/* XXX: does not include slab overhead */
     	skb->truesize = size + sizeof(struct sk_buff);
    
    @@ -250,6 +256,7 @@
     #ifdef CONFIG_NET_SCHED
     	skb->tc_index = 0;
     #endif
    +	skb->security_context = NULL;
     }
    
     static void skb_drop_fraglist(struct sk_buff *skb)
    @@ -327,6 +334,7 @@
     #ifdef CONFIG_NETFILTER
     	nf_conntrack_put(skb->nfct);
     #endif
    +	security_ops->skb_ops->free_security(skb);
     	skb_headerinit(skb, NULL, 0);  /* clean state */
     	kfree_skbmem(skb);
     }
    @@ -399,7 +407,7 @@
     #ifdef CONFIG_NET_SCHED
     	C(tc_index);
     #endif
    -
    +	security_ops->skb_ops->clone(n, skb);
     	atomic_inc(&(skb_shinfo(skb)->dataref));
     	skb->cloned = 1;
     #ifdef CONFIG_NETFILTER
    @@ -442,6 +450,7 @@
     #ifdef CONFIG_NET_SCHED
     	new->tc_index = old->tc_index;
     #endif
    +	security_ops->skb_ops->copy(new, old);
     }
    
     /**
    diff -urN --exclude BitKeeper --exclude SCCS --exclude ChangeSet lsm/net/ipv4/ip_gre.c lsm-w2/net/ipv4/ip_gre.c
    --- lsm/net/ipv4/ip_gre.c	Thu Jun 28 04:02:01 2001
    +++ lsm-w2/net/ipv4/ip_gre.c	Sat Jul 21 21:55:04 2001
    @@ -655,6 +655,7 @@
     		skb->nf_debug = 0;
     #endif
     #endif
    +		security_ops->skb_ops->decapsulate(skb);
     		ipgre_ecn_decapsulate(iph, skb);
     		netif_rx(skb);
     		read_unlock(&ipgre_lock);
    @@ -884,7 +885,8 @@
     	skb->nf_debug = 0;
     #endif
     #endif
    -
    +	security_ops->skb_ops->encapsulate(skb);
    +
     	IPTUNNEL_XMIT();
     	tunnel->recursion--;
     	return 0;
    diff -urN --exclude BitKeeper --exclude SCCS --exclude ChangeSet lsm/net/ipv4/ip_output.c lsm-w2/net/ipv4/ip_output.c
    --- lsm/net/ipv4/ip_output.c	Thu Jun 28 04:02:01 2001
    +++ lsm-w2/net/ipv4/ip_output.c	Sat Jul 21 21:55:04 2001
    @@ -856,6 +856,7 @@
     		skb2->nf_debug = skb->nf_debug;
     #endif
     #endif
    +		security_ops->skb_ops->fragment(skb2, skb);
    
     		/*
     		 *	Put this fragment into the sending queue.
    diff -urN --exclude BitKeeper --exclude SCCS --exclude ChangeSet lsm/net/ipv4/ipip.c lsm-w2/net/ipv4/ipip.c
    --- lsm/net/ipv4/ipip.c	Thu Jun 28 04:02:01 2001
    +++ lsm-w2/net/ipv4/ipip.c	Sat Jul 21 21:55:04 2001
    @@ -500,6 +500,7 @@
     		skb->nf_debug = 0;
     #endif
     #endif
    +		security_ops->skb_ops->decapsulate(skb);
     		ipip_ecn_decapsulate(iph, skb);
     		netif_rx(skb);
     		read_unlock(&ipip_lock);
    @@ -647,6 +648,8 @@
     	skb->nf_debug = 0;
     #endif
     #endif
    +
    +	security_ops->skb_ops->encapsulate(skb);
    
     	IPTUNNEL_XMIT();
     	tunnel->recursion--;
    diff -urN --exclude BitKeeper --exclude SCCS --exclude ChangeSet lsm/net/ipv4/ipmr.c lsm-w2/net/ipv4/ipmr.c
    --- lsm/net/ipv4/ipmr.c	Thu Jun 28 04:02:01 2001
    +++ lsm-w2/net/ipv4/ipmr.c	Sat Jul 21 21:55:04 2001
    @@ -1104,6 +1104,7 @@
     	nf_conntrack_put(skb->nfct);
     	skb->nfct = NULL;
     #endif
    +	security_ops->skb_ops->encapsulate(skb);
     }
    
     static inline int ipmr_forward_finish(struct sk_buff *skb)
    @@ -1449,6 +1450,7 @@
     	nf_conntrack_put(skb->nfct);
     	skb->nfct = NULL;
     #endif
    +	security_ops->skb_ops->decapsulate(skb);
     	netif_rx(skb);
     	dev_put(reg_dev);
     	return 0;
    @@ -1516,6 +1518,7 @@
     	nf_conntrack_put(skb->nfct);
     	skb->nfct = NULL;
     #endif
    +	security_ops->skb_ops->decapsulate(skb);
     	netif_rx(skb);
     	dev_put(reg_dev);
     	return 0;
    
    
    _______________________________________________
    linux-security-module mailing list
    linux-security-moduleat_private
    http://mail.wirex.com/mailman/listinfo/linux-security-module
    



    This archive was generated by hypermail 2b30 : Sat Jul 21 2001 - 05:55:42 PDT