* [PATCH] LSM networking: introduction (0/8)
@ 2003-01-30 22:42 James Morris
2003-01-30 22:46 ` [PATCH] LSM networking: kconfig (1/8) James Morris
0 siblings, 1 reply; 14+ messages in thread
From: James Morris @ 2003-01-30 22:42 UTC (permalink / raw)
To: David S. Miller, kuznet; +Cc: netdev, linux-security-module
Following this email will be the LSM (Linux Security Modules) networking
code split up into eight patches for submission to the mainline kernel.
Since the last submission of these patches, improvements have been made to
the LSM code based on feedback from maintainers and the community. The
LSM hooks are now implemented as static inlines in the main kernel, and
may be compiled out, while the LSM networking code is now generally
configurable via CONFIG_SECURITY_NETWORK. This work was done by Stephen
Smalley.
The configuration exceptions are the two Netlink hooks and the
ip_decode_options() hook, which always need to be present as they
implement default capabilities logic. The rest of the hooks disappear
when not enabled.
Cumulative summary:
include/linux/ip.h | 1
include/linux/netdevice.h | 4
include/linux/security.h | 807 +++++++++++++++++++++++++++++++++++++++++-
include/linux/skbuff.h | 3
include/linux/tcp.h | 11
include/net/sock.h | 16
include/net/tcp.h | 26 +
net/core/datagram.c | 5
net/core/dev.c | 3
net/core/rtnetlink.c | 3
net/core/skbuff.c | 16
net/core/sock.c | 6
net/ipv4/ah.c | 2
net/ipv4/ip_fragment.c | 7
net/ipv4/ip_gre.c | 3
net/ipv4/ip_options.c | 5
net/ipv4/ip_output.c | 3
net/ipv4/ipip.c | 4
net/ipv4/ipmr.c | 4
net/ipv4/netfilter/ip_queue.c | 3
net/ipv4/syncookies.c | 3
net/ipv4/tcp_ipv4.c | 8
net/ipv4/tcp_minisocks.c | 6
net/netlink/af_netlink.c | 8
net/socket.c | 72 +++
net/unix/af_unix.c | 16
security/Kconfig | 9
security/capability.c | 30 +
security/dummy.c | 267 +++++++++++++
29 files changed, 1334 insertions(+), 17 deletions(-)
(Note that more information on LSM can be found at
http://lsm.immunix.org/).
- James
--
James Morris
<jmorris@intercode.com.au>
^ permalink raw reply [flat|nested] 14+ messages in thread
* [PATCH] LSM networking: kconfig (1/8)
2003-01-30 22:42 [PATCH] LSM networking: introduction (0/8) James Morris
@ 2003-01-30 22:46 ` James Morris
2003-01-30 22:51 ` [PATCH] LSM networking: netdev hooks for 2.5.59 (2/8) James Morris
0 siblings, 1 reply; 14+ messages in thread
From: James Morris @ 2003-01-30 22:46 UTC (permalink / raw)
To: David S. Miller, kuznet; +Cc: netdev, linux-security-module
Kconfig | 9 +++++++++
1 files changed, 9 insertions(+)
diff -urN -X dontdiff linux-2.5.59.w0/security/Kconfig linux-2.5.59.w1/security/Kconfig
--- linux-2.5.59.w0/security/Kconfig Tue Dec 24 23:31:09 2002
+++ linux-2.5.59.w1/security/Kconfig Thu Jan 30 21:18:42 2003
@@ -15,6 +15,15 @@
If you are unsure how to answer this question, answer N.
+config SECURITY_NETWORK
+ bool "Socket and Networking Security Hooks"
+ depends on SECURITY
+ help
+ This enables the socket and networking security hooks.
+ If enabled, a security module can use these hooks to
+ implement socket and networking access controls.
+ If you are unsure how to answer this question, answer N.
+
config SECURITY_CAPABILITIES
tristate "Default Linux Capabilities"
depends on SECURITY!=n
^ permalink raw reply [flat|nested] 14+ messages in thread
* [PATCH] LSM networking: netdev hooks for 2.5.59 (2/8)
2003-01-30 22:46 ` [PATCH] LSM networking: kconfig (1/8) James Morris
@ 2003-01-30 22:51 ` James Morris
2003-01-30 22:56 ` [PATCH] LSM networking: skb hooks for 2.5.59 (3/8) James Morris
0 siblings, 1 reply; 14+ messages in thread
From: James Morris @ 2003-01-30 22:51 UTC (permalink / raw)
To: David S. Miller, kuznet; +Cc: netdev, linux-security-module
include/linux/netdevice.h | 4 ++++
include/linux/security.h | 38 +++++++++++++++++++++++++++++++++++---
net/core/dev.c | 3 +++
security/dummy.c | 12 ++++++++++++
4 files changed, 54 insertions(+), 3 deletions(-)
diff -urN -X dontdiff linux-2.5.59.w0/include/linux/netdevice.h linux-2.5.59.w1/include/linux/netdevice.h
--- linux-2.5.59.w0/include/linux/netdevice.h Fri Jan 17 19:46:08 2003
+++ linux-2.5.59.w1/include/linux/netdevice.h Thu Jan 30 21:23:47 2003
@@ -442,6 +442,10 @@
/* generic object representation */
struct kobject kobj;
+
+#ifdef CONFIG_SECURITY_NETWORK
+ void *security;
+#endif
};
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 16 22:51:34 2003
+++ linux-2.5.59.w1/include/linux/security.h Thu Jan 30 21:26:28 2003
@@ -63,9 +63,6 @@
/* setfsuid or setfsgid, id0 == fsuid or fsgid */
#define LSM_SETID_FS 8
-
-#ifdef CONFIG_SECURITY
-
/* forward declares to avoid warnings */
struct sk_buff;
struct net_device;
@@ -73,6 +70,9 @@
struct sched_param;
struct swap_info_struct;
+
+#ifdef CONFIG_SECURITY
+
/**
* struct security_operations - main security structure
*
@@ -586,6 +586,19 @@
* is being reparented to the init task.
* @p contains the task_struct for the kernel thread.
*
+ * Security hooks for network devices.
+ * @netdev_unregister:
+ * Update the module's state when a network device is unregistered,
+ * deallocating the dev->security field if it was previously allocated.
+ * @dev contains the network device
+ *
+ * These are the hooks for network device operations. Since it would be quite
+ * invasive to provide hooks in every location where a network device might be
+ * probed or initialized, there are no separate hooks for allocation or
+ * initialization. Security modules can allocate and initialize the
+ * dev->security field on the first access to the device, but should be careful
+ * to use nonblocking allocation.
+ *
* Security hooks affecting all System V IPC operations.
*
* @ipc_permission:
@@ -952,6 +965,10 @@
struct security_operations *ops);
int (*unregister_security) (const char *name,
struct security_operations *ops);
+
+#ifdef CONFIG_SECURITY_NETWORK
+ void (*netdev_unregister) (struct net_device * dev);
+#endif /* CONFIG_SECURITY_NETWORK */
};
/* global variables */
@@ -2106,5 +2123,20 @@
#endif /* CONFIG_SECURITY */
+#ifdef CONFIG_SECURITY_NETWORK
+
+static inline void security_netdev_unregister(struct net_device * dev)
+{
+ security_ops->netdev_unregister(dev);
+}
+
+#else /* CONFIG_SECURITY_NETWORK */
+
+static inline void security_netdev_unregister(struct net_device * dev)
+{
+}
+
+#endif /* CONFIG_SECURITY_NETWORK */
+
#endif /* ! __LINUX_SECURITY_H */
diff -urN -X dontdiff linux-2.5.59.w0/net/core/dev.c linux-2.5.59.w1/net/core/dev.c
--- linux-2.5.59.w0/net/core/dev.c Fri Jan 17 19:46:08 2003
+++ linux-2.5.59.w1/net/core/dev.c Thu Jan 30 21:23:47 2003
@@ -107,6 +107,7 @@
#include <linux/kmod.h>
#include <linux/module.h>
#include <linux/kallsyms.h>
+#include <linux/security.h>
#if defined(CONFIG_NET_RADIO) || defined(CONFIG_NET_PCMCIA_RADIO)
#include <linux/wireless.h> /* Note : will define WIRELESS_EXT */
#include <net/iw_handler.h>
@@ -2680,6 +2681,8 @@
free_divert_blk(dev);
#endif
+ security_netdev_unregister(dev);
+
if (dev->features & NETIF_F_DYNALLOC) {
#ifdef NET_REFCNT_DEBUG
if (atomic_read(&dev->refcnt) != 1)
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 16 22:51:35 2003
+++ linux-2.5.59.w1/security/dummy.c Thu Jan 30 21:23:47 2003
@@ -597,6 +597,15 @@
return 0;
}
+#ifdef CONFIG_SECURITY_NETWORK
+
+static void dummy_netdev_unregister (struct net_device *dev)
+{
+ return;
+}
+
+#endif /* CONFIG_SECURITY_NETWORK */
+
static int dummy_register_security (const char *name, struct security_operations *ops)
{
return -EINVAL;
@@ -725,5 +734,8 @@
set_to_dummy_if_null(ops, sem_semop);
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, netdev_unregister);
+#endif /* CONFIG_SECURITY_NETWORK */
}
^ permalink raw reply [flat|nested] 14+ messages in thread
* [PATCH] LSM networking: skb hooks for 2.5.59 (3/8)
2003-01-30 22:51 ` [PATCH] LSM networking: netdev hooks for 2.5.59 (2/8) James Morris
@ 2003-01-30 22:56 ` James Morris
2003-01-30 23:01 ` [PATCH] LSM networking: socket hooks for 2.5.59 (4/8) James Morris
0 siblings, 1 reply; 14+ messages in thread
From: James Morris @ 2003-01-30 22:56 UTC (permalink / raw)
To: David S. Miller, kuznet; +Cc: netdev, linux-security-module
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 */
}
^ permalink raw reply [flat|nested] 14+ messages in thread
* [PATCH] LSM networking: socket hooks for 2.5.59 (4/8)
2003-01-30 22:56 ` [PATCH] LSM networking: skb hooks for 2.5.59 (3/8) James Morris
@ 2003-01-30 23:01 ` James Morris
2003-01-30 23:06 ` [PATCH] LSM networking: ipv4 hooks for 2.5.59 (5/8) James Morris
0 siblings, 1 reply; 14+ messages in thread
From: James Morris @ 2003-01-30 23:01 UTC (permalink / raw)
To: David S. Miller, kuznet; +Cc: netdev, linux-security-module
include/linux/security.h | 346 +++++++++++++++++++++++++++++++++++++++++++++++
include/net/sock.h | 14 +
net/core/sock.c | 6
net/ipv4/tcp_ipv4.c | 4
net/socket.c | 72 +++++++++
security/dummy.c | 111 ++++++++++++++-
6 files changed, 549 insertions(+), 4 deletions(-)
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:31:15 2003
+++ linux-2.5.59.w1/include/linux/security.h Thu Jan 30 21:31:32 2003
@@ -65,6 +65,9 @@
/* forward declares to avoid warnings */
struct sock;
+struct socket;
+struct sockaddr;
+struct msghdr;
struct sk_buff;
struct net_device;
struct nfsctl_arg;
@@ -587,6 +590,126 @@
* is being reparented to the init task.
* @p contains the task_struct for the kernel thread.
*
+ * Security hooks for socket operations.
+ *
+ * @socket_create:
+ * Check permissions prior to creating a new socket.
+ * @family contains the requested protocol family.
+ * @type contains the requested communications type.
+ * @protocol contains the requested protocol.
+ * Return 0 if permission is granted.
+ * @socket_post_create:
+ * This hook allows a module to update or allocate a per-socket security
+ * structure. Note that the security field was not added directly to the
+ * socket structure, but rather, the socket security information is stored
+ * in the associated inode. Typically, the inode alloc_security hook will
+ * allocate and and attach security information to
+ * sock->inode->i_security. This hook may be used to update the
+ * sock->inode->i_security field with additional information that wasn't
+ * available when the inode was allocated.
+ * @sock contains the newly created socket structure.
+ * @family contains the requested protocol family.
+ * @type contains the requested communications type.
+ * @protocol contains the requested protocol.
+ * @socket_bind:
+ * Check permission before socket protocol layer bind operation is
+ * performed and the socket @sock is bound to the address specified in the
+ * @address parameter.
+ * @sock contains the socket structure.
+ * @address contains the address to bind to.
+ * @addrlen contains the length of address.
+ * Return 0 if permission is granted.
+ * @socket_connect:
+ * Check permission before socket protocol layer connect operation
+ * attempts to connect socket @sock to a remote address, @address.
+ * @sock contains the socket structure.
+ * @address contains the address of remote endpoint.
+ * @addrlen contains the length of address.
+ * Return 0 if permission is granted.
+ * @socket_listen:
+ * Check permission before socket protocol layer listen operation.
+ * @sock contains the socket structure.
+ * @backlog contains the maximum length for the pending connection queue.
+ * Return 0 if permission is granted.
+ * @socket_accept:
+ * Check permission before accepting a new connection. Note that the new
+ * socket, @newsock, has been created and some information copied to it,
+ * but the accept operation has not actually been performed.
+ * @sock contains the listening socket structure.
+ * @newsock contains the newly created server socket for connection.
+ * Return 0 if permission is granted.
+ * @socket_post_accept:
+ * This hook allows a security module to copy security
+ * information into the newly created socket's inode.
+ * @sock contains the listening socket structure.
+ * @newsock contains the newly created server socket for connection.
+ * @socket_sendmsg:
+ * Check permission before transmitting a message to another socket.
+ * @sock contains the socket structure.
+ * @msg contains the message to be transmitted.
+ * @size contains the size of message.
+ * Return 0 if permission is granted.
+ * @socket_recvmsg:
+ * Check permission before receiving a message from a socket.
+ * @sock contains the socket structure.
+ * @msg contains the message structure.
+ * @size contains the size of message structure.
+ * @flags contains the operational flags.
+ * Return 0 if permission is granted.
+ * @socket_getsockname:
+ * Check permission before the local address (name) of the socket object
+ * @sock is retrieved.
+ * @sock contains the socket structure.
+ * Return 0 if permission is granted.
+ * @socket_getpeername:
+ * Check permission before the remote address (name) of a socket object
+ * @sock is retrieved.
+ * @sock contains the socket structure.
+ * Return 0 if permission is granted.
+ * @socket_getsockopt:
+ * Check permissions before retrieving the options associated with socket
+ * @sock.
+ * @sock contains the socket structure.
+ * @level contains the protocol level to retrieve option from.
+ * @optname contains the name of option to retrieve.
+ * Return 0 if permission is granted.
+ * @socket_setsockopt:
+ * Check permissions before setting the options associated with socket
+ * @sock.
+ * @sock contains the socket structure.
+ * @level contains the protocol level to set options for.
+ * @optname contains the name of the option to set.
+ * Return 0 if permission is granted.
+ * @socket_shutdown:
+ * Checks permission before all or part of a connection on the socket
+ * @sock is shut down.
+ * @sock contains the socket structure.
+ * @how contains the flag indicating how future sends and receives are handled.
+ * Return 0 if permission is granted.
+ * @socket_sock_alloc_security:
+ * @sk contains the sock structure.
+ * @gfp_mask contains the kernel allocation gfp_mask value.
+ * Allocate and attach a security structure to @sk->security. The
+ * security field is initialized to NULL when the sock structure is
+ * allocated.
+ * Return 0 if operation was successful.
+ * @socket_sock_free_security:
+ * @sk contains the sock structure.
+ * Deallocate and clear the sk->security field.
+ * @socket_sock_rcv_skb:
+ * Check permissions on incoming network packets. This hook is distinct
+ * from the network input hooks of ip_security_ops since it is the first
+ * time that the incoming sk_buff @skb has been associated with a
+ * particular socket, @sk. Security modules should not try to dereference
+ * @sk->socket if the socket is in a time wait state
+ * (@sk->state == TCP_TIME_WAIT), since the @sk refers to a tcp_tw_bucket
+ * structure in that case. Also, even if the socket is not in this state,
+ * @sk->socket may be NULL, e.g. a newly created server socket for a
+ * connection that has not yet been accepted by a process.
+ * @sk contains the sock (not socket) associated with the incoming sk_buff.
+ * @skb contains the incoming network data.
+ * Return 0 if permission is granted.
+ *
* Lifecycle hooks for network buffers.
*
* @skb_alloc_security:
@@ -1012,6 +1135,30 @@
struct security_operations *ops);
#ifdef CONFIG_SECURITY_NETWORK
+ int (*socket_create) (int family, int type, int protocol);
+ void (*socket_post_create) (struct socket * sock, int family,
+ int type, int protocol);
+ int (*socket_bind) (struct socket * sock,
+ struct sockaddr * address, int addrlen);
+ int (*socket_connect) (struct socket * sock,
+ struct sockaddr * address, int addrlen);
+ int (*socket_listen) (struct socket * sock, int backlog);
+ int (*socket_accept) (struct socket * sock, struct socket * newsock);
+ void (*socket_post_accept) (struct socket * sock,
+ struct socket * newsock);
+ int (*socket_sendmsg) (struct socket * sock,
+ struct msghdr * msg, int size);
+ int (*socket_recvmsg) (struct socket * sock,
+ struct msghdr * msg, int size, int flags);
+ int (*socket_getsockname) (struct socket * sock);
+ int (*socket_getpeername) (struct socket * sock);
+ int (*socket_getsockopt) (struct socket * sock, int level, int optname);
+ int (*socket_setsockopt) (struct socket * sock, int level, int optname);
+ int (*socket_shutdown) (struct socket * sock, int how);
+ int (*socket_sock_alloc_security) (struct sock * sk, int gfp_mask);
+ void (*socket_sock_free_security) (struct sock * sk);
+ int (*socket_sock_rcv_skb) (struct sock * sk, struct sk_buff * skb);
+
int (*skb_alloc_security) (struct sk_buff * skb, int gfp_mask);
int (*skb_clone) (struct sk_buff * newskb,
const struct sk_buff * oldskb);
@@ -2180,6 +2327,107 @@
#ifdef CONFIG_SECURITY_NETWORK
+static inline int security_socket_create (int family, int type, int protocol)
+{
+ return security_ops->socket_create(family, type, protocol);
+}
+
+static inline void security_socket_post_create(struct socket * sock,
+ int family,
+ int type,
+ int protocol)
+{
+ security_ops->socket_post_create(sock, family, type, protocol);
+}
+
+static inline int security_socket_bind(struct socket * sock,
+ struct sockaddr * address,
+ int addrlen)
+{
+ return security_ops->socket_bind(sock, address, addrlen);
+}
+
+static inline int security_socket_connect(struct socket * sock,
+ struct sockaddr * address,
+ int addrlen)
+{
+ return security_ops->socket_connect(sock, address, addrlen);
+}
+
+static inline int security_socket_listen(struct socket * sock, int backlog)
+{
+ return security_ops->socket_listen(sock, backlog);
+}
+
+static inline int security_socket_accept(struct socket * sock,
+ struct socket * newsock)
+{
+ return security_ops->socket_accept(sock, newsock);
+}
+
+static inline void security_socket_post_accept(struct socket * sock,
+ struct socket * newsock)
+{
+ security_ops->socket_post_accept(sock, newsock);
+}
+
+static inline int security_socket_sendmsg(struct socket * sock,
+ struct msghdr * msg, int size)
+{
+ return security_ops->socket_sendmsg(sock, msg, size);
+}
+
+static inline int security_socket_recvmsg(struct socket * sock,
+ struct msghdr * msg, int size,
+ int flags)
+{
+ return security_ops->socket_recvmsg(sock, msg, size, flags);
+}
+
+static inline int security_socket_getsockname(struct socket * sock)
+{
+ return security_ops->socket_getsockname(sock);
+}
+
+static inline int security_socket_getpeername(struct socket * sock)
+{
+ return security_ops->socket_getpeername(sock);
+}
+
+static inline int security_socket_getsockopt(struct socket * sock,
+ int level, int optname)
+{
+ return security_ops->socket_getsockopt(sock, level, optname);
+}
+
+static inline int security_socket_setsockopt(struct socket * sock,
+ int level, int optname)
+{
+ return security_ops->socket_setsockopt(sock, level, optname);
+}
+
+static inline int security_socket_shutdown(struct socket * sock, int how)
+{
+ return security_ops->socket_shutdown(sock, how);
+}
+
+static inline int security_sock_alloc(struct sock * sk,
+ int gfp_mask)
+{
+ return security_ops->socket_sock_alloc_security(sk, gfp_mask);
+}
+
+static inline void security_sock_free(struct sock * sk)
+{
+ security_ops->socket_sock_free_security(sk);
+}
+
+static inline int security_sock_rcv_skb (struct sock * sk,
+ struct sk_buff * skb)
+{
+ return security_ops->socket_sock_rcv_skb (sk, skb);
+}
+
static inline int security_skb_alloc(struct sk_buff * skb, int gfp_mask)
{
return security_ops->skb_alloc_security(skb, gfp_mask);
@@ -2221,6 +2469,104 @@
#else /* CONFIG_SECURITY_NETWORK */
+static inline int security_socket_create (int family, int type, int protocol)
+{
+ return 0;
+}
+
+static inline void security_socket_post_create(struct socket * sock,
+ int family,
+ int type,
+ int protocol)
+{
+}
+
+static inline int security_socket_bind(struct socket * sock,
+ struct sockaddr * address,
+ int addrlen)
+{
+ return 0;
+}
+
+static inline int security_socket_connect(struct socket * sock,
+ struct sockaddr * address,
+ int addrlen)
+{
+ return 0;
+}
+
+static inline int security_socket_listen(struct socket * sock, int backlog)
+{
+ return 0;
+}
+
+static inline int security_socket_accept(struct socket * sock,
+ struct socket * newsock)
+{
+ return 0;
+}
+
+static inline void security_socket_post_accept(struct socket * sock,
+ struct socket * newsock)
+{
+}
+
+static inline int security_socket_sendmsg(struct socket * sock,
+ struct msghdr * msg, int size)
+{
+ return 0;
+}
+
+static inline int security_socket_recvmsg(struct socket * sock,
+ struct msghdr * msg, int size,
+ int flags)
+{
+ return 0;
+}
+
+static inline int security_socket_getsockname(struct socket * sock)
+{
+ return 0;
+}
+
+static inline int security_socket_getpeername(struct socket * sock)
+{
+ return 0;
+}
+
+static inline int security_socket_getsockopt(struct socket * sock,
+ int level, int optname)
+{
+ return 0;
+}
+
+static inline int security_socket_setsockopt(struct socket * sock,
+ int level, int optname)
+{
+ return 0;
+}
+
+static inline int security_socket_shutdown(struct socket * sock, int how)
+{
+ return 0;
+}
+
+static inline int security_sock_alloc(struct sock * sk,
+ int gfp_mask)
+{
+ return 0;
+}
+
+static inline void security_sock_free(struct sock * sk)
+{
+}
+
+static inline int security_sock_rcv_skb (struct sock * sk,
+ struct sk_buff * skb)
+{
+ return 0;
+}
+
static inline int security_skb_alloc(struct sk_buff * skb, int gfp_mask)
{
return 0;
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 Thu Jan 30 21:31:15 2003
+++ linux-2.5.59.w1/include/net/sock.h Thu Jan 30 21:31:32 2003
@@ -197,7 +197,12 @@
/* RPC layer private data */
void *user_data;
-
+
+#ifdef CONFIG_SECURITY_NETWORK
+ /* LSM security field */
+ void *security;
+#endif
+
/* Callbacks */
void (*state_change)(struct sock *sk);
void (*data_ready)(struct sock *sk,int bytes);
@@ -714,15 +719,20 @@
static inline int sock_queue_rcv_skb(struct sock *sk, struct sk_buff *skb)
{
+ int err = 0;
+
/* Cast skb->rcvbuf to unsigned... It's pointless, but reduces
number of warnings when compiling with -W --ANK
*/
if (atomic_read(&sk->rmem_alloc) + skb->truesize >= (unsigned)sk->rcvbuf)
return -ENOMEM;
+ err = security_sock_rcv_skb(sk, skb);
+ if (err)
+ return err;
+
#ifdef CONFIG_FILTER
if (sk->filter) {
- int err = 0;
struct sk_filter *filter;
/* It would be deadlock, if sock_queue_rcv_skb is used
diff -urN -X dontdiff linux-2.5.59.w0/net/core/sock.c linux-2.5.59.w1/net/core/sock.c
--- linux-2.5.59.w0/net/core/sock.c Sat Oct 19 19:57:49 2002
+++ linux-2.5.59.w1/net/core/sock.c Thu Jan 30 21:31:32 2003
@@ -109,6 +109,7 @@
#include <linux/poll.h>
#include <linux/tcp.h>
#include <linux/init.h>
+#include <linux/security.h>
#include <asm/uaccess.h>
#include <asm/system.h>
@@ -600,6 +601,10 @@
sk->family = family;
sock_lock_init(sk);
}
+ if (security_sock_alloc(sk, priority)) {
+ kmem_cache_free(slab, sk);
+ return NULL;
+ }
sk->slab = slab;
}
@@ -626,6 +631,7 @@
if (atomic_read(&sk->omem_alloc))
printk(KERN_DEBUG "sk_free: optmem leakage (%d bytes) detected.\n", atomic_read(&sk->omem_alloc));
+ security_sock_free(sk);
kmem_cache_free(sk->slab, sk);
}
diff -urN -X dontdiff linux-2.5.59.w0/net/ipv4/tcp_ipv4.c linux-2.5.59.w1/net/ipv4/tcp_ipv4.c
--- linux-2.5.59.w0/net/ipv4/tcp_ipv4.c Thu Jan 16 22:51:35 2003
+++ linux-2.5.59.w1/net/ipv4/tcp_ipv4.c Thu Jan 30 21:31:32 2003
@@ -71,6 +71,7 @@
#include <linux/stddef.h>
#include <linux/proc_fs.h>
#include <linux/seq_file.h>
+#include <linux/security.h>
extern int sysctl_ip_dynaddr;
extern int sysctl_ip_default_ttl;
@@ -1798,6 +1799,9 @@
goto no_tcp_socket;
process:
+ if (security_sock_rcv_skb(sk, skb))
+ goto discard_and_relse;
+
if (sk->state == TCP_TIME_WAIT)
goto do_time_wait;
diff -urN -X dontdiff linux-2.5.59.w0/net/socket.c linux-2.5.59.w1/net/socket.c
--- linux-2.5.59.w0/net/socket.c Thu Jan 9 16:08:27 2003
+++ linux-2.5.59.w1/net/socket.c Thu Jan 30 21:31:32 2003
@@ -77,6 +77,7 @@
#include <linux/highmem.h>
#include <linux/divert.h>
#include <linux/mount.h>
+#include <linux/security.h>
#if defined(CONFIG_KMOD) && defined(CONFIG_NET)
#include <linux/kmod.h>
@@ -527,6 +528,10 @@
si->msg = msg;
si->size = size;
+ err = security_socket_sendmsg(sock, msg, size);
+ if (err)
+ return err;
+
err = scm_send(sock, msg, si->scm);
if (err >= 0) {
err = sock->ops->sendmsg(iocb, sock, msg, size, si->scm);
@@ -551,6 +556,7 @@
int __sock_recvmsg(struct kiocb *iocb, struct socket *sock, struct msghdr *msg, int size, int flags)
{
+ int err;
struct sock_iocb *si = kiocb_to_siocb(iocb);
si->sock = sock;
@@ -560,6 +566,10 @@
si->size = size;
si->flags = flags;
+ err = security_socket_recvmsg(sock, msg, size, flags);
+ if (err)
+ return err;
+
memset(si->scm, 0, sizeof(*si->scm));
size = sock->ops->recvmsg(iocb, sock, msg, size, flags, si->scm);
@@ -963,6 +973,7 @@
int sock_create(int family, int type, int protocol, struct socket **res)
{
int i;
+ int err;
struct socket *sock;
/*
@@ -986,6 +997,10 @@
}
family = PF_PACKET;
}
+
+ err = security_socket_create(family, type, protocol);
+ if (err)
+ return err;
#if defined(CONFIG_KMOD) && defined(CONFIG_NET)
/* Attempt to load a protocol module if the find failed.
@@ -1031,6 +1046,7 @@
}
*res = sock;
+ security_socket_post_create(sock, family, type, protocol);
out:
net_family_read_unlock();
@@ -1141,8 +1157,14 @@
if((sock = sockfd_lookup(fd,&err))!=NULL)
{
- if((err=move_addr_to_kernel(umyaddr,addrlen,address))>=0)
+ if((err=move_addr_to_kernel(umyaddr,addrlen,address))>=0) {
+ err = security_socket_bind(sock, (struct sockaddr *)address, addrlen);
+ if (err) {
+ sockfd_put(sock);
+ return err;
+ }
err = sock->ops->bind(sock, (struct sockaddr *)address, addrlen);
+ }
sockfd_put(sock);
}
return err;
@@ -1163,6 +1185,13 @@
if ((sock = sockfd_lookup(fd, &err)) != NULL) {
if ((unsigned) backlog > SOMAXCONN)
backlog = SOMAXCONN;
+
+ err = security_socket_listen(sock, backlog);
+ if (err) {
+ sockfd_put(sock);
+ return err;
+ }
+
err=sock->ops->listen(sock, backlog);
sockfd_put(sock);
}
@@ -1199,6 +1228,10 @@
newsock->type = sock->type;
newsock->ops = sock->ops;
+ err = security_socket_accept(sock, newsock);
+ if (err)
+ goto out_release;
+
err = sock->ops->accept(sock, newsock, sock->file->f_flags);
if (err < 0)
goto out_release;
@@ -1218,6 +1251,8 @@
if ((err = sock_map_fd(newsock)) < 0)
goto out_release;
+ security_socket_post_accept(sock, newsock);
+
out_put:
sockfd_put(sock);
out:
@@ -1253,6 +1288,11 @@
err = move_addr_to_kernel(uservaddr, addrlen, address);
if (err < 0)
goto out_put;
+
+ err = security_socket_connect(sock, (struct sockaddr *)address, addrlen);
+ if (err)
+ goto out_put;
+
err = sock->ops->connect(sock, (struct sockaddr *) address, addrlen,
sock->file->f_flags);
out_put:
@@ -1275,6 +1315,11 @@
sock = sockfd_lookup(fd, &err);
if (!sock)
goto out;
+
+ err = security_socket_getsockname(sock);
+ if (err)
+ goto out_put;
+
err = sock->ops->getname(sock, (struct sockaddr *)address, &len, 0);
if (err)
goto out_put;
@@ -1299,6 +1344,12 @@
if ((sock = sockfd_lookup(fd, &err))!=NULL)
{
+ err = security_socket_getpeername(sock);
+ if (err) {
+ sockfd_put(sock);
+ return err;
+ }
+
err = sock->ops->getname(sock, (struct sockaddr *)address, &len, 1);
if (!err)
err=move_addr_to_user(address,len, usockaddr, usockaddr_len);
@@ -1427,6 +1478,12 @@
if ((sock = sockfd_lookup(fd, &err))!=NULL)
{
+ err = security_socket_setsockopt(sock,level,optname);
+ if (err) {
+ sockfd_put(sock);
+ return err;
+ }
+
if (level == SOL_SOCKET)
err=sock_setsockopt(sock,level,optname,optval,optlen);
else
@@ -1448,6 +1505,13 @@
if ((sock = sockfd_lookup(fd, &err))!=NULL)
{
+ err = security_socket_getsockopt(sock, level,
+ optname);
+ if (err) {
+ sockfd_put(sock);
+ return err;
+ }
+
if (level == SOL_SOCKET)
err=sock_getsockopt(sock,level,optname,optval,optlen);
else
@@ -1469,6 +1533,12 @@
if ((sock = sockfd_lookup(fd, &err))!=NULL)
{
+ err = security_socket_shutdown(sock, how);
+ if (err) {
+ sockfd_put(sock);
+ return err;
+ }
+
err=sock->ops->shutdown(sock, how);
sockfd_put(sock);
}
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:31:15 2003
+++ linux-2.5.59.w1/security/dummy.c Thu Jan 30 21:31:32 2003
@@ -20,7 +20,7 @@
#include <linux/security.h>
#include <linux/skbuff.h>
#include <linux/netlink.h>
-
+#include <net/sock.h>
static int dummy_ptrace (struct task_struct *parent, struct task_struct *child)
{
@@ -599,6 +599,98 @@
#ifdef CONFIG_SECURITY_NETWORK
+static int dummy_socket_create (int family, int type, int protocol)
+{
+ return 0;
+}
+
+static void dummy_socket_post_create (struct socket *sock, int family, int type,
+ int protocol)
+{
+ return;
+}
+
+static int dummy_socket_bind (struct socket *sock, struct sockaddr *address,
+ int addrlen)
+{
+ return 0;
+}
+
+static int dummy_socket_connect (struct socket *sock, struct sockaddr *address,
+ int addrlen)
+{
+ return 0;
+}
+
+static int dummy_socket_listen (struct socket *sock, int backlog)
+{
+ return 0;
+}
+
+static int dummy_socket_accept (struct socket *sock, struct socket *newsock)
+{
+ return 0;
+}
+
+static void dummy_socket_post_accept (struct socket *sock,
+ struct socket *newsock)
+{
+ return;
+}
+
+static int dummy_socket_sendmsg (struct socket *sock, struct msghdr *msg,
+ int size)
+{
+ return 0;
+}
+
+static int dummy_socket_recvmsg (struct socket *sock, struct msghdr *msg,
+ int size, int flags)
+{
+ return 0;
+}
+
+static int dummy_socket_getsockname (struct socket *sock)
+{
+ return 0;
+}
+
+static int dummy_socket_getpeername (struct socket *sock)
+{
+ return 0;
+}
+
+static int dummy_socket_setsockopt (struct socket *sock, int level, int optname)
+{
+ return 0;
+}
+
+static int dummy_socket_getsockopt (struct socket *sock, int level, int optname)
+{
+ return 0;
+}
+
+static int dummy_socket_shutdown (struct socket *sock, int how)
+{
+ return 0;
+}
+
+static int dummy_socket_sock_alloc_security(struct sock *sk, int gfp_mask)
+{
+ sk->security = NULL;
+ return 0;
+}
+
+static void dummy_socket_sock_free_security(struct sock *sk)
+{
+ return;
+}
+
+static int dummy_socket_sock_rcv_skb (struct sock *sk, struct sk_buff *skb)
+{
+ return 0;
+}
+
static int dummy_skb_alloc_security (struct sk_buff *skb, int gfp_mask)
{
return 0;
@@ -768,6 +860,23 @@
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, socket_create);
+ set_to_dummy_if_null(ops, socket_post_create);
+ set_to_dummy_if_null(ops, socket_bind);
+ set_to_dummy_if_null(ops, socket_connect);
+ set_to_dummy_if_null(ops, socket_listen);
+ set_to_dummy_if_null(ops, socket_accept);
+ set_to_dummy_if_null(ops, socket_post_accept);
+ set_to_dummy_if_null(ops, socket_sendmsg);
+ set_to_dummy_if_null(ops, socket_recvmsg);
+ set_to_dummy_if_null(ops, socket_getsockname);
+ set_to_dummy_if_null(ops, socket_getpeername);
+ set_to_dummy_if_null(ops, socket_setsockopt);
+ set_to_dummy_if_null(ops, socket_getsockopt);
+ set_to_dummy_if_null(ops, socket_shutdown);
+ set_to_dummy_if_null(ops, socket_sock_alloc_security);
+ set_to_dummy_if_null(ops, socket_sock_free_security);
+ set_to_dummy_if_null(ops, socket_sock_rcv_skb);
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);
^ permalink raw reply [flat|nested] 14+ messages in thread
* [PATCH] LSM networking: ipv4 hooks for 2.5.59 (5/8)
2003-01-30 23:01 ` [PATCH] LSM networking: socket hooks for 2.5.59 (4/8) James Morris
@ 2003-01-30 23:06 ` James Morris
2003-01-30 23:10 ` [PATCH] LSM networking: netlink hooks for 2.5.59 (6/8) James Morris
0 siblings, 1 reply; 14+ messages in thread
From: James Morris @ 2003-01-30 23:06 UTC (permalink / raw)
To: David S. Miller, kuznet; +Cc: netdev, linux-security-module
include/linux/ip.h | 1
include/linux/security.h | 108 ++++++++++++++++++++++++++++++++++++++++++++++-
net/ipv4/ah.c | 2
net/ipv4/ip_fragment.c | 7 ++-
net/ipv4/ip_gre.c | 3 +
net/ipv4/ip_options.c | 5 ++
net/ipv4/ip_output.c | 3 +
net/ipv4/ipip.c | 4 +
net/ipv4/ipmr.c | 4 +
security/capability.c | 13 +++++
security/dummy.c | 36 +++++++++++++++
11 files changed, 183 insertions(+), 3 deletions(-)
diff -urN -X dontdiff linux-2.5.59.w0/include/linux/ip.h linux-2.5.59.w1/include/linux/ip.h
--- linux-2.5.59.w0/include/linux/ip.h Thu Oct 31 16:01:08 2002
+++ linux-2.5.59.w1/include/linux/ip.h Thu Jan 30 21:33:32 2003
@@ -58,6 +58,7 @@
#define IPOPT_SEC (2 |IPOPT_CONTROL|IPOPT_COPY)
#define IPOPT_LSRR (3 |IPOPT_CONTROL|IPOPT_COPY)
#define IPOPT_TIMESTAMP (4 |IPOPT_MEASUREMENT)
+#define IPOPT_CIPSO (6 |IPOPT_CONTROL|IPOPT_COPY)
#define IPOPT_RR (7 |IPOPT_CONTROL)
#define IPOPT_SID (8 |IPOPT_CONTROL|IPOPT_COPY)
#define IPOPT_SSRR (9 |IPOPT_CONTROL|IPOPT_COPY)
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:33:15 2003
+++ linux-2.5.59.w1/include/linux/security.h Thu Jan 30 21:33:32 2003
@@ -38,6 +38,9 @@
* as the default capabilities functions
*/
extern int cap_capable (struct task_struct *tsk, int cap);
+struct sk_buff;
+extern int cap_ip_decode_options (struct sk_buff *skb, const char *optptr,
+ unsigned char **pp_ptr);
extern int cap_ptrace (struct task_struct *parent, struct task_struct *child);
extern int cap_capget (struct task_struct *target, kernel_cap_t *effective, kernel_cap_t *inheritable, kernel_cap_t *permitted);
extern int cap_capset_check (struct task_struct *target, kernel_cap_t *effective, kernel_cap_t *inheritable, kernel_cap_t *permitted);
@@ -68,7 +71,6 @@
struct socket;
struct sockaddr;
struct msghdr;
-struct sk_buff;
struct net_device;
struct nfsctl_arg;
struct sched_param;
@@ -710,6 +712,48 @@
* @skb contains the incoming network data.
* Return 0 if permission is granted.
*
+ * IPv4 networking hooks.
+ *
+ * @ip_fragment:
+ * This is called for each fragment generated when an outgoing packet is
+ * being fragmented, and may be used to copy security attributes from the
+ * original packet to each fragment.
+ * @newskb contains the newly created fragment.
+ * @oldskb contains the original packet being fragmented.
+ * @ip_defragment:
+ * This hook is called when an incoming fragment is about to be inserted
+ * into a reassembly queue. It's purpose is to enable the validation of
+ * security attributes for each fragment. An LSM module using this hook
+ * will likely need to maintain its own fragment queue information, handle
+ * fragment expiration and implement DoS countermeasures.
+ * @skb contains the incoming fragment.
+ * Returns 0 on success.
+ * @ip_encapsulate:
+ * This hook is called when an IP packet is encapsulated, and may be used
+ * to update security attributes prior to reprocessing via the local_out
+ * or forward hooks.
+ * @skb contains the encapsulated packet.
+ * @ip_decapsulate:
+ * This hook is called when a packet is decapsulated, and may be used to
+ * process security attributes at each level of encapsulation. An example
+ * of this would be keeping track of nested security associations for an
+ * incoming packet.
+ * @skb contains the decapsulated packet.
+ * @ip_decode_options:
+ * This hook is used for processing IP security options at the network
+ * layer when labeled networking (e.g. CIPSO) is implemented.
+ * For outgoing packets, IP options passed down from the application or
+ * transport layers may be verified here prior the packet being built.
+ * For incoming packets, IP options may be verified and their values
+ * recorded via the &sk_buff security blob for later processing.
+ * @skb contains the &sk_buff containing IP packet (usually NULL for outgoing).
+ * @optptr contains the &ip_options structure.
+ * @pp_ptr contains the parameter problem pointer.
+ * Returns 0 on success.
+ * A non-zero return value will cause an ICMP parameter problem message to
+ * be generated and transmitted to the sender. The @pp_ptr parameter may
+ * be used to point to the offending option parameter.
+ *
* Lifecycle hooks for network buffers.
*
* @skb_alloc_security:
@@ -987,6 +1031,9 @@
int (*quotactl) (int cmds, int type, int id, struct super_block * sb);
int (*quota_on) (struct file * f);
+ int (*ip_decode_options) (struct sk_buff * skb,
+ const char *optptr, unsigned char **pp_ptr);
+
int (*bprm_alloc_security) (struct linux_binprm * bprm);
void (*bprm_free_security) (struct linux_binprm * bprm);
void (*bprm_compute_creds) (struct linux_binprm * bprm);
@@ -1159,6 +1206,12 @@
void (*socket_sock_free_security) (struct sock * sk);
int (*socket_sock_rcv_skb) (struct sock * sk, struct sk_buff * skb);
+ void (*ip_fragment) (struct sk_buff * newskb,
+ const struct sk_buff * oldskb);
+ int (*ip_defragment) (struct sk_buff * skb);
+ void (*ip_encapsulate) (struct sk_buff * skb);
+ void (*ip_decapsulate) (struct sk_buff * skb);
+
int (*skb_alloc_security) (struct sk_buff * skb, int gfp_mask);
int (*skb_clone) (struct sk_buff * newskb,
const struct sk_buff * oldskb);
@@ -1222,6 +1275,13 @@
return security_ops->quota_on (file);
}
+static inline int security_ip_decode_options(struct sk_buff * skb,
+ const char *optptr,
+ unsigned char **pp_ptr)
+{
+ return security_ops->ip_decode_options(skb, optptr, pp_ptr);
+}
+
static inline int security_bprm_alloc (struct linux_binprm *bprm)
{
return security_ops->bprm_alloc_security (bprm);
@@ -1827,6 +1887,13 @@
return 0;
}
+static inline int security_ip_decode_options(struct sk_buff * skb,
+ const char *optptr,
+ unsigned char **pp_ptr)
+{
+ return cap_ip_decode_options(skb,optptr,pp_ptr);
+}
+
static inline int security_bprm_alloc (struct linux_binprm *bprm)
{
return 0;
@@ -2428,6 +2495,27 @@
return security_ops->socket_sock_rcv_skb (sk, skb);
}
+static inline void security_ip_fragment(struct sk_buff * newskb,
+ const struct sk_buff * oldskb)
+{
+ security_ops->ip_fragment(newskb, oldskb);
+}
+
+static inline int security_ip_defragment(struct sk_buff * skb)
+{
+ return security_ops->ip_defragment(skb);
+}
+
+static inline void security_ip_encapsulate(struct sk_buff * skb)
+{
+ security_ops->ip_encapsulate(skb);
+}
+
+static inline void security_ip_decapsulate(struct sk_buff * skb)
+{
+ security_ops->ip_decapsulate(skb);
+}
+
static inline int security_skb_alloc(struct sk_buff * skb, int gfp_mask)
{
return security_ops->skb_alloc_security(skb, gfp_mask);
@@ -2567,6 +2655,24 @@
return 0;
}
+static inline void security_ip_fragment(struct sk_buff * newskb,
+ const struct sk_buff * oldskb)
+{
+}
+
+static inline int security_ip_defragment(struct sk_buff * skb)
+{
+ return 0;
+}
+
+static inline void security_ip_encapsulate(struct sk_buff * skb)
+{
+}
+
+static inline void security_ip_decapsulate(struct sk_buff * skb)
+{
+}
+
static inline int security_skb_alloc(struct sk_buff * skb, int gfp_mask)
{
return 0;
diff -urN -X dontdiff linux-2.5.59.w0/net/ipv4/ah.c linux-2.5.59.w1/net/ipv4/ah.c
--- linux-2.5.59.w0/net/ipv4/ah.c Sat Jan 11 10:47:20 2003
+++ linux-2.5.59.w1/net/ipv4/ah.c Thu Jan 30 21:33:32 2003
@@ -52,7 +52,7 @@
switch (*optptr) {
case IPOPT_SEC:
case 0x85: /* Some "Extended Security" crap. */
- case 0x86: /* Another "Commercial Security" crap. */
+ case IPOPT_CIPSO: /* Another "Commercial Security" crap. */
case IPOPT_RA:
case 0x80|21: /* RFC1770 */
break;
diff -urN -X dontdiff linux-2.5.59.w0/net/ipv4/ip_fragment.c linux-2.5.59.w1/net/ipv4/ip_fragment.c
--- linux-2.5.59.w0/net/ipv4/ip_fragment.c Sat Jan 11 10:47:20 2003
+++ linux-2.5.59.w1/net/ipv4/ip_fragment.c Thu Jan 30 21:33:32 2003
@@ -37,6 +37,7 @@
#include <linux/udp.h>
#include <linux/inet.h>
#include <linux/netfilter_ipv4.h>
+#include <linux/security.h>
/* NOTE. Logic of IP defragmentation is parallel to corresponding IPv6
* code now. If you change something here, _PLEASE_ update ipv6/reassembly.c
@@ -372,7 +373,11 @@
{
struct sk_buff *prev, *next;
int flags, offset;
- int ihl, end;
+ int ihl, end, ret;
+
+ ret = security_ip_defragment(skb);
+ if (ret)
+ goto err;
if (qp->last_in & COMPLETE)
goto err;
diff -urN -X dontdiff linux-2.5.59.w0/net/ipv4/ip_gre.c linux-2.5.59.w1/net/ipv4/ip_gre.c
--- linux-2.5.59.w0/net/ipv4/ip_gre.c Tue Nov 12 00:12:06 2002
+++ linux-2.5.59.w1/net/ipv4/ip_gre.c Thu Jan 30 21:33:32 2003
@@ -28,6 +28,7 @@
#include <linux/inetdevice.h>
#include <linux/igmp.h>
#include <linux/netfilter_ipv4.h>
+#include <linux/security.h>
#include <net/sock.h>
#include <net/ip.h>
@@ -661,6 +662,7 @@
skb->nf_debug = 0;
#endif
#endif
+ security_ip_decapsulate(skb);
ipgre_ecn_decapsulate(iph, skb);
netif_rx(skb);
read_unlock(&ipgre_lock);
@@ -898,6 +900,7 @@
skb->nf_debug = 0;
#endif
#endif
+ security_ip_encapsulate(skb);
IPTUNNEL_XMIT();
tunnel->recursion--;
diff -urN -X dontdiff linux-2.5.59.w0/net/ipv4/ip_options.c linux-2.5.59.w1/net/ipv4/ip_options.c
--- linux-2.5.59.w0/net/ipv4/ip_options.c Tue Sep 24 19:22:50 2002
+++ linux-2.5.59.w1/net/ipv4/ip_options.c Thu Jan 30 21:33:32 2003
@@ -18,6 +18,7 @@
#include <linux/icmp.h>
#include <linux/netdevice.h>
#include <linux/rtnetlink.h>
+#include <linux/security.h>
#include <net/sock.h>
#include <net/ip.h>
#include <net/icmp.h>
@@ -433,7 +434,11 @@
opt->router_alert = optptr - iph;
break;
case IPOPT_SEC:
+ case IPOPT_CIPSO:
case IPOPT_SID:
+ if (security_ip_decode_options(skb, optptr, &pp_ptr))
+ goto error;
+ break;
default:
if (!skb && !capable(CAP_NET_RAW)) {
pp_ptr = optptr;
diff -urN -X dontdiff linux-2.5.59.w0/net/ipv4/ip_output.c linux-2.5.59.w1/net/ipv4/ip_output.c
--- linux-2.5.59.w0/net/ipv4/ip_output.c Sat Jan 11 10:47:20 2003
+++ linux-2.5.59.w1/net/ipv4/ip_output.c Thu Jan 30 21:33:32 2003
@@ -81,6 +81,7 @@
#include <linux/netfilter_ipv4.h>
#include <linux/mroute.h>
#include <linux/netlink.h>
+#include <linux/security.h>
/*
* Shall we try to damage output packets if routing dev changes?
@@ -633,6 +634,8 @@
ptr += len;
offset += len;
+ security_ip_fragment(skb2, skb);
+
/*
* Put this fragment into the sending queue.
*/
diff -urN -X dontdiff linux-2.5.59.w0/net/ipv4/ipip.c linux-2.5.59.w1/net/ipv4/ipip.c
--- linux-2.5.59.w0/net/ipv4/ipip.c Tue Nov 12 00:12:07 2002
+++ linux-2.5.59.w1/net/ipv4/ipip.c Thu Jan 30 21:33:32 2003
@@ -108,6 +108,7 @@
#include <linux/mroute.h>
#include <linux/init.h>
#include <linux/netfilter_ipv4.h>
+#include <linux/security.h>
#include <net/sock.h>
#include <net/ip.h>
@@ -508,6 +509,7 @@
skb->nf_debug = 0;
#endif
#endif
+ security_ip_decapsulate(skb);
ipip_ecn_decapsulate(iph, skb);
netif_rx(skb);
read_unlock(&ipip_lock);
@@ -662,6 +664,8 @@
#endif
#endif
+ security_ip_encapsulate(skb);
+
IPTUNNEL_XMIT();
tunnel->recursion--;
return 0;
diff -urN -X dontdiff linux-2.5.59.w0/net/ipv4/ipmr.c linux-2.5.59.w1/net/ipv4/ipmr.c
--- linux-2.5.59.w0/net/ipv4/ipmr.c Tue Nov 12 00:12:07 2002
+++ linux-2.5.59.w1/net/ipv4/ipmr.c Thu Jan 30 21:33:32 2003
@@ -60,6 +60,7 @@
#include <linux/netfilter_ipv4.h>
#include <net/ipip.h>
#include <net/checksum.h>
+#include <linux/security.h>
#if defined(CONFIG_IP_PIMSM_V1) || defined(CONFIG_IP_PIMSM_V2)
#define CONFIG_IP_PIMSM 1
@@ -1105,6 +1106,7 @@
nf_conntrack_put(skb->nfct);
skb->nfct = NULL;
#endif
+ security_ip_encapsulate(skb);
}
static inline int ipmr_forward_finish(struct sk_buff *skb)
@@ -1461,6 +1463,7 @@
nf_conntrack_put(skb->nfct);
skb->nfct = NULL;
#endif
+ security_ip_decapsulate(skb);
netif_rx(skb);
dev_put(reg_dev);
return 0;
@@ -1528,6 +1531,7 @@
nf_conntrack_put(skb->nfct);
skb->nfct = NULL;
#endif
+ security_ip_decapsulate(skb);
netif_rx(skb);
dev_put(reg_dev);
return 0;
diff -urN -X dontdiff linux-2.5.59.w0/security/capability.c linux-2.5.59.w1/security/capability.c
--- linux-2.5.59.w0/security/capability.c Tue Dec 10 15:02:03 2002
+++ linux-2.5.59.w1/security/capability.c Thu Jan 30 21:33:32 2003
@@ -266,6 +266,16 @@
return;
}
+int cap_ip_decode_options (struct sk_buff *skb, const char *optptr,
+ unsigned char **pp_ptr)
+{
+ if (!skb && !capable (CAP_NET_RAW)) {
+ (const unsigned char *) *pp_ptr = optptr;
+ return -EPERM;
+ }
+ return 0;
+}
+
EXPORT_SYMBOL(cap_capable);
EXPORT_SYMBOL(cap_ptrace);
EXPORT_SYMBOL(cap_capget);
@@ -276,6 +286,7 @@
EXPORT_SYMBOL(cap_task_post_setuid);
EXPORT_SYMBOL(cap_task_kmod_set_label);
EXPORT_SYMBOL(cap_task_reparent_to_init);
+EXPORT_SYMBOL(cap_ip_decode_options);
#ifdef CONFIG_SECURITY
@@ -293,6 +304,8 @@
.task_post_setuid = cap_task_post_setuid,
.task_kmod_set_label = cap_task_kmod_set_label,
.task_reparent_to_init = cap_task_reparent_to_init,
+
+ .ip_decode_options = cap_ip_decode_options,
};
#if defined(CONFIG_SECURITY_CAPABILITIES_MODULE)
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:33:15 2003
+++ linux-2.5.59.w1/security/dummy.c Thu Jan 30 21:33:32 2003
@@ -597,6 +597,16 @@
return 0;
}
+static int dummy_ip_decode_options (struct sk_buff *skb, const char *optptr,
+ unsigned char **pp_ptr)
+{
+ if (!skb && !capable (CAP_NET_RAW)) {
+ (const unsigned char *) *pp_ptr = optptr;
+ return -EPERM;
+ }
+ return 0;
+}
+
#ifdef CONFIG_SECURITY_NETWORK
static int dummy_socket_create (int family, int type, int protocol)
@@ -686,6 +696,27 @@
return;
}
+static void dummy_ip_fragment (struct sk_buff *newskb,
+ const struct sk_buff *oldskb)
+{
+ return;
+}
+
+static int dummy_ip_defragment (struct sk_buff *skb)
+{
+ return 0;
+}
+
+static void dummy_ip_decapsulate (struct sk_buff *skb)
+{
+ return;
+}
+
+static void dummy_ip_encapsulate (struct sk_buff *skb)
+{
+ return;
+}
+
static int dummy_socket_sock_rcv_skb (struct sock *sk, struct sk_buff *skb)
{
return 0;
@@ -859,6 +890,7 @@
set_to_dummy_if_null(ops, sem_semop);
set_to_dummy_if_null(ops, register_security);
set_to_dummy_if_null(ops, unregister_security);
+ set_to_dummy_if_null(ops, ip_decode_options);
#ifdef CONFIG_SECURITY_NETWORK
set_to_dummy_if_null(ops, socket_create);
set_to_dummy_if_null(ops, socket_post_create);
@@ -877,6 +909,10 @@
set_to_dummy_if_null(ops, socket_sock_alloc_security);
set_to_dummy_if_null(ops, socket_sock_free_security);
set_to_dummy_if_null(ops, socket_sock_rcv_skb);
+ set_to_dummy_if_null(ops, ip_fragment);
+ set_to_dummy_if_null(ops, ip_defragment);
+ set_to_dummy_if_null(ops, ip_decapsulate);
+ set_to_dummy_if_null(ops, ip_encapsulate);
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);
^ permalink raw reply [flat|nested] 14+ messages in thread
* [PATCH] LSM networking: netlink hooks for 2.5.59 (6/8)
2003-01-30 23:06 ` [PATCH] LSM networking: ipv4 hooks for 2.5.59 (5/8) James Morris
@ 2003-01-30 23:10 ` James Morris
2003-01-30 23:17 ` [PATCH] LSM networking: af_unix hooks for 2.5.59 (7/8) James Morris
2003-01-30 23:19 ` [PATCH] LSM networking: netlink hooks for 2.5.59 (6/8) David S. Miller
0 siblings, 2 replies; 14+ messages in thread
From: James Morris @ 2003-01-30 23:10 UTC (permalink / raw)
To: David S. Miller, kuznet; +Cc: netdev, linux-security-module
include/linux/security.h | 39 +++++++++++++++++++++++++++++++++++++++
net/core/rtnetlink.c | 3 ++-
net/ipv4/netfilter/ip_queue.c | 3 ++-
net/netlink/af_netlink.c | 8 +++++++-
security/capability.c | 17 +++++++++++++++++
security/dummy.c | 18 ++++++++++++++++++
6 files changed, 85 insertions(+), 3 deletions(-)
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:36:34 2003
+++ linux-2.5.59.w1/include/linux/security.h Thu Jan 30 21:36:14 2003
@@ -39,6 +39,8 @@
*/
extern int cap_capable (struct task_struct *tsk, int cap);
struct sk_buff;
+extern int cap_netlink_send (struct sk_buff *skb);
+extern int cap_netlink_recv (struct sk_buff *skb);
extern int cap_ip_decode_options (struct sk_buff *skb, const char *optptr,
unsigned char **pp_ptr);
extern int cap_ptrace (struct task_struct *parent, struct task_struct *child);
@@ -1002,6 +1004,20 @@
* @cap contains the capability <include/linux/capability.h>.
* Return 0 if the capability is granted for @tsk.
*
+ * @netlink_send:
+ * Save security information for a netlink message so that permission
+ * checking can be performed when the message is processed. The security
+ * information can either be saved using the existing eff_cap field of the
+ * netlink_skb_parms structure or it can be saved using the skbuff
+ * lsm_security field.
+ * @skb contains the sk_buff structure for the netlink message.
+ * Return 0 if the information was successfully saved.
+ * @netlink_recv:
+ * Check permission before processing the received netlink message in
+ * @skb.
+ * @skb contains the sk_buff structure for the netlink message.
+ * Return 0 if permission is granted.
+ *
* @register_security:
* allow module stacking.
* @name contains the name of the security module being stacked.
@@ -1031,6 +1047,9 @@
int (*quotactl) (int cmds, int type, int id, struct super_block * sb);
int (*quota_on) (struct file * f);
+ int (*netlink_send) (struct sk_buff * skb);
+ int (*netlink_recv) (struct sk_buff * skb);
+
int (*ip_decode_options) (struct sk_buff * skb,
const char *optptr, unsigned char **pp_ptr);
@@ -1275,6 +1294,16 @@
return security_ops->quota_on (file);
}
+static inline int security_netlink_send(struct sk_buff * skb)
+{
+ return security_ops->netlink_send(skb);
+}
+
+static inline int security_netlink_recv(struct sk_buff * skb)
+{
+ return security_ops->netlink_recv(skb);
+}
+
static inline int security_ip_decode_options(struct sk_buff * skb,
const char *optptr,
unsigned char **pp_ptr)
@@ -1887,6 +1916,16 @@
return 0;
}
+static inline int security_netlink_send(struct sk_buff * skb)
+{
+ return cap_netlink_send(skb);
+}
+
+static inline int security_netlink_recv(struct sk_buff * skb)
+{
+ return cap_netlink_recv(skb);
+}
+
static inline int security_ip_decode_options(struct sk_buff * skb,
const char *optptr,
unsigned char **pp_ptr)
diff -urN -X dontdiff linux-2.5.59.w0/net/core/rtnetlink.c linux-2.5.59.w1/net/core/rtnetlink.c
--- linux-2.5.59.w0/net/core/rtnetlink.c Fri Jan 17 19:46:08 2003
+++ linux-2.5.59.w1/net/core/rtnetlink.c Thu Jan 30 21:36:14 2003
@@ -34,6 +34,7 @@
#include <linux/capability.h>
#include <linux/skbuff.h>
#include <linux/init.h>
+#include <linux/security.h>
#include <asm/uaccess.h>
#include <asm/system.h>
@@ -363,7 +364,7 @@
sz_idx = type>>2;
kind = type&3;
- if (kind != 2 && !cap_raised(NETLINK_CB(skb).eff_cap, CAP_NET_ADMIN)) {
+ if (kind != 2 && security_netlink_recv(skb)) {
*errp = -EPERM;
return -1;
}
diff -urN -X dontdiff linux-2.5.59.w0/net/ipv4/netfilter/ip_queue.c linux-2.5.59.w1/net/ipv4/netfilter/ip_queue.c
--- linux-2.5.59.w0/net/ipv4/netfilter/ip_queue.c Sun Aug 11 12:20:40 2002
+++ linux-2.5.59.w1/net/ipv4/netfilter/ip_queue.c Thu Jan 30 21:36:14 2003
@@ -26,6 +26,7 @@
#include <linux/brlock.h>
#include <linux/sysctl.h>
#include <linux/proc_fs.h>
+#include <linux/security.h>
#include <net/sock.h>
#include <net/route.h>
@@ -496,7 +497,7 @@
if (type <= IPQM_BASE)
return;
- if(!cap_raised(NETLINK_CB(skb).eff_cap, CAP_NET_ADMIN))
+ if (security_netlink_recv(skb))
RCV_SKB_FAIL(-EPERM);
write_lock_bh(&queue_lock);
diff -urN -X dontdiff linux-2.5.59.w0/net/netlink/af_netlink.c linux-2.5.59.w1/net/netlink/af_netlink.c
--- linux-2.5.59.w0/net/netlink/af_netlink.c Tue Dec 10 15:02:03 2002
+++ linux-2.5.59.w1/net/netlink/af_netlink.c Thu Jan 30 21:36:14 2003
@@ -42,6 +42,7 @@
#include <linux/proc_fs.h>
#include <linux/smp_lock.h>
#include <linux/notifier.h>
+#include <linux/security.h>
#include <net/sock.h>
#include <net/scm.h>
@@ -636,7 +637,12 @@
check them, when this message will be delivered
to corresponding kernel module. --ANK (980802)
*/
- NETLINK_CB(skb).eff_cap = current->cap_effective;
+
+ err = security_netlink_send(skb);
+ if (err) {
+ kfree_skb(skb);
+ goto out;
+ }
err = -EFAULT;
if (memcpy_fromiovec(skb_put(skb,len), msg->msg_iov, len)) {
diff -urN -X dontdiff linux-2.5.59.w0/security/capability.c linux-2.5.59.w1/security/capability.c
--- linux-2.5.59.w0/security/capability.c Thu Jan 30 21:36:34 2003
+++ linux-2.5.59.w1/security/capability.c Thu Jan 30 21:36:14 2003
@@ -28,6 +28,19 @@
return -EPERM;
}
+int cap_netlink_send (struct sk_buff *skb)
+{
+ NETLINK_CB (skb).eff_cap = current->cap_effective;
+ return 0;
+}
+
+int cap_netlink_recv (struct sk_buff *skb)
+{
+ if (!cap_raised (NETLINK_CB (skb).eff_cap, CAP_NET_ADMIN))
+ return -EPERM;
+ return 0;
+}
+
int cap_ptrace (struct task_struct *parent, struct task_struct *child)
{
/* Derived from arch/i386/kernel/ptrace.c:sys_ptrace. */
@@ -286,6 +299,8 @@
EXPORT_SYMBOL(cap_task_post_setuid);
EXPORT_SYMBOL(cap_task_kmod_set_label);
EXPORT_SYMBOL(cap_task_reparent_to_init);
+EXPORT_SYMBOL(cap_netlink_send);
+EXPORT_SYMBOL(cap_netlink_recv);
EXPORT_SYMBOL(cap_ip_decode_options);
#ifdef CONFIG_SECURITY
@@ -297,6 +312,8 @@
.capset_check = cap_capset_check,
.capset_set = cap_capset_set,
.capable = cap_capable,
+ .netlink_send = cap_netlink_send,
+ .netlink_recv = cap_netlink_recv,
.bprm_compute_creds = cap_bprm_compute_creds,
.bprm_set_security = cap_bprm_set_security,
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:36:34 2003
+++ linux-2.5.59.w1/security/dummy.c Thu Jan 30 21:36:14 2003
@@ -85,6 +85,22 @@
return 0;
}
+static int dummy_netlink_send (struct sk_buff *skb)
+{
+ if (current->euid == 0)
+ cap_raise (NETLINK_CB (skb).eff_cap, CAP_NET_ADMIN);
+ else
+ NETLINK_CB (skb).eff_cap = 0;
+ return 0;
+}
+
+static int dummy_netlink_recv (struct sk_buff *skb)
+{
+ if (!cap_raised (NETLINK_CB (skb).eff_cap, CAP_NET_ADMIN))
+ return -EPERM;
+ return 0;
+}
+
static int dummy_bprm_alloc_security (struct linux_binprm *bprm)
{
return 0;
@@ -890,6 +906,8 @@
set_to_dummy_if_null(ops, sem_semop);
set_to_dummy_if_null(ops, register_security);
set_to_dummy_if_null(ops, unregister_security);
+ set_to_dummy_if_null(ops, netlink_send);
+ set_to_dummy_if_null(ops, netlink_recv);
set_to_dummy_if_null(ops, ip_decode_options);
#ifdef CONFIG_SECURITY_NETWORK
set_to_dummy_if_null(ops, socket_create);
^ permalink raw reply [flat|nested] 14+ messages in thread
* [PATCH] LSM networking: af_unix hooks for 2.5.59 (7/8)
2003-01-30 23:10 ` [PATCH] LSM networking: netlink hooks for 2.5.59 (6/8) James Morris
@ 2003-01-30 23:17 ` James Morris
2003-01-30 23:22 ` [PATCH] LSM networking: tcp hooks for 2.5.59 (8/8) James Morris
2003-01-30 23:19 ` [PATCH] LSM networking: netlink hooks for 2.5.59 (6/8) David S. Miller
1 sibling, 1 reply; 14+ messages in thread
From: James Morris @ 2003-01-30 23:17 UTC (permalink / raw)
To: David S. Miller, kuznet; +Cc: netdev, linux-security-module
include/linux/security.h | 54 +++++++++++++++++++++++++++++++++++++++++++++++
net/unix/af_unix.c | 16 +++++++++++++
security/dummy.c | 15 +++++++++++++
3 files changed, 85 insertions(+)
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:41:57 2003
+++ linux-2.5.59.w1/include/linux/security.h Thu Jan 30 21:41:38 2003
@@ -1018,6 +1018,29 @@
* @skb contains the sk_buff structure for the netlink message.
* Return 0 if permission is granted.
*
+ * @unix_stream_connect:
+ * Check permissions before establishing a Unix domain stream connection
+ * between @sock and @other.
+ * @sock contains the socket structure.
+ * @other contains the peer socket structure.
+ * Return 0 if permission is granted.
+ * @unix_may_send:
+ * Check permissions before connecting or sending datagrams from @sock to
+ * @other.
+ * @sock contains the socket structure.
+ * @sock contains the peer socket structure.
+ * Return 0 if permission is granted.
+ *
+ * The @unix_stream_connect and @unix_may_send hooks were necessary because
+ * Linux provides an alternative to the conventional file name space for Unix
+ * domain sockets. Whereas binding and connecting to sockets in the file name
+ * space is mediated by the typical file permissions (and caught by the mknod
+ * and permission hooks in inode_security_ops), binding and connecting to
+ * sockets in the abstract name space is completely unmediated. Sufficient
+ * control of Unix domain sockets in the abstract name space isn't possible
+ * using only the socket layer hooks, since we need to know the actual target
+ * socket, which is not looked up until we are inside the af_unix code.
+ *
* @register_security:
* allow module stacking.
* @name contains the name of the security module being stacked.
@@ -1201,6 +1224,10 @@
struct security_operations *ops);
#ifdef CONFIG_SECURITY_NETWORK
+ int (*unix_stream_connect) (struct socket * sock,
+ struct socket * other, struct sock * newsk);
+ int (*unix_may_send) (struct socket * sock, struct socket * other);
+
int (*socket_create) (int family, int type, int protocol);
void (*socket_post_create) (struct socket * sock, int family,
int type, int protocol);
@@ -2433,6 +2460,20 @@
#ifdef CONFIG_SECURITY_NETWORK
+static inline int security_unix_stream_connect(struct socket * sock,
+ struct socket * other,
+ struct sock * newsk)
+{
+ return security_ops->unix_stream_connect(sock, other, newsk);
+}
+
+
+static inline int security_unix_may_send(struct socket * sock,
+ struct socket * other)
+{
+ return security_ops->unix_may_send(sock, other);
+}
+
static inline int security_socket_create (int family, int type, int protocol)
{
return security_ops->socket_create(family, type, protocol);
@@ -2596,6 +2637,19 @@
#else /* CONFIG_SECURITY_NETWORK */
+static inline int security_unix_stream_connect(struct socket * sock,
+ struct socket * other,
+ struct sock * newsk)
+{
+ return 0;
+}
+
+static inline int security_unix_may_send(struct socket * sock,
+ struct socket * other)
+{
+ return 0;
+}
+
static inline int security_socket_create (int family, int type, int protocol)
{
return 0;
diff -urN -X dontdiff linux-2.5.59.w0/net/unix/af_unix.c linux-2.5.59.w1/net/unix/af_unix.c
--- linux-2.5.59.w0/net/unix/af_unix.c Sat Jan 11 10:47:20 2003
+++ linux-2.5.59.w1/net/unix/af_unix.c Thu Jan 30 21:41:38 2003
@@ -115,6 +115,7 @@
#include <linux/rtnetlink.h>
#include <linux/mount.h>
#include <net/checksum.h>
+#include <linux/security.h>
int sysctl_unix_max_dgram_qlen = 10;
@@ -816,6 +817,11 @@
err = -EPERM;
if (!unix_may_send(sk, other))
goto out_unlock;
+
+ err = security_unix_may_send(sk->socket, other->socket);
+ if (err)
+ goto out_unlock;
+
} else {
/*
* 1003.1g breaking connected state with AF_UNSPEC
@@ -981,6 +987,12 @@
goto restart;
}
+ err = security_unix_stream_connect(sock, other->socket, newsk);
+ if (err) {
+ unix_state_wunlock(sk);
+ goto out_unlock;
+ }
+
/* The way is open! Fastly set all the necessary fields... */
sock_hold(sk);
@@ -1280,6 +1292,10 @@
if (other->shutdown&RCV_SHUTDOWN)
goto out_unlock;
+ err = security_unix_may_send(sk->socket, other->socket);
+ if (err)
+ goto out_unlock;
+
if (unix_peer(other) != sk &&
skb_queue_len(&other->receive_queue) > other->max_ack_backlog) {
if (!timeo) {
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:41:57 2003
+++ linux-2.5.59.w1/security/dummy.c Thu Jan 30 21:41:38 2003
@@ -625,6 +625,19 @@
#ifdef CONFIG_SECURITY_NETWORK
+static int dummy_unix_stream_connect (struct socket *sock,
+ struct socket *other,
+ struct sock *newsk)
+{
+ return 0;
+}
+
+static int dummy_unix_may_send (struct socket *sock,
+ struct socket *other)
+{
+ return 0;
+}
+
static int dummy_socket_create (int family, int type, int protocol)
{
return 0;
@@ -910,6 +923,8 @@
set_to_dummy_if_null(ops, netlink_recv);
set_to_dummy_if_null(ops, ip_decode_options);
#ifdef CONFIG_SECURITY_NETWORK
+ set_to_dummy_if_null(ops, unix_stream_connect);
+ set_to_dummy_if_null(ops, unix_may_send);
set_to_dummy_if_null(ops, socket_create);
set_to_dummy_if_null(ops, socket_post_create);
set_to_dummy_if_null(ops, socket_bind);
^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: [PATCH] LSM networking: netlink hooks for 2.5.59 (6/8)
2003-01-30 23:10 ` [PATCH] LSM networking: netlink hooks for 2.5.59 (6/8) James Morris
2003-01-30 23:17 ` [PATCH] LSM networking: af_unix hooks for 2.5.59 (7/8) James Morris
@ 2003-01-30 23:19 ` David S. Miller
1 sibling, 0 replies; 14+ messages in thread
From: David S. Miller @ 2003-01-30 23:19 UTC (permalink / raw)
To: jmorris; +Cc: kuznet, netdev, linux-security-module
This one is not acceptable, you're adding a function call to
every netlink SKB receive even in the case where security
is disabled.
Capability testing is a very simple bit test, there is no
justification for calling these cap_netlink_{send,recv}() things
externally for such a simple operation when security is disabled.
It is things like this that make me still totally hate the networking
security changes. It is like a virus that is spreading throughout the
entire tree. It is a bunch of strange tests that have to be
maintained which do external calls to modules that are not even in the
source tree so I can't even see how the callbacks are used (no, the
fact that there is documentation of the callback doesn't change this
issue, and no I'm not going to some site to download a bunch of
security modules everytime I need to make changes in these areas).
Frankly, while I'm very happy about the fixup of the security
overhead, these changes are still way too invasive. This stuff
is garbage.
^ permalink raw reply [flat|nested] 14+ messages in thread
* [PATCH] LSM networking: tcp hooks for 2.5.59 (8/8)
2003-01-30 23:17 ` [PATCH] LSM networking: af_unix hooks for 2.5.59 (7/8) James Morris
@ 2003-01-30 23:22 ` James Morris
2003-01-30 23:25 ` David S. Miller
0 siblings, 1 reply; 14+ messages in thread
From: James Morris @ 2003-01-30 23:22 UTC (permalink / raw)
To: David S. Miller, kuznet; +Cc: netdev, linux-security-module
include/linux/security.h | 103 +++++++++++++++++++++++++++++++++++++++++++++++
include/linux/tcp.h | 11 +++++
include/net/tcp.h | 26 ++++++++++-
net/ipv4/syncookies.c | 3 +
net/ipv4/tcp_ipv4.c | 4 +
net/ipv4/tcp_minisocks.c | 6 ++
security/dummy.c | 36 ++++++++++++++++
7 files changed, 186 insertions(+), 3 deletions(-)
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:43:00 2003
+++ linux-2.5.59.w1/include/linux/security.h Thu Jan 30 21:44:11 2003
@@ -77,6 +77,7 @@
struct nfsctl_arg;
struct sched_param;
struct swap_info_struct;
+struct open_request;
#ifdef CONFIG_SECURITY
@@ -594,6 +595,38 @@
* is being reparented to the init task.
* @p contains the task_struct for the kernel thread.
*
+ * Security hooks for TCP networking.
+ *
+ * @open_request_alloc_security:
+ * Allocate the security blob for an open_request structure. The
+ * req->security field is initialized to NULL when the structure is
+ * allocated.
+ * @req Pointer to the open_request structure.
+ * Return 0 if successful, or -ENOMEM on out of memory condition.
+ * @open_request_free_security:
+ * Free the security blob for an open_request structure.
+ * @req Pointer to the open_request structure.
+ * @tcp_connection_request:
+ * A new connection is being requested on a server. This hook allows
+ * security information to be attached to the new connection request.
+ * @sk contains the listening sock.
+ * @skb contains the incoming network packet.
+ * @req contains the open_request structure.
+ * @tcp_synack:
+ * A TCP SYN-ACK packet is being sent out, the second part of the TCP
+ * three-way handshake for a new connection.
+ * @sk contains the listening sock.
+ * @skb contains the outgoing network packet.
+ * @req contains the open_request structure.
+ * @tcp_create_openreq_child:
+ * A new connection is being established on a TCP sock. This hook allows
+ * the association of security information with the new sock as it is
+ * being created.
+ * @sk contains the listening sock.
+ * @newsk contains the sock associated with the new connection.
+ * @skb contains the incoming network packet that finalized the connection.
+ * @req contains the open_request structure.
+ *
* Security hooks for socket operations.
*
* @socket_create:
@@ -1224,6 +1257,16 @@
struct security_operations *ops);
#ifdef CONFIG_SECURITY_NETWORK
+ int (*open_request_alloc_security) (struct open_request * req);
+ void (*open_request_free_security) (struct open_request * req);
+ void (*tcp_connection_request) (struct sock * sk, struct sk_buff * skb,
+ struct open_request * req);
+ void (*tcp_synack) (struct sock * sk, struct sk_buff * skb,
+ struct open_request * req);
+ void (*tcp_create_openreq_child) (struct sock * sk, struct sock * newsk,
+ struct sk_buff * skb,
+ struct open_request * req);
+
int (*unix_stream_connect) (struct socket * sock,
struct socket * other, struct sock * newsk);
int (*unix_may_send) (struct socket * sock, struct socket * other);
@@ -2460,6 +2503,38 @@
#ifdef CONFIG_SECURITY_NETWORK
+static inline int security_open_request_alloc (struct open_request * req)
+{
+ return security_ops->open_request_alloc_security (req);
+}
+
+static inline void security_open_request_free (struct open_request * req)
+{
+ security_ops->open_request_free_security (req);
+}
+
+static inline void security_tcp_connection_request(struct sock * sk,
+ struct sk_buff * skb,
+ struct open_request * req)
+{
+ security_ops->tcp_connection_request(sk, skb, req);
+}
+
+static inline void security_tcp_synack(struct sock * sk,
+ struct sk_buff * skb,
+ struct open_request * req)
+{
+ security_ops->tcp_synack(sk, skb, req);
+}
+
+static inline void security_tcp_create_openreq_child(struct sock * sk,
+ struct sock * newsk,
+ struct sk_buff * skb,
+ struct open_request * req)
+{
+ security_ops->tcp_create_openreq_child(sk, newsk, skb, req);
+}
+
static inline int security_unix_stream_connect(struct socket * sock,
struct socket * other,
struct sock * newsk)
@@ -2637,6 +2712,34 @@
#else /* CONFIG_SECURITY_NETWORK */
+static inline int security_open_request_alloc (struct open_request * req)
+{
+ return 0;
+}
+
+static inline void security_open_request_free (struct open_request * req)
+{
+}
+
+static inline void security_tcp_connection_request(struct sock * sk,
+ struct sk_buff * skb,
+ struct open_request * req)
+{
+}
+
+static inline void security_tcp_synack(struct sock * sk,
+ struct sk_buff * skb,
+ struct open_request * req)
+{
+}
+
+static inline void security_tcp_create_openreq_child(struct sock * sk,
+ struct sock * newsk,
+ struct sk_buff * skb,
+ struct open_request * req)
+{
+}
+
static inline int security_unix_stream_connect(struct socket * sock,
struct socket * other,
struct sock * newsk)
diff -urN -X dontdiff linux-2.5.59.w0/include/linux/tcp.h linux-2.5.59.w1/include/linux/tcp.h
--- linux-2.5.59.w0/include/linux/tcp.h Sat Oct 19 19:57:49 2002
+++ linux-2.5.59.w1/include/linux/tcp.h Thu Jan 30 21:44:11 2003
@@ -382,4 +382,15 @@
#define tcp_sk(__sk) (&((struct tcp_sock *)__sk)->tcp)
+static inline void clone_tcp_sk(struct sock *newsk, struct sock *sk) {
+#ifdef CONFIG_SECURITY_NETWORK
+/* Save/restore the LSM security pointer around the copy */
+ void *sptr = newsk->security;
+ memcpy(newsk, sk, sizeof(struct tcp_sock));
+ newsk->security = sptr;
+#else
+ memcpy(newsk, sk, sizeof(struct tcp_sock));
+#endif
+}
+
#endif /* _LINUX_TCP_H */
diff -urN -X dontdiff linux-2.5.59.w0/include/net/tcp.h linux-2.5.59.w1/include/net/tcp.h
--- linux-2.5.59.w0/include/net/tcp.h Sat Jan 11 10:47:20 2003
+++ linux-2.5.59.w1/include/net/tcp.h Thu Jan 30 21:44:11 2003
@@ -29,6 +29,7 @@
#include <linux/slab.h>
#include <linux/cache.h>
#include <linux/percpu.h>
+#include <linux/security.h>
#include <net/checksum.h>
#include <net/sock.h>
#if defined(CONFIG_IPV6) || defined (CONFIG_IPV6_MODULE)
@@ -533,13 +534,34 @@
struct tcp_v6_open_req v6_req;
#endif
} af;
+#ifdef CONFIG_SECURITY_NETWORK
+ /* LSM security field */
+ void *security;
+#endif
};
/* SLAB cache for open requests. */
extern kmem_cache_t *tcp_openreq_cachep;
-#define tcp_openreq_alloc() kmem_cache_alloc(tcp_openreq_cachep, SLAB_ATOMIC)
-#define tcp_openreq_fastfree(req) kmem_cache_free(tcp_openreq_cachep, req)
+static inline struct open_request *tcp_openreq_alloc(void)
+{
+ struct open_request *req =
+ kmem_cache_alloc(tcp_openreq_cachep, SLAB_ATOMIC);
+
+ if (req != NULL) {
+ if (security_open_request_alloc(req)) {
+ kmem_cache_free(tcp_openreq_cachep, req);
+ return NULL;
+ }
+ }
+ return req;
+}
+
+static inline void tcp_openreq_fastfree(struct open_request *req)
+{
+ security_open_request_free(req);
+ kmem_cache_free(tcp_openreq_cachep, req);
+}
static inline void tcp_openreq_free(struct open_request *req)
{
diff -urN -X dontdiff linux-2.5.59.w0/net/ipv4/syncookies.c linux-2.5.59.w1/net/ipv4/syncookies.c
--- linux-2.5.59.w0/net/ipv4/syncookies.c Thu Oct 31 16:01:08 2002
+++ linux-2.5.59.w1/net/ipv4/syncookies.c Thu Jan 30 21:44:11 2003
@@ -17,6 +17,7 @@
#include <linux/tcp.h>
#include <linux/slab.h>
#include <linux/random.h>
+#include <linux/security.h>
#include <net/tcp.h>
extern int sysctl_tcp_syncookies;
@@ -188,6 +189,8 @@
}
}
+ security_tcp_connection_request(sk, skb, req);
+
/* Try to redo what tcp_v4_send_synack did. */
req->window_clamp = dst_metric(&rt->u.dst, RTAX_WINDOW);
tcp_select_initial_window(tcp_full_space(sk), req->mss,
diff -urN -X dontdiff linux-2.5.59.w0/net/ipv4/tcp_ipv4.c linux-2.5.59.w1/net/ipv4/tcp_ipv4.c
--- linux-2.5.59.w0/net/ipv4/tcp_ipv4.c Thu Jan 30 21:33:15 2003
+++ linux-2.5.59.w1/net/ipv4/tcp_ipv4.c Thu Jan 30 21:44:11 2003
@@ -1334,6 +1334,8 @@
if (skb) {
struct tcphdr *th = skb->h.th;
+ security_tcp_synack(sk, skb, req);
+
th->check = tcp_v4_check(th, skb->len,
req->af.v4_req.loc_addr,
req->af.v4_req.rmt_addr,
@@ -1550,6 +1552,8 @@
}
req->snt_isn = isn;
+ security_tcp_connection_request(sk, skb, req);
+
if (tcp_v4_send_synack(sk, req, dst))
goto drop_and_free;
diff -urN -X dontdiff linux-2.5.59.w0/net/ipv4/tcp_minisocks.c linux-2.5.59.w1/net/ipv4/tcp_minisocks.c
--- linux-2.5.59.w0/net/ipv4/tcp_minisocks.c Thu Jan 9 16:08:27 2003
+++ linux-2.5.59.w1/net/ipv4/tcp_minisocks.c Thu Jan 30 21:44:11 2003
@@ -23,6 +23,7 @@
#include <linux/config.h>
#include <linux/mm.h>
#include <linux/sysctl.h>
+#include <linux/security.h>
#include <net/tcp.h>
#include <net/inet_common.h>
#include <net/xfrm.h>
@@ -654,7 +655,8 @@
struct sk_filter *filter;
#endif
- memcpy(newsk, sk, sizeof(struct tcp_sock));
+ clone_tcp_sk(newsk, sk);
+
newsk->state = TCP_SYN_RECV;
/* SANITY */
@@ -801,6 +803,8 @@
newsk->no_largesend = 1;
TCP_INC_STATS_BH(TcpPassiveOpens);
+
+ security_tcp_create_openreq_child(sk, newsk, skb, req);
}
return newsk;
}
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:43:00 2003
+++ linux-2.5.59.w1/security/dummy.c Thu Jan 30 22:14:55 2003
@@ -21,6 +21,7 @@
#include <linux/skbuff.h>
#include <linux/netlink.h>
#include <net/sock.h>
+#include <net/tcp.h>
static int dummy_ptrace (struct task_struct *parent, struct task_struct *child)
{
@@ -625,6 +626,36 @@
#ifdef CONFIG_SECURITY_NETWORK
+static int dummy_open_request_alloc_security(struct open_request * req)
+{
+ req->security = NULL;
+ return 0;
+}
+
+static void dummy_open_request_free_security(struct open_request * req)
+{
+ return;
+}
+
+static void dummy_tcp_connection_request(struct sock *sk, struct sk_buff * skb,
+ struct open_request *req)
+{
+ return;
+}
+
+static void dummy_tcp_synack(struct sock *sk, struct sk_buff * skb,
+ struct open_request *req)
+{
+ return;
+}
+
+static void dummy_tcp_create_openreq_child(struct sock *sk, struct sock *newsk,
+ struct sk_buff *skb,
+ struct open_request *req)
+{
+ return;
+}
+
static int dummy_unix_stream_connect (struct socket *sock,
struct socket *other,
struct sock *newsk)
@@ -923,6 +954,11 @@
set_to_dummy_if_null(ops, netlink_recv);
set_to_dummy_if_null(ops, ip_decode_options);
#ifdef CONFIG_SECURITY_NETWORK
+ set_to_dummy_if_null(ops, open_request_alloc_security);
+ set_to_dummy_if_null(ops, open_request_free_security);
+ set_to_dummy_if_null(ops, tcp_connection_request);
+ set_to_dummy_if_null(ops, tcp_synack);
+ set_to_dummy_if_null(ops, tcp_create_openreq_child);
set_to_dummy_if_null(ops, unix_stream_connect);
set_to_dummy_if_null(ops, unix_may_send);
set_to_dummy_if_null(ops, socket_create);
^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: [PATCH] LSM networking: tcp hooks for 2.5.59 (8/8)
2003-01-30 23:22 ` [PATCH] LSM networking: tcp hooks for 2.5.59 (8/8) James Morris
@ 2003-01-30 23:25 ` David S. Miller
2003-01-31 0:15 ` James Morris
0 siblings, 1 reply; 14+ messages in thread
From: David S. Miller @ 2003-01-30 23:25 UTC (permalink / raw)
To: jmorris; +Cc: kuznet, netdev, linux-security-module
No, no, and no.
This stuff will not pass.
There is no way in hell we're going to insert this security crap into
the actual protocol implementations. I was right in seeing this as a
virus that will eventually infect the whole tree.
None of these security modules should know jack anything about open
requests and other TCP internals.
This stuff is totally unmaintainable garbage. And I do not want to
hear "well how can we implement xxx which we need for yyy" because it
isn't my problem that you can't figure out a clean way to do this
stuff.
Linus would similarly barf if he was given a patch that added
hooks like "security_ext2_foo()".
I totally reject this networking security stuff for 2.6.x
^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: [PATCH] LSM networking: tcp hooks for 2.5.59 (8/8)
2003-01-30 23:25 ` David S. Miller
@ 2003-01-31 0:15 ` James Morris
2003-01-31 0:16 ` David S. Miller
0 siblings, 1 reply; 14+ messages in thread
From: James Morris @ 2003-01-31 0:15 UTC (permalink / raw)
To: David S. Miller; +Cc: kuznet, netdev, linux-security-module
On Thu, 30 Jan 2003, David S. Miller wrote:
> I totally reject this networking security stuff for 2.6.x
Ok. Thanks for looking at it.
- James
--
James Morris
<jmorris@intercode.com.au>
^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: [PATCH] LSM networking: tcp hooks for 2.5.59 (8/8)
2003-01-31 0:15 ` James Morris
@ 2003-01-31 0:16 ` David S. Miller
2003-02-01 0:12 ` James Morris
0 siblings, 1 reply; 14+ messages in thread
From: David S. Miller @ 2003-01-31 0:16 UTC (permalink / raw)
To: jmorris; +Cc: kuznet, netdev, linux-security-module
From: James Morris <jmorris@intercode.com.au>
Date: Fri, 31 Jan 2003 11:15:22 +1100 (EST)
On Thu, 30 Jan 2003, David S. Miller wrote:
> I totally reject this networking security stuff for 2.6.x
Ok. Thanks for looking at it.
James, do not take my comments too harshly please.
I realize the amount of work that went into these
changes and I do appreciate that.
The big problem is that the TCP bits had no apparent attempt to
abstract things out. What is going to happen, for example, when net
protocol FOO makes mini-sockets too? Will we make more
security_FOO_*() hooks or will we get smart and abstract this
technique somehow?
See, if I saw things like:
openreq = sock_make_minisock(sizeof(struct openreq));
then the changes would be more acceptable.
The net/socket.c stuff looks fine. All the stuff that makes decisions
based upon packets is highly questionable. Netfilter can do all of
this work, it even has connection tracking infrastructure for TCP
connections.
I think with the net/socket.c stuff to take care of the user
side and some ingenious netfilter hacks for the packet side,
you could accomplish everything you need for the security stuff.
If you think this is implementable, then I'll happily accept the
net/socket.c stuff and even the af_unix hack, with the assumption
being that the rest can be handled by netfilter or something similar.
Oh yes, I'd also take the netlink capability thing too as long as it
was inlined properly for the no-security case.
^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: [PATCH] LSM networking: tcp hooks for 2.5.59 (8/8)
2003-01-31 0:16 ` David S. Miller
@ 2003-02-01 0:12 ` James Morris
0 siblings, 0 replies; 14+ messages in thread
From: James Morris @ 2003-02-01 0:12 UTC (permalink / raw)
To: David S. Miller; +Cc: kuznet, netdev, linux-security-module
On Thu, 30 Jan 2003, David S. Miller wrote:
> If you think this is implementable, then I'll happily accept the
> net/socket.c stuff and even the af_unix hack, with the assumption
> being that the rest can be handled by netfilter or something similar.
> Oh yes, I'd also take the netlink capability thing too as long as it
> was inlined properly for the no-security case.
Explicitly labeled networking and the SELinux extended sockets API
probably can't be supported with just these hooks and Netfilter.
However, this subset of the networking hooks will still be very useful in
general, and we'll rework the patch accordingly.
- James
--
James Morris
<jmorris@intercode.com.au>
^ permalink raw reply [flat|nested] 14+ messages in thread
end of thread, other threads:[~2003-02-01 0:12 UTC | newest]
Thread overview: 14+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2003-01-30 22:42 [PATCH] LSM networking: introduction (0/8) James Morris
2003-01-30 22:46 ` [PATCH] LSM networking: kconfig (1/8) James Morris
2003-01-30 22:51 ` [PATCH] LSM networking: netdev hooks for 2.5.59 (2/8) James Morris
2003-01-30 22:56 ` [PATCH] LSM networking: skb hooks for 2.5.59 (3/8) James Morris
2003-01-30 23:01 ` [PATCH] LSM networking: socket hooks for 2.5.59 (4/8) James Morris
2003-01-30 23:06 ` [PATCH] LSM networking: ipv4 hooks for 2.5.59 (5/8) James Morris
2003-01-30 23:10 ` [PATCH] LSM networking: netlink hooks for 2.5.59 (6/8) James Morris
2003-01-30 23:17 ` [PATCH] LSM networking: af_unix hooks for 2.5.59 (7/8) James Morris
2003-01-30 23:22 ` [PATCH] LSM networking: tcp hooks for 2.5.59 (8/8) James Morris
2003-01-30 23:25 ` David S. Miller
2003-01-31 0:15 ` James Morris
2003-01-31 0:16 ` David S. Miller
2003-02-01 0:12 ` James Morris
2003-01-30 23:19 ` [PATCH] LSM networking: netlink hooks for 2.5.59 (6/8) David S. Miller
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).