[PATCH] LSM networking: skb hooks for 2.5.59 (3/8)

From: James Morris (jmorrisat_private)
Date: Thu Jan 30 2003 - 14:56:34 PST

  • Next message: James Morris: "[PATCH] LSM networking: socket hooks for 2.5.59 (4/8)"

     include/linux/security.h |  119 +++++++++++++++++++++++++++++++++++++++++++++++
     include/linux/skbuff.h   |    3 +
     include/net/sock.h       |    2 
     net/core/datagram.c      |    5 +
     net/core/skbuff.c        |   16 ++++++
     security/dummy.c         |   39 +++++++++++++++
     6 files changed, 183 insertions(+), 1 deletion(-)
    
    diff -urN -X dontdiff linux-2.5.59.w0/include/linux/security.h linux-2.5.59.w1/include/linux/security.h
    --- linux-2.5.59.w0/include/linux/security.h	Thu Jan 30 21:29:06 2003
    +++ linux-2.5.59.w1/include/linux/security.h	Thu Jan 30 21:29:32 2003
    @@ -64,6 +64,7 @@
     #define LSM_SETID_FS	8
     
     /* forward declares to avoid warnings */
    +struct sock;
     struct sk_buff;
     struct net_device;
     struct nfsctl_arg;
    @@ -586,6 +587,50 @@
      * 	is being reparented to the init task.
      *	@p contains the task_struct for the kernel thread.
      *
    + * Lifecycle hooks for network buffers.
    + *
    + * @skb_alloc_security:
    + *	This hook is called by the &sk_buff allocator when a new buffer is
    + *	being allocated.  An LSM module may allocate and assign a new security
    + *	blob for the &sk_buff via this hook.
    + *	@skb contains the buffer being allocated.
    + *	@gfp_mask contains the kernel allocation gfp_mask value.
    + *	Return 0 if successful, or -ENOMEM on out of memory condition.
    + * @skb_clone:
    + *	This hook is called when an &sk_buff is being cloned, and may be used,
    + *	for example, to increment a reference count on the associated security
    + *	blob.  The security blob in the @newskb will not have been allocated.
    + *	@newskb contains the newly cloned buffer.
    + *	@oldskb contains the buffer being cloned.
    + *	Returns 0 on success -ENOMEM on failure.
    + * @skb_copy:
    + *	This hook is called when an &sk_buff header is being copied, which
    + *	occurs during the skb_copy() and pskb_copy() functions in
    + *	<net/core/skbuff.c>
    + *	@newskb contains the newly copied buffer.
    + *	@oldskb contains the buffer being copied.
    + * @skb_set_owner_w:
    + *	This hook is called when the ownership of an &sk_buff is being assigned
    + *	to a sending socket.  Typically, this would be used to copy security
    + *	attributes from the sending socket to the &sk_buff.
    + *	@skb contains the buffer being owned.
    + *	@sk contains sock to which ownership is being assigned.
    + * @skb_recv_datagram:
    + *      This hook is called when a process is receiving a datagram
    + *      message.  At this point, there is an association between the
    + *      current process, the socket, and the skb.
    + *      @skb contains the buffer being returned.
    + *      @sk is the receiving sock.
    + *      @flags contains operational flags.
    + * @skb_free_security:
    + *	This hook is called when an &sk_buff is being destroyed, and should be
    + *	used to free any associated security blob.
    + *	@skb contains the buffer being destroyed.
    + *
    + * These are the lifecycle hooks for network buffers. They are used to help
    + * manage the lifecycle of security blobs for &sk_buff structures, and are not
    + * intended to be used for access decisions.
    + *
      * Security hooks for network devices.
      * @netdev_unregister:
      *	Update the module's state when a network device is unregistered,
    @@ -967,6 +1012,16 @@
     	                            struct security_operations *ops);
     
     #ifdef CONFIG_SECURITY_NETWORK
    +	int (*skb_alloc_security) (struct sk_buff * skb, int gfp_mask);
    +	int (*skb_clone) (struct sk_buff * newskb,
    +			  const struct sk_buff * oldskb);
    +	void (*skb_copy) (struct sk_buff * newskb,
    +			  const struct sk_buff * oldskb);
    +	void (*skb_set_owner_w) (struct sk_buff * skb, struct sock * sk);
    +	void (*skb_recv_datagram) (struct sk_buff * skb, struct sock * sk,
    +				   unsigned flags);
    +	void (*skb_free_security) (struct sk_buff * skb);
    +
     	void (*netdev_unregister) (struct net_device * dev);
     #endif	/* CONFIG_SECURITY_NETWORK */
     };
    @@ -2125,6 +2180,40 @@
     
     #ifdef CONFIG_SECURITY_NETWORK
     
    +static inline int security_skb_alloc(struct sk_buff * skb, int gfp_mask)
    +{
    +	return security_ops->skb_alloc_security(skb, gfp_mask);
    +}
    +
    +static inline int security_skb_clone(struct sk_buff * newskb, 
    +				     const struct sk_buff * oldskb)
    +{
    +	return security_ops->skb_clone(newskb, oldskb);
    +}
    +
    +static inline void security_skb_copy(struct sk_buff * newskb, 
    +				     const struct sk_buff * oldskb)
    +{
    +	security_ops->skb_copy(newskb, oldskb);
    +}
    +
    +static inline void security_skb_set_owner_w (struct sk_buff * skb, 
    +					     struct sock * sk)
    +{
    +	security_ops->skb_set_owner_w (skb, sk);
    +}
    +
    +static inline void security_skb_recv_datagram(struct sk_buff * skb, 
    +					      struct sock * sk, unsigned flags)
    +{
    +	security_ops->skb_recv_datagram(skb, sk, flags);
    +}
    +
    +static inline void security_skb_free(struct sk_buff * skb)
    +{
    +	security_ops->skb_free_security(skb);
    +}
    +
     static inline void security_netdev_unregister(struct net_device * dev)
     {
     	security_ops->netdev_unregister(dev);
    @@ -2132,6 +2221,36 @@
     
     #else	/* CONFIG_SECURITY_NETWORK */
     
    +static inline int security_skb_alloc(struct sk_buff * skb, int gfp_mask)
    +{
    +	return 0;
    +}
    +
    +static inline int security_skb_clone(struct sk_buff * newskb, 
    +				     const struct sk_buff * oldskb)
    +{
    +	return 0;
    +}
    +
    +static inline void security_skb_copy(struct sk_buff * newskb, 
    +				     const struct sk_buff * oldskb)
    +{
    +}
    +
    +static inline void security_skb_set_owner_w (struct sk_buff * skb, 
    +					     struct sock * sk)
    +{
    +}
    +
    +static inline void security_skb_recv_datagram(struct sk_buff * skb, 
    +					      struct sock * sk, unsigned flags)
    +{
    +}
    +
    +static inline void security_skb_free(struct sk_buff * skb)
    +{
    +}
    +
     static inline void security_netdev_unregister(struct net_device * dev)
     {
     }
    diff -urN -X dontdiff linux-2.5.59.w0/include/linux/skbuff.h linux-2.5.59.w1/include/linux/skbuff.h
    --- linux-2.5.59.w0/include/linux/skbuff.h	Thu Jan 16 22:51:34 2003
    +++ linux-2.5.59.w1/include/linux/skbuff.h	Thu Jan 30 21:29:32 2003
    @@ -261,6 +261,9 @@
     #ifdef CONFIG_NET_SCHED
            __u32			tc_index;               /* traffic control index */
     #endif
    +#ifdef CONFIG_SECURITY_NETWORK
    +	void		*lsm_security;		/* replaces the above security field */
    +#endif
     };
     
     #define SK_WMEM_MAX	65535
    diff -urN -X dontdiff linux-2.5.59.w0/include/net/sock.h linux-2.5.59.w1/include/net/sock.h
    --- linux-2.5.59.w0/include/net/sock.h	Mon Nov 18 23:56:19 2002
    +++ linux-2.5.59.w1/include/net/sock.h	Thu Jan 30 21:29:33 2003
    @@ -44,6 +44,7 @@
     
     #include <linux/netdevice.h>
     #include <linux/skbuff.h>	/* struct sk_buff */
    +#include <linux/security.h>
     
     #ifdef CONFIG_FILTER
     #include <linux/filter.h>
    @@ -700,6 +701,7 @@
     	sock_hold(sk);
     	skb->sk = sk;
     	skb->destructor = sock_wfree;
    +	security_skb_set_owner_w(skb, sk);
     	atomic_add(skb->truesize, &sk->wmem_alloc);
     }
     
    diff -urN -X dontdiff linux-2.5.59.w0/net/core/datagram.c linux-2.5.59.w1/net/core/datagram.c
    --- linux-2.5.59.w0/net/core/datagram.c	Sun Aug 11 12:20:40 2002
    +++ linux-2.5.59.w1/net/core/datagram.c	Thu Jan 30 21:29:33 2003
    @@ -47,6 +47,7 @@
     #include <linux/rtnetlink.h>
     #include <linux/poll.h>
     #include <linux/highmem.h>
    +#include <linux/security.h>
     
     #include <net/protocol.h>
     #include <linux/skbuff.h>
    @@ -176,8 +177,10 @@
     		} else
     			skb = skb_dequeue(&sk->receive_queue);
     
    -		if (skb)
    +		if (skb) {
    +			security_skb_recv_datagram(skb, sk, flags);
     			return skb;
    +		}
     
     		/* User doesn't want to wait */
     		error = -EAGAIN;
    diff -urN -X dontdiff linux-2.5.59.w0/net/core/skbuff.c linux-2.5.59.w1/net/core/skbuff.c
    --- linux-2.5.59.w0/net/core/skbuff.c	Thu Jan 16 22:51:35 2003
    +++ linux-2.5.59.w1/net/core/skbuff.c	Thu Jan 30 21:29:33 2003
    @@ -53,6 +53,7 @@
     #include <linux/rtnetlink.h>
     #include <linux/init.h>
     #include <linux/highmem.h>
    +#include <linux/security.h>
     
     #include <net/protocol.h>
     #include <net/dst.h>
    @@ -195,6 +196,11 @@
     	if (!data)
     		goto nodata;
     
    +	if (security_skb_alloc(skb, gfp_mask)) {
    + 		kfree(data);
    +		goto nodata;
    +	}
    +
     	/* XXX: does not include slab overhead */
     	skb->truesize = size + sizeof(struct sk_buff);
     
    @@ -257,6 +263,9 @@
     #ifdef CONFIG_NET_SCHED
     	skb->tc_index	  = 0;
     #endif
    +#ifdef CONFIG_SECURITY_NETWORK
    +	skb->lsm_security = NULL;
    +#endif
     }
     
     static void skb_drop_fraglist(struct sk_buff *skb)
    @@ -339,6 +348,7 @@
     	nf_bridge_put(skb->nf_bridge);
     #endif
     #endif
    +	security_skb_free(skb);
     	skb_headerinit(skb, NULL, 0);  /* clean state */
     	kfree_skbmem(skb);
     }
    @@ -366,6 +376,11 @@
     		if (!n)
     			return NULL;
     	}
    +	
    +	if (security_skb_clone(n, skb)) {
    +		skb_head_to_pool(n);
    +		return NULL;
    +	}
     
     #define C(x) n->x = skb->x
     
    @@ -470,6 +485,7 @@
     #ifdef CONFIG_NET_SCHED
     	new->tc_index	= old->tc_index;
     #endif
    +	security_skb_copy(new, old);
     }
     
     /**
    diff -urN -X dontdiff linux-2.5.59.w0/security/dummy.c linux-2.5.59.w1/security/dummy.c
    --- linux-2.5.59.w0/security/dummy.c	Thu Jan 30 21:29:06 2003
    +++ linux-2.5.59.w1/security/dummy.c	Thu Jan 30 21:29:33 2003
    @@ -599,6 +599,39 @@
     
     #ifdef CONFIG_SECURITY_NETWORK
     
    +static int dummy_skb_alloc_security (struct sk_buff *skb, int gfp_mask)
    +{
    +	return 0;
    +}
    +
    +static int dummy_skb_clone (struct sk_buff *newskb,
    +			     const struct sk_buff *oldskb)
    +{
    +	return 0;
    +}
    +
    +static void dummy_skb_copy (struct sk_buff *newskb,
    +			    const struct sk_buff *oldskb)
    +{
    +	return;
    +}
    +
    +static void dummy_skb_set_owner_w (struct sk_buff *skb, struct sock *sk)
    +{
    +	return;
    +}
    +
    +static void dummy_skb_recv_datagram (struct sk_buff *skb, struct sock *sk,
    +				     unsigned flags)
    +{
    +	return;
    +}
    +
    +static void dummy_skb_free_security (struct sk_buff *skb)
    +{
    +	return;
    +}
    +
     static void dummy_netdev_unregister (struct net_device *dev)
     {
     	return;
    @@ -735,6 +768,12 @@
     	set_to_dummy_if_null(ops, register_security);
     	set_to_dummy_if_null(ops, unregister_security);
     #ifdef CONFIG_SECURITY_NETWORK
    +	set_to_dummy_if_null(ops, skb_alloc_security);
    +	set_to_dummy_if_null(ops, skb_clone);
    +	set_to_dummy_if_null(ops, skb_copy);
    +	set_to_dummy_if_null(ops, skb_set_owner_w);
    +	set_to_dummy_if_null(ops, skb_recv_datagram);
    +	set_to_dummy_if_null(ops, skb_free_security);
     	set_to_dummy_if_null(ops, netdev_unregister);
     #endif	/* CONFIG_SECURITY_NETWORK */
     }
    
    
    _______________________________________________
    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 : Thu Jan 30 2003 - 15:00:46 PST