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);
|