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 */
}
|