aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--include/linux/pfkeyv2.h13
-rw-r--r--include/linux/security.h132
-rw-r--r--include/linux/xfrm.h29
-rw-r--r--include/net/flow.h7
-rw-r--r--include/net/xfrm.h27
-rw-r--r--net/core/flow.c8
-rw-r--r--net/key/af_key.c197
-rw-r--r--net/xfrm/xfrm_policy.c88
-rw-r--r--net/xfrm/xfrm_state.c9
-rw-r--r--net/xfrm/xfrm_user.c148
-rw-r--r--security/Kconfig13
-rw-r--r--security/dummy.c45
12 files changed, 655 insertions, 61 deletions
diff --git a/include/linux/pfkeyv2.h b/include/linux/pfkeyv2.h
index 724066778aff..6351c4055ace 100644
--- a/include/linux/pfkeyv2.h
+++ b/include/linux/pfkeyv2.h
@@ -216,6 +216,16 @@ struct sadb_x_nat_t_port {
216} __attribute__((packed)); 216} __attribute__((packed));
217/* sizeof(struct sadb_x_nat_t_port) == 8 */ 217/* sizeof(struct sadb_x_nat_t_port) == 8 */
218 218
219/* Generic LSM security context */
220struct sadb_x_sec_ctx {
221 uint16_t sadb_x_sec_len;
222 uint16_t sadb_x_sec_exttype;
223 uint8_t sadb_x_ctx_alg; /* LSMs: e.g., selinux == 1 */
224 uint8_t sadb_x_ctx_doi;
225 uint16_t sadb_x_ctx_len;
226} __attribute__((packed));
227/* sizeof(struct sadb_sec_ctx) = 8 */
228
219/* Message types */ 229/* Message types */
220#define SADB_RESERVED 0 230#define SADB_RESERVED 0
221#define SADB_GETSPI 1 231#define SADB_GETSPI 1
@@ -325,7 +335,8 @@ struct sadb_x_nat_t_port {
325#define SADB_X_EXT_NAT_T_SPORT 21 335#define SADB_X_EXT_NAT_T_SPORT 21
326#define SADB_X_EXT_NAT_T_DPORT 22 336#define SADB_X_EXT_NAT_T_DPORT 22
327#define SADB_X_EXT_NAT_T_OA 23 337#define SADB_X_EXT_NAT_T_OA 23
328#define SADB_EXT_MAX 23 338#define SADB_X_EXT_SEC_CTX 24
339#define SADB_EXT_MAX 24
329 340
330/* Identity Extension values */ 341/* Identity Extension values */
331#define SADB_IDENTTYPE_RESERVED 0 342#define SADB_IDENTTYPE_RESERVED 0
diff --git a/include/linux/security.h b/include/linux/security.h
index f7e0ae018712..ef753654daa5 100644
--- a/include/linux/security.h
+++ b/include/linux/security.h
@@ -59,6 +59,12 @@ struct sk_buff;
59struct sock; 59struct sock;
60struct sockaddr; 60struct sockaddr;
61struct socket; 61struct socket;
62struct flowi;
63struct dst_entry;
64struct xfrm_selector;
65struct xfrm_policy;
66struct xfrm_state;
67struct xfrm_user_sec_ctx;
62 68
63extern int cap_netlink_send(struct sock *sk, struct sk_buff *skb); 69extern int cap_netlink_send(struct sock *sk, struct sk_buff *skb);
64extern int cap_netlink_recv(struct sk_buff *skb); 70extern int cap_netlink_recv(struct sk_buff *skb);
@@ -788,6 +794,52 @@ struct swap_info_struct;
788 * which is used to copy security attributes between local stream sockets. 794 * which is used to copy security attributes between local stream sockets.
789 * @sk_free_security: 795 * @sk_free_security:
790 * Deallocate security structure. 796 * Deallocate security structure.
797 * @sk_getsid:
798 * Retrieve the LSM-specific sid for the sock to enable caching of network
799 * authorizations.
800 *
801 * Security hooks for XFRM operations.
802 *
803 * @xfrm_policy_alloc_security:
804 * @xp contains the xfrm_policy being added to Security Policy Database
805 * used by the XFRM system.
806 * @sec_ctx contains the security context information being provided by
807 * the user-level policy update program (e.g., setkey).
808 * Allocate a security structure to the xp->selector.security field.
809 * The security field is initialized to NULL when the xfrm_policy is
810 * allocated.
811 * Return 0 if operation was successful (memory to allocate, legal context)
812 * @xfrm_policy_clone_security:
813 * @old contains an existing xfrm_policy in the SPD.
814 * @new contains a new xfrm_policy being cloned from old.
815 * Allocate a security structure to the new->selector.security field
816 * that contains the information from the old->selector.security field.
817 * Return 0 if operation was successful (memory to allocate).
818 * @xfrm_policy_free_security:
819 * @xp contains the xfrm_policy
820 * Deallocate xp->selector.security.
821 * @xfrm_state_alloc_security:
822 * @x contains the xfrm_state being added to the Security Association
823 * Database by the XFRM system.
824 * @sec_ctx contains the security context information being provided by
825 * the user-level SA generation program (e.g., setkey or racoon).
826 * Allocate a security structure to the x->sel.security field. The
827 * security field is initialized to NULL when the xfrm_state is
828 * allocated.
829 * Return 0 if operation was successful (memory to allocate, legal context).
830 * @xfrm_state_free_security:
831 * @x contains the xfrm_state.
832 * Deallocate x>sel.security.
833 * @xfrm_policy_lookup:
834 * @xp contains the xfrm_policy for which the access control is being
835 * checked.
836 * @sk_sid contains the sock security label that is used to authorize
837 * access to the policy xp.
838 * @dir contains the direction of the flow (input or output).
839 * Check permission when a sock selects a xfrm_policy for processing
840 * XFRMs on a packet. The hook is called when selecting either a
841 * per-socket policy or a generic xfrm policy.
842 * Return 0 if permission is granted.
791 * 843 *
792 * Security hooks affecting all Key Management operations 844 * Security hooks affecting all Key Management operations
793 * 845 *
@@ -1237,8 +1289,18 @@ struct security_operations {
1237 int (*socket_getpeersec) (struct socket *sock, char __user *optval, int __user *optlen, unsigned len); 1289 int (*socket_getpeersec) (struct socket *sock, char __user *optval, int __user *optlen, unsigned len);
1238 int (*sk_alloc_security) (struct sock *sk, int family, gfp_t priority); 1290 int (*sk_alloc_security) (struct sock *sk, int family, gfp_t priority);
1239 void (*sk_free_security) (struct sock *sk); 1291 void (*sk_free_security) (struct sock *sk);
1292 unsigned int (*sk_getsid) (struct sock *sk, struct flowi *fl, u8 dir);
1240#endif /* CONFIG_SECURITY_NETWORK */ 1293#endif /* CONFIG_SECURITY_NETWORK */
1241 1294
1295#ifdef CONFIG_SECURITY_NETWORK_XFRM
1296 int (*xfrm_policy_alloc_security) (struct xfrm_policy *xp, struct xfrm_user_sec_ctx *sec_ctx);
1297 int (*xfrm_policy_clone_security) (struct xfrm_policy *old, struct xfrm_policy *new);
1298 void (*xfrm_policy_free_security) (struct xfrm_policy *xp);
1299 int (*xfrm_state_alloc_security) (struct xfrm_state *x, struct xfrm_user_sec_ctx *sec_ctx);
1300 void (*xfrm_state_free_security) (struct xfrm_state *x);
1301 int (*xfrm_policy_lookup)(struct xfrm_policy *xp, u32 sk_sid, u8 dir);
1302#endif /* CONFIG_SECURITY_NETWORK_XFRM */
1303
1242 /* key management security hooks */ 1304 /* key management security hooks */
1243#ifdef CONFIG_KEYS 1305#ifdef CONFIG_KEYS
1244 int (*key_alloc)(struct key *key); 1306 int (*key_alloc)(struct key *key);
@@ -2679,6 +2741,11 @@ static inline void security_sk_free(struct sock *sk)
2679{ 2741{
2680 return security_ops->sk_free_security(sk); 2742 return security_ops->sk_free_security(sk);
2681} 2743}
2744
2745static inline unsigned int security_sk_sid(struct sock *sk, struct flowi *fl, u8 dir)
2746{
2747 return security_ops->sk_getsid(sk, fl, dir);
2748}
2682#else /* CONFIG_SECURITY_NETWORK */ 2749#else /* CONFIG_SECURITY_NETWORK */
2683static inline int security_unix_stream_connect(struct socket * sock, 2750static inline int security_unix_stream_connect(struct socket * sock,
2684 struct socket * other, 2751 struct socket * other,
@@ -2795,8 +2862,73 @@ static inline int security_sk_alloc(struct sock *sk, int family, gfp_t priority)
2795static inline void security_sk_free(struct sock *sk) 2862static inline void security_sk_free(struct sock *sk)
2796{ 2863{
2797} 2864}
2865
2866static inline unsigned int security_sk_sid(struct sock *sk, struct flowi *fl, u8 dir)
2867{
2868 return 0;
2869}
2798#endif /* CONFIG_SECURITY_NETWORK */ 2870#endif /* CONFIG_SECURITY_NETWORK */
2799 2871
2872#ifdef CONFIG_SECURITY_NETWORK_XFRM
2873static inline int security_xfrm_policy_alloc(struct xfrm_policy *xp, struct xfrm_user_sec_ctx *sec_ctx)
2874{
2875 return security_ops->xfrm_policy_alloc_security(xp, sec_ctx);
2876}
2877
2878static inline int security_xfrm_policy_clone(struct xfrm_policy *old, struct xfrm_policy *new)
2879{
2880 return security_ops->xfrm_policy_clone_security(old, new);
2881}
2882
2883static inline void security_xfrm_policy_free(struct xfrm_policy *xp)
2884{
2885 security_ops->xfrm_policy_free_security(xp);
2886}
2887
2888static inline int security_xfrm_state_alloc(struct xfrm_state *x, struct xfrm_user_sec_ctx *sec_ctx)
2889{
2890 return security_ops->xfrm_state_alloc_security(x, sec_ctx);
2891}
2892
2893static inline void security_xfrm_state_free(struct xfrm_state *x)
2894{
2895 security_ops->xfrm_state_free_security(x);
2896}
2897
2898static inline int security_xfrm_policy_lookup(struct xfrm_policy *xp, u32 sk_sid, u8 dir)
2899{
2900 return security_ops->xfrm_policy_lookup(xp, sk_sid, dir);
2901}
2902#else /* CONFIG_SECURITY_NETWORK_XFRM */
2903static inline int security_xfrm_policy_alloc(struct xfrm_policy *xp, struct xfrm_user_sec_ctx *sec_ctx)
2904{
2905 return 0;
2906}
2907
2908static inline int security_xfrm_policy_clone(struct xfrm_policy *old, struct xfrm_policy *new)
2909{
2910 return 0;
2911}
2912
2913static inline void security_xfrm_policy_free(struct xfrm_policy *xp)
2914{
2915}
2916
2917static inline int security_xfrm_state_alloc(struct xfrm_state *x, struct xfrm_user_sec_ctx *sec_ctx)
2918{
2919 return 0;
2920}
2921
2922static inline void security_xfrm_state_free(struct xfrm_state *x)
2923{
2924}
2925
2926static inline int security_xfrm_policy_lookup(struct xfrm_policy *xp, u32 sk_sid, u8 dir)
2927{
2928 return 0;
2929}
2930#endif /* CONFIG_SECURITY_NETWORK_XFRM */
2931
2800#ifdef CONFIG_KEYS 2932#ifdef CONFIG_KEYS
2801#ifdef CONFIG_SECURITY 2933#ifdef CONFIG_SECURITY
2802static inline int security_key_alloc(struct key *key) 2934static inline int security_key_alloc(struct key *key)
diff --git a/include/linux/xfrm.h b/include/linux/xfrm.h
index 0fb077d68441..82fbb758e28f 100644
--- a/include/linux/xfrm.h
+++ b/include/linux/xfrm.h
@@ -27,6 +27,22 @@ struct xfrm_id
27 __u8 proto; 27 __u8 proto;
28}; 28};
29 29
30struct xfrm_sec_ctx {
31 __u8 ctx_doi;
32 __u8 ctx_alg;
33 __u16 ctx_len;
34 __u32 ctx_sid;
35 char ctx_str[0];
36};
37
38/* Security Context Domains of Interpretation */
39#define XFRM_SC_DOI_RESERVED 0
40#define XFRM_SC_DOI_LSM 1
41
42/* Security Context Algorithms */
43#define XFRM_SC_ALG_RESERVED 0
44#define XFRM_SC_ALG_SELINUX 1
45
30/* Selector, used as selector both on policy rules (SPD) and SAs. */ 46/* Selector, used as selector both on policy rules (SPD) and SAs. */
31 47
32struct xfrm_selector 48struct xfrm_selector
@@ -146,6 +162,18 @@ enum {
146 162
147#define XFRM_NR_MSGTYPES (XFRM_MSG_MAX + 1 - XFRM_MSG_BASE) 163#define XFRM_NR_MSGTYPES (XFRM_MSG_MAX + 1 - XFRM_MSG_BASE)
148 164
165/*
166 * Generic LSM security context for comunicating to user space
167 * NOTE: Same format as sadb_x_sec_ctx
168 */
169struct xfrm_user_sec_ctx {
170 __u16 len;
171 __u16 exttype;
172 __u8 ctx_alg; /* LSMs: e.g., selinux == 1 */
173 __u8 ctx_doi;
174 __u16 ctx_len;
175};
176
149struct xfrm_user_tmpl { 177struct xfrm_user_tmpl {
150 struct xfrm_id id; 178 struct xfrm_id id;
151 __u16 family; 179 __u16 family;
@@ -176,6 +204,7 @@ enum xfrm_attr_type_t {
176 XFRMA_TMPL, /* 1 or more struct xfrm_user_tmpl */ 204 XFRMA_TMPL, /* 1 or more struct xfrm_user_tmpl */
177 XFRMA_SA, 205 XFRMA_SA,
178 XFRMA_POLICY, 206 XFRMA_POLICY,
207 XFRMA_SEC_CTX, /* struct xfrm_sec_ctx */
179 __XFRMA_MAX 208 __XFRMA_MAX
180 209
181#define XFRMA_MAX (__XFRMA_MAX - 1) 210#define XFRMA_MAX (__XFRMA_MAX - 1)
diff --git a/include/net/flow.h b/include/net/flow.h
index 9a5c94b1a0ec..ec7eb86eb203 100644
--- a/include/net/flow.h
+++ b/include/net/flow.h
@@ -84,11 +84,12 @@ struct flowi {
84#define FLOW_DIR_OUT 1 84#define FLOW_DIR_OUT 1
85#define FLOW_DIR_FWD 2 85#define FLOW_DIR_FWD 2
86 86
87typedef void (*flow_resolve_t)(struct flowi *key, u16 family, u8 dir, 87struct sock;
88typedef void (*flow_resolve_t)(struct flowi *key, u32 sk_sid, u16 family, u8 dir,
88 void **objp, atomic_t **obj_refp); 89 void **objp, atomic_t **obj_refp);
89 90
90extern void *flow_cache_lookup(struct flowi *key, u16 family, u8 dir, 91extern void *flow_cache_lookup(struct flowi *key, u32 sk_sid, u16 family, u8 dir,
91 flow_resolve_t resolver); 92 flow_resolve_t resolver);
92extern void flow_cache_flush(void); 93extern void flow_cache_flush(void);
93extern atomic_t flow_cache_genid; 94extern atomic_t flow_cache_genid;
94 95
diff --git a/include/net/xfrm.h b/include/net/xfrm.h
index 1cdb87912137..487abca3ca6f 100644
--- a/include/net/xfrm.h
+++ b/include/net/xfrm.h
@@ -144,6 +144,9 @@ struct xfrm_state
144 * transformer. */ 144 * transformer. */
145 struct xfrm_type *type; 145 struct xfrm_type *type;
146 146
147 /* Security context */
148 struct xfrm_sec_ctx *security;
149
147 /* Private data of this transformer, format is opaque, 150 /* Private data of this transformer, format is opaque,
148 * interpreted by xfrm_type methods. */ 151 * interpreted by xfrm_type methods. */
149 void *data; 152 void *data;
@@ -298,6 +301,7 @@ struct xfrm_policy
298 __u8 flags; 301 __u8 flags;
299 __u8 dead; 302 __u8 dead;
300 __u8 xfrm_nr; 303 __u8 xfrm_nr;
304 struct xfrm_sec_ctx *security;
301 struct xfrm_tmpl xfrm_vec[XFRM_MAX_DEPTH]; 305 struct xfrm_tmpl xfrm_vec[XFRM_MAX_DEPTH];
302}; 306};
303 307
@@ -510,6 +514,25 @@ xfrm_selector_match(struct xfrm_selector *sel, struct flowi *fl,
510 return 0; 514 return 0;
511} 515}
512 516
517#ifdef CONFIG_SECURITY_NETWORK_XFRM
518/* If neither has a context --> match
519 * Otherwise, both must have a context and the sids, doi, alg must match
520 */
521static inline int xfrm_sec_ctx_match(struct xfrm_sec_ctx *s1, struct xfrm_sec_ctx *s2)
522{
523 return ((!s1 && !s2) ||
524 (s1 && s2 &&
525 (s1->ctx_sid == s2->ctx_sid) &&
526 (s1->ctx_doi == s2->ctx_doi) &&
527 (s1->ctx_alg == s2->ctx_alg)));
528}
529#else
530static inline int xfrm_sec_ctx_match(struct xfrm_sec_ctx *s1, struct xfrm_sec_ctx *s2)
531{
532 return 1;
533}
534#endif
535
513/* A struct encoding bundle of transformations to apply to some set of flow. 536/* A struct encoding bundle of transformations to apply to some set of flow.
514 * 537 *
515 * dst->child points to the next element of bundle. 538 * dst->child points to the next element of bundle.
@@ -878,8 +901,8 @@ static inline int xfrm_dst_lookup(struct xfrm_dst **dst, struct flowi *fl, unsig
878struct xfrm_policy *xfrm_policy_alloc(gfp_t gfp); 901struct xfrm_policy *xfrm_policy_alloc(gfp_t gfp);
879extern int xfrm_policy_walk(int (*func)(struct xfrm_policy *, int, int, void*), void *); 902extern int xfrm_policy_walk(int (*func)(struct xfrm_policy *, int, int, void*), void *);
880int xfrm_policy_insert(int dir, struct xfrm_policy *policy, int excl); 903int xfrm_policy_insert(int dir, struct xfrm_policy *policy, int excl);
881struct xfrm_policy *xfrm_policy_bysel(int dir, struct xfrm_selector *sel, 904struct xfrm_policy *xfrm_policy_bysel_ctx(int dir, struct xfrm_selector *sel,
882 int delete); 905 struct xfrm_sec_ctx *ctx, int delete);
883struct xfrm_policy *xfrm_policy_byid(int dir, u32 id, int delete); 906struct xfrm_policy *xfrm_policy_byid(int dir, u32 id, int delete);
884void xfrm_policy_flush(void); 907void xfrm_policy_flush(void);
885u32 xfrm_get_acqseq(void); 908u32 xfrm_get_acqseq(void);
diff --git a/net/core/flow.c b/net/core/flow.c
index 7e95b39de9fd..c4f25385029f 100644
--- a/net/core/flow.c
+++ b/net/core/flow.c
@@ -23,6 +23,7 @@
23#include <net/flow.h> 23#include <net/flow.h>
24#include <asm/atomic.h> 24#include <asm/atomic.h>
25#include <asm/semaphore.h> 25#include <asm/semaphore.h>
26#include <linux/security.h>
26 27
27struct flow_cache_entry { 28struct flow_cache_entry {
28 struct flow_cache_entry *next; 29 struct flow_cache_entry *next;
@@ -30,6 +31,7 @@ struct flow_cache_entry {
30 u8 dir; 31 u8 dir;
31 struct flowi key; 32 struct flowi key;
32 u32 genid; 33 u32 genid;
34 u32 sk_sid;
33 void *object; 35 void *object;
34 atomic_t *object_ref; 36 atomic_t *object_ref;
35}; 37};
@@ -162,7 +164,7 @@ static int flow_key_compare(struct flowi *key1, struct flowi *key2)
162 return 0; 164 return 0;
163} 165}
164 166
165void *flow_cache_lookup(struct flowi *key, u16 family, u8 dir, 167void *flow_cache_lookup(struct flowi *key, u32 sk_sid, u16 family, u8 dir,
166 flow_resolve_t resolver) 168 flow_resolve_t resolver)
167{ 169{
168 struct flow_cache_entry *fle, **head; 170 struct flow_cache_entry *fle, **head;
@@ -186,6 +188,7 @@ void *flow_cache_lookup(struct flowi *key, u16 family, u8 dir,
186 for (fle = *head; fle; fle = fle->next) { 188 for (fle = *head; fle; fle = fle->next) {
187 if (fle->family == family && 189 if (fle->family == family &&
188 fle->dir == dir && 190 fle->dir == dir &&
191 fle->sk_sid == sk_sid &&
189 flow_key_compare(key, &fle->key) == 0) { 192 flow_key_compare(key, &fle->key) == 0) {
190 if (fle->genid == atomic_read(&flow_cache_genid)) { 193 if (fle->genid == atomic_read(&flow_cache_genid)) {
191 void *ret = fle->object; 194 void *ret = fle->object;
@@ -210,6 +213,7 @@ void *flow_cache_lookup(struct flowi *key, u16 family, u8 dir,
210 *head = fle; 213 *head = fle;
211 fle->family = family; 214 fle->family = family;
212 fle->dir = dir; 215 fle->dir = dir;
216 fle->sk_sid = sk_sid;
213 memcpy(&fle->key, key, sizeof(*key)); 217 memcpy(&fle->key, key, sizeof(*key));
214 fle->object = NULL; 218 fle->object = NULL;
215 flow_count(cpu)++; 219 flow_count(cpu)++;
@@ -221,7 +225,7 @@ nocache:
221 void *obj; 225 void *obj;
222 atomic_t *obj_ref; 226 atomic_t *obj_ref;
223 227
224 resolver(key, family, dir, &obj, &obj_ref); 228 resolver(key, sk_sid, family, dir, &obj, &obj_ref);
225 229
226 if (fle) { 230 if (fle) {
227 fle->genid = atomic_read(&flow_cache_genid); 231 fle->genid = atomic_read(&flow_cache_genid);
diff --git a/net/key/af_key.c b/net/key/af_key.c
index 39031684b65c..d32f7791f1e4 100644
--- a/net/key/af_key.c
+++ b/net/key/af_key.c
@@ -336,6 +336,7 @@ static u8 sadb_ext_min_len[] = {
336 [SADB_X_EXT_NAT_T_SPORT] = (u8) sizeof(struct sadb_x_nat_t_port), 336 [SADB_X_EXT_NAT_T_SPORT] = (u8) sizeof(struct sadb_x_nat_t_port),
337 [SADB_X_EXT_NAT_T_DPORT] = (u8) sizeof(struct sadb_x_nat_t_port), 337 [SADB_X_EXT_NAT_T_DPORT] = (u8) sizeof(struct sadb_x_nat_t_port),
338 [SADB_X_EXT_NAT_T_OA] = (u8) sizeof(struct sadb_address), 338 [SADB_X_EXT_NAT_T_OA] = (u8) sizeof(struct sadb_address),
339 [SADB_X_EXT_SEC_CTX] = (u8) sizeof(struct sadb_x_sec_ctx),
339}; 340};
340 341
341/* Verify sadb_address_{len,prefixlen} against sa_family. */ 342/* Verify sadb_address_{len,prefixlen} against sa_family. */
@@ -383,6 +384,55 @@ static int verify_address_len(void *p)
383 return 0; 384 return 0;
384} 385}
385 386
387static inline int pfkey_sec_ctx_len(struct sadb_x_sec_ctx *sec_ctx)
388{
389 int len = 0;
390
391 len += sizeof(struct sadb_x_sec_ctx);
392 len += sec_ctx->sadb_x_ctx_len;
393 len += sizeof(uint64_t) - 1;
394 len /= sizeof(uint64_t);
395
396 return len;
397}
398
399static inline int verify_sec_ctx_len(void *p)
400{
401 struct sadb_x_sec_ctx *sec_ctx = (struct sadb_x_sec_ctx *)p;
402 int len;
403
404 if (sec_ctx->sadb_x_ctx_len > PAGE_SIZE)
405 return -EINVAL;
406
407 len = pfkey_sec_ctx_len(sec_ctx);
408
409 if (sec_ctx->sadb_x_sec_len != len)
410 return -EINVAL;
411
412 return 0;
413}
414
415static inline struct xfrm_user_sec_ctx *pfkey_sadb2xfrm_user_sec_ctx(struct sadb_x_sec_ctx *sec_ctx)
416{
417 struct xfrm_user_sec_ctx *uctx = NULL;
418 int ctx_size = sec_ctx->sadb_x_ctx_len;
419
420 uctx = kmalloc((sizeof(*uctx)+ctx_size), GFP_KERNEL);
421
422 if (!uctx)
423 return NULL;
424
425 uctx->len = pfkey_sec_ctx_len(sec_ctx);
426 uctx->exttype = sec_ctx->sadb_x_sec_exttype;
427 uctx->ctx_doi = sec_ctx->sadb_x_ctx_doi;
428 uctx->ctx_alg = sec_ctx->sadb_x_ctx_alg;
429 uctx->ctx_len = sec_ctx->sadb_x_ctx_len;
430 memcpy(uctx + 1, sec_ctx + 1,
431 uctx->ctx_len);
432
433 return uctx;
434}
435
386static int present_and_same_family(struct sadb_address *src, 436static int present_and_same_family(struct sadb_address *src,
387 struct sadb_address *dst) 437 struct sadb_address *dst)
388{ 438{
@@ -438,6 +488,10 @@ static int parse_exthdrs(struct sk_buff *skb, struct sadb_msg *hdr, void **ext_h
438 if (verify_address_len(p)) 488 if (verify_address_len(p))
439 return -EINVAL; 489 return -EINVAL;
440 } 490 }
491 if (ext_type == SADB_X_EXT_SEC_CTX) {
492 if (verify_sec_ctx_len(p))
493 return -EINVAL;
494 }
441 ext_hdrs[ext_type-1] = p; 495 ext_hdrs[ext_type-1] = p;
442 } 496 }
443 p += ext_len; 497 p += ext_len;
@@ -586,6 +640,9 @@ static struct sk_buff * pfkey_xfrm_state2msg(struct xfrm_state *x, int add_keys,
586 struct sadb_key *key; 640 struct sadb_key *key;
587 struct sadb_x_sa2 *sa2; 641 struct sadb_x_sa2 *sa2;
588 struct sockaddr_in *sin; 642 struct sockaddr_in *sin;
643 struct sadb_x_sec_ctx *sec_ctx;
644 struct xfrm_sec_ctx *xfrm_ctx;
645 int ctx_size = 0;
589#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) 646#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
590 struct sockaddr_in6 *sin6; 647 struct sockaddr_in6 *sin6;
591#endif 648#endif
@@ -609,6 +666,12 @@ static struct sk_buff * pfkey_xfrm_state2msg(struct xfrm_state *x, int add_keys,
609 sizeof(struct sadb_address)*2 + 666 sizeof(struct sadb_address)*2 +
610 sockaddr_size*2 + 667 sockaddr_size*2 +
611 sizeof(struct sadb_x_sa2); 668 sizeof(struct sadb_x_sa2);
669
670 if ((xfrm_ctx = x->security)) {
671 ctx_size = PFKEY_ALIGN8(xfrm_ctx->ctx_len);
672 size += sizeof(struct sadb_x_sec_ctx) + ctx_size;
673 }
674
612 /* identity & sensitivity */ 675 /* identity & sensitivity */
613 676
614 if ((x->props.family == AF_INET && 677 if ((x->props.family == AF_INET &&
@@ -899,6 +962,20 @@ static struct sk_buff * pfkey_xfrm_state2msg(struct xfrm_state *x, int add_keys,
899 n_port->sadb_x_nat_t_port_reserved = 0; 962 n_port->sadb_x_nat_t_port_reserved = 0;
900 } 963 }
901 964
965 /* security context */
966 if (xfrm_ctx) {
967 sec_ctx = (struct sadb_x_sec_ctx *) skb_put(skb,
968 sizeof(struct sadb_x_sec_ctx) + ctx_size);
969 sec_ctx->sadb_x_sec_len =
970 (sizeof(struct sadb_x_sec_ctx) + ctx_size) / sizeof(uint64_t);
971 sec_ctx->sadb_x_sec_exttype = SADB_X_EXT_SEC_CTX;
972 sec_ctx->sadb_x_ctx_doi = xfrm_ctx->ctx_doi;
973 sec_ctx->sadb_x_ctx_alg = xfrm_ctx->ctx_alg;
974 sec_ctx->sadb_x_ctx_len = xfrm_ctx->ctx_len;
975 memcpy(sec_ctx + 1, xfrm_ctx->ctx_str,
976 xfrm_ctx->ctx_len);
977 }
978
902 return skb; 979 return skb;
903} 980}
904 981
@@ -909,6 +986,7 @@ static struct xfrm_state * pfkey_msg2xfrm_state(struct sadb_msg *hdr,
909 struct sadb_lifetime *lifetime; 986 struct sadb_lifetime *lifetime;
910 struct sadb_sa *sa; 987 struct sadb_sa *sa;
911 struct sadb_key *key; 988 struct sadb_key *key;
989 struct sadb_x_sec_ctx *sec_ctx;
912 uint16_t proto; 990 uint16_t proto;
913 int err; 991 int err;
914 992
@@ -993,6 +1071,21 @@ static struct xfrm_state * pfkey_msg2xfrm_state(struct sadb_msg *hdr,
993 x->lft.soft_add_expires_seconds = lifetime->sadb_lifetime_addtime; 1071 x->lft.soft_add_expires_seconds = lifetime->sadb_lifetime_addtime;
994 x->lft.soft_use_expires_seconds = lifetime->sadb_lifetime_usetime; 1072 x->lft.soft_use_expires_seconds = lifetime->sadb_lifetime_usetime;
995 } 1073 }
1074
1075 sec_ctx = (struct sadb_x_sec_ctx *) ext_hdrs[SADB_X_EXT_SEC_CTX-1];
1076 if (sec_ctx != NULL) {
1077 struct xfrm_user_sec_ctx *uctx = pfkey_sadb2xfrm_user_sec_ctx(sec_ctx);
1078
1079 if (!uctx)
1080 goto out;
1081
1082 err = security_xfrm_state_alloc(x, uctx);
1083 kfree(uctx);
1084
1085 if (err)
1086 goto out;
1087 }
1088
996 key = (struct sadb_key*) ext_hdrs[SADB_EXT_KEY_AUTH-1]; 1089 key = (struct sadb_key*) ext_hdrs[SADB_EXT_KEY_AUTH-1];
997 if (sa->sadb_sa_auth) { 1090 if (sa->sadb_sa_auth) {
998 int keysize = 0; 1091 int keysize = 0;
@@ -1720,6 +1813,18 @@ parse_ipsecrequests(struct xfrm_policy *xp, struct sadb_x_policy *pol)
1720 return 0; 1813 return 0;
1721} 1814}
1722 1815
1816static inline int pfkey_xfrm_policy2sec_ctx_size(struct xfrm_policy *xp)
1817{
1818 struct xfrm_sec_ctx *xfrm_ctx = xp->security;
1819
1820 if (xfrm_ctx) {
1821 int len = sizeof(struct sadb_x_sec_ctx);
1822 len += xfrm_ctx->ctx_len;
1823 return PFKEY_ALIGN8(len);
1824 }
1825 return 0;
1826}
1827
1723static int pfkey_xfrm_policy2msg_size(struct xfrm_policy *xp) 1828static int pfkey_xfrm_policy2msg_size(struct xfrm_policy *xp)
1724{ 1829{
1725 int sockaddr_size = pfkey_sockaddr_size(xp->family); 1830 int sockaddr_size = pfkey_sockaddr_size(xp->family);
@@ -1733,7 +1838,8 @@ static int pfkey_xfrm_policy2msg_size(struct xfrm_policy *xp)
1733 (sockaddr_size * 2) + 1838 (sockaddr_size * 2) +
1734 sizeof(struct sadb_x_policy) + 1839 sizeof(struct sadb_x_policy) +
1735 (xp->xfrm_nr * (sizeof(struct sadb_x_ipsecrequest) + 1840 (xp->xfrm_nr * (sizeof(struct sadb_x_ipsecrequest) +
1736 (socklen * 2))); 1841 (socklen * 2))) +
1842 pfkey_xfrm_policy2sec_ctx_size(xp);
1737} 1843}
1738 1844
1739static struct sk_buff * pfkey_xfrm_policy2msg_prep(struct xfrm_policy *xp) 1845static struct sk_buff * pfkey_xfrm_policy2msg_prep(struct xfrm_policy *xp)
@@ -1757,6 +1863,8 @@ static void pfkey_xfrm_policy2msg(struct sk_buff *skb, struct xfrm_policy *xp, i
1757 struct sadb_lifetime *lifetime; 1863 struct sadb_lifetime *lifetime;
1758 struct sadb_x_policy *pol; 1864 struct sadb_x_policy *pol;
1759 struct sockaddr_in *sin; 1865 struct sockaddr_in *sin;
1866 struct sadb_x_sec_ctx *sec_ctx;
1867 struct xfrm_sec_ctx *xfrm_ctx;
1760#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) 1868#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
1761 struct sockaddr_in6 *sin6; 1869 struct sockaddr_in6 *sin6;
1762#endif 1870#endif
@@ -1941,6 +2049,21 @@ static void pfkey_xfrm_policy2msg(struct sk_buff *skb, struct xfrm_policy *xp, i
1941 } 2049 }
1942 } 2050 }
1943 } 2051 }
2052
2053 /* security context */
2054 if ((xfrm_ctx = xp->security)) {
2055 int ctx_size = pfkey_xfrm_policy2sec_ctx_size(xp);
2056
2057 sec_ctx = (struct sadb_x_sec_ctx *) skb_put(skb, ctx_size);
2058 sec_ctx->sadb_x_sec_len = ctx_size / sizeof(uint64_t);
2059 sec_ctx->sadb_x_sec_exttype = SADB_X_EXT_SEC_CTX;
2060 sec_ctx->sadb_x_ctx_doi = xfrm_ctx->ctx_doi;
2061 sec_ctx->sadb_x_ctx_alg = xfrm_ctx->ctx_alg;
2062 sec_ctx->sadb_x_ctx_len = xfrm_ctx->ctx_len;
2063 memcpy(sec_ctx + 1, xfrm_ctx->ctx_str,
2064 xfrm_ctx->ctx_len);
2065 }
2066
1944 hdr->sadb_msg_len = size / sizeof(uint64_t); 2067 hdr->sadb_msg_len = size / sizeof(uint64_t);
1945 hdr->sadb_msg_reserved = atomic_read(&xp->refcnt); 2068 hdr->sadb_msg_reserved = atomic_read(&xp->refcnt);
1946} 2069}
@@ -1976,12 +2099,13 @@ out:
1976 2099
1977static int pfkey_spdadd(struct sock *sk, struct sk_buff *skb, struct sadb_msg *hdr, void **ext_hdrs) 2100static int pfkey_spdadd(struct sock *sk, struct sk_buff *skb, struct sadb_msg *hdr, void **ext_hdrs)
1978{ 2101{
1979 int err; 2102 int err = 0;
1980 struct sadb_lifetime *lifetime; 2103 struct sadb_lifetime *lifetime;
1981 struct sadb_address *sa; 2104 struct sadb_address *sa;
1982 struct sadb_x_policy *pol; 2105 struct sadb_x_policy *pol;
1983 struct xfrm_policy *xp; 2106 struct xfrm_policy *xp;
1984 struct km_event c; 2107 struct km_event c;
2108 struct sadb_x_sec_ctx *sec_ctx;
1985 2109
1986 if (!present_and_same_family(ext_hdrs[SADB_EXT_ADDRESS_SRC-1], 2110 if (!present_and_same_family(ext_hdrs[SADB_EXT_ADDRESS_SRC-1],
1987 ext_hdrs[SADB_EXT_ADDRESS_DST-1]) || 2111 ext_hdrs[SADB_EXT_ADDRESS_DST-1]) ||
@@ -2028,6 +2152,22 @@ static int pfkey_spdadd(struct sock *sk, struct sk_buff *skb, struct sadb_msg *h
2028 if (xp->selector.dport) 2152 if (xp->selector.dport)
2029 xp->selector.dport_mask = ~0; 2153 xp->selector.dport_mask = ~0;
2030 2154
2155 sec_ctx = (struct sadb_x_sec_ctx *) ext_hdrs[SADB_X_EXT_SEC_CTX-1];
2156 if (sec_ctx != NULL) {
2157 struct xfrm_user_sec_ctx *uctx = pfkey_sadb2xfrm_user_sec_ctx(sec_ctx);
2158
2159 if (!uctx) {
2160 err = -ENOBUFS;
2161 goto out;
2162 }
2163
2164 err = security_xfrm_policy_alloc(xp, uctx);
2165 kfree(uctx);
2166
2167 if (err)
2168 goto out;
2169 }
2170
2031 xp->lft.soft_byte_limit = XFRM_INF; 2171 xp->lft.soft_byte_limit = XFRM_INF;
2032 xp->lft.hard_byte_limit = XFRM_INF; 2172 xp->lft.hard_byte_limit = XFRM_INF;
2033 xp->lft.soft_packet_limit = XFRM_INF; 2173 xp->lft.soft_packet_limit = XFRM_INF;
@@ -2051,10 +2191,9 @@ static int pfkey_spdadd(struct sock *sk, struct sk_buff *skb, struct sadb_msg *h
2051 2191
2052 err = xfrm_policy_insert(pol->sadb_x_policy_dir-1, xp, 2192 err = xfrm_policy_insert(pol->sadb_x_policy_dir-1, xp,
2053 hdr->sadb_msg_type != SADB_X_SPDUPDATE); 2193 hdr->sadb_msg_type != SADB_X_SPDUPDATE);
2054 if (err) { 2194
2055 kfree(xp); 2195 if (err)
2056 return err; 2196 goto out;
2057 }
2058 2197
2059 if (hdr->sadb_msg_type == SADB_X_SPDUPDATE) 2198 if (hdr->sadb_msg_type == SADB_X_SPDUPDATE)
2060 c.event = XFRM_MSG_UPDPOLICY; 2199 c.event = XFRM_MSG_UPDPOLICY;
@@ -2069,6 +2208,7 @@ static int pfkey_spdadd(struct sock *sk, struct sk_buff *skb, struct sadb_msg *h
2069 return 0; 2208 return 0;
2070 2209
2071out: 2210out:
2211 security_xfrm_policy_free(xp);
2072 kfree(xp); 2212 kfree(xp);
2073 return err; 2213 return err;
2074} 2214}
@@ -2078,9 +2218,10 @@ static int pfkey_spddelete(struct sock *sk, struct sk_buff *skb, struct sadb_msg
2078 int err; 2218 int err;
2079 struct sadb_address *sa; 2219 struct sadb_address *sa;
2080 struct sadb_x_policy *pol; 2220 struct sadb_x_policy *pol;
2081 struct xfrm_policy *xp; 2221 struct xfrm_policy *xp, tmp;
2082 struct xfrm_selector sel; 2222 struct xfrm_selector sel;
2083 struct km_event c; 2223 struct km_event c;
2224 struct sadb_x_sec_ctx *sec_ctx;
2084 2225
2085 if (!present_and_same_family(ext_hdrs[SADB_EXT_ADDRESS_SRC-1], 2226 if (!present_and_same_family(ext_hdrs[SADB_EXT_ADDRESS_SRC-1],
2086 ext_hdrs[SADB_EXT_ADDRESS_DST-1]) || 2227 ext_hdrs[SADB_EXT_ADDRESS_DST-1]) ||
@@ -2109,7 +2250,24 @@ static int pfkey_spddelete(struct sock *sk, struct sk_buff *skb, struct sadb_msg
2109 if (sel.dport) 2250 if (sel.dport)
2110 sel.dport_mask = ~0; 2251 sel.dport_mask = ~0;
2111 2252
2112 xp = xfrm_policy_bysel(pol->sadb_x_policy_dir-1, &sel, 1); 2253 sec_ctx = (struct sadb_x_sec_ctx *) ext_hdrs[SADB_X_EXT_SEC_CTX-1];
2254 memset(&tmp, 0, sizeof(struct xfrm_policy));
2255
2256 if (sec_ctx != NULL) {
2257 struct xfrm_user_sec_ctx *uctx = pfkey_sadb2xfrm_user_sec_ctx(sec_ctx);
2258
2259 if (!uctx)
2260 return -ENOMEM;
2261
2262 err = security_xfrm_policy_alloc(&tmp, uctx);
2263 kfree(uctx);
2264
2265 if (err)
2266 return err;
2267 }
2268
2269 xp = xfrm_policy_bysel_ctx(pol->sadb_x_policy_dir-1, &sel, tmp.security, 1);
2270 security_xfrm_policy_free(&tmp);
2113 if (xp == NULL) 2271 if (xp == NULL)
2114 return -ENOENT; 2272 return -ENOENT;
2115 2273
@@ -2660,6 +2818,7 @@ static struct xfrm_policy *pfkey_compile_policy(u16 family, int opt,
2660{ 2818{
2661 struct xfrm_policy *xp; 2819 struct xfrm_policy *xp;
2662 struct sadb_x_policy *pol = (struct sadb_x_policy*)data; 2820 struct sadb_x_policy *pol = (struct sadb_x_policy*)data;
2821 struct sadb_x_sec_ctx *sec_ctx;
2663 2822
2664 switch (family) { 2823 switch (family) {
2665 case AF_INET: 2824 case AF_INET:
@@ -2709,10 +2868,32 @@ static struct xfrm_policy *pfkey_compile_policy(u16 family, int opt,
2709 (*dir = parse_ipsecrequests(xp, pol)) < 0) 2868 (*dir = parse_ipsecrequests(xp, pol)) < 0)
2710 goto out; 2869 goto out;
2711 2870
2871 /* security context too */
2872 if (len >= (pol->sadb_x_policy_len*8 +
2873 sizeof(struct sadb_x_sec_ctx))) {
2874 char *p = (char *)pol;
2875 struct xfrm_user_sec_ctx *uctx;
2876
2877 p += pol->sadb_x_policy_len*8;
2878 sec_ctx = (struct sadb_x_sec_ctx *)p;
2879 if (len < pol->sadb_x_policy_len*8 +
2880 sec_ctx->sadb_x_sec_len)
2881 goto out;
2882 if ((*dir = verify_sec_ctx_len(p)))
2883 goto out;
2884 uctx = pfkey_sadb2xfrm_user_sec_ctx(sec_ctx);
2885 *dir = security_xfrm_policy_alloc(xp, uctx);
2886 kfree(uctx);
2887
2888 if (*dir)
2889 goto out;
2890 }
2891
2712 *dir = pol->sadb_x_policy_dir-1; 2892 *dir = pol->sadb_x_policy_dir-1;
2713 return xp; 2893 return xp;
2714 2894
2715out: 2895out:
2896 security_xfrm_policy_free(xp);
2716 kfree(xp); 2897 kfree(xp);
2717 return NULL; 2898 return NULL;
2718} 2899}
diff --git a/net/xfrm/xfrm_policy.c b/net/xfrm/xfrm_policy.c
index d19e274b9c4a..64a447375fdb 100644
--- a/net/xfrm/xfrm_policy.c
+++ b/net/xfrm/xfrm_policy.c
@@ -10,7 +10,7 @@
10 * YOSHIFUJI Hideaki 10 * YOSHIFUJI Hideaki
11 * Split up af-specific portion 11 * Split up af-specific portion
12 * Derek Atkins <derek@ihtfp.com> Add the post_input processor 12 * Derek Atkins <derek@ihtfp.com> Add the post_input processor
13 * 13 *
14 */ 14 */
15 15
16#include <asm/bug.h> 16#include <asm/bug.h>
@@ -256,6 +256,7 @@ void __xfrm_policy_destroy(struct xfrm_policy *policy)
256 if (del_timer(&policy->timer)) 256 if (del_timer(&policy->timer))
257 BUG(); 257 BUG();
258 258
259 security_xfrm_policy_free(policy);
259 kfree(policy); 260 kfree(policy);
260} 261}
261EXPORT_SYMBOL(__xfrm_policy_destroy); 262EXPORT_SYMBOL(__xfrm_policy_destroy);
@@ -350,7 +351,8 @@ int xfrm_policy_insert(int dir, struct xfrm_policy *policy, int excl)
350 351
351 write_lock_bh(&xfrm_policy_lock); 352 write_lock_bh(&xfrm_policy_lock);
352 for (p = &xfrm_policy_list[dir]; (pol=*p)!=NULL;) { 353 for (p = &xfrm_policy_list[dir]; (pol=*p)!=NULL;) {
353 if (!delpol && memcmp(&policy->selector, &pol->selector, sizeof(pol->selector)) == 0) { 354 if (!delpol && memcmp(&policy->selector, &pol->selector, sizeof(pol->selector)) == 0 &&
355 xfrm_sec_ctx_match(pol->security, policy->security)) {
354 if (excl) { 356 if (excl) {
355 write_unlock_bh(&xfrm_policy_lock); 357 write_unlock_bh(&xfrm_policy_lock);
356 return -EEXIST; 358 return -EEXIST;
@@ -416,14 +418,15 @@ int xfrm_policy_insert(int dir, struct xfrm_policy *policy, int excl)
416} 418}
417EXPORT_SYMBOL(xfrm_policy_insert); 419EXPORT_SYMBOL(xfrm_policy_insert);
418 420
419struct xfrm_policy *xfrm_policy_bysel(int dir, struct xfrm_selector *sel, 421struct xfrm_policy *xfrm_policy_bysel_ctx(int dir, struct xfrm_selector *sel,
420 int delete) 422 struct xfrm_sec_ctx *ctx, int delete)
421{ 423{
422 struct xfrm_policy *pol, **p; 424 struct xfrm_policy *pol, **p;
423 425
424 write_lock_bh(&xfrm_policy_lock); 426 write_lock_bh(&xfrm_policy_lock);
425 for (p = &xfrm_policy_list[dir]; (pol=*p)!=NULL; p = &pol->next) { 427 for (p = &xfrm_policy_list[dir]; (pol=*p)!=NULL; p = &pol->next) {
426 if (memcmp(sel, &pol->selector, sizeof(*sel)) == 0) { 428 if ((memcmp(sel, &pol->selector, sizeof(*sel)) == 0) &&
429 (xfrm_sec_ctx_match(ctx, pol->security))) {
427 xfrm_pol_hold(pol); 430 xfrm_pol_hold(pol);
428 if (delete) 431 if (delete)
429 *p = pol->next; 432 *p = pol->next;
@@ -438,7 +441,7 @@ struct xfrm_policy *xfrm_policy_bysel(int dir, struct xfrm_selector *sel,
438 } 441 }
439 return pol; 442 return pol;
440} 443}
441EXPORT_SYMBOL(xfrm_policy_bysel); 444EXPORT_SYMBOL(xfrm_policy_bysel_ctx);
442 445
443struct xfrm_policy *xfrm_policy_byid(int dir, u32 id, int delete) 446struct xfrm_policy *xfrm_policy_byid(int dir, u32 id, int delete)
444{ 447{
@@ -519,7 +522,7 @@ EXPORT_SYMBOL(xfrm_policy_walk);
519 522
520/* Find policy to apply to this flow. */ 523/* Find policy to apply to this flow. */
521 524
522static void xfrm_policy_lookup(struct flowi *fl, u16 family, u8 dir, 525static void xfrm_policy_lookup(struct flowi *fl, u32 sk_sid, u16 family, u8 dir,
523 void **objp, atomic_t **obj_refp) 526 void **objp, atomic_t **obj_refp)
524{ 527{
525 struct xfrm_policy *pol; 528 struct xfrm_policy *pol;
@@ -533,9 +536,12 @@ static void xfrm_policy_lookup(struct flowi *fl, u16 family, u8 dir,
533 continue; 536 continue;
534 537
535 match = xfrm_selector_match(sel, fl, family); 538 match = xfrm_selector_match(sel, fl, family);
539
536 if (match) { 540 if (match) {
537 xfrm_pol_hold(pol); 541 if (!security_xfrm_policy_lookup(pol, sk_sid, dir)) {
538 break; 542 xfrm_pol_hold(pol);
543 break;
544 }
539 } 545 }
540 } 546 }
541 read_unlock_bh(&xfrm_policy_lock); 547 read_unlock_bh(&xfrm_policy_lock);
@@ -543,15 +549,37 @@ static void xfrm_policy_lookup(struct flowi *fl, u16 family, u8 dir,
543 *obj_refp = &pol->refcnt; 549 *obj_refp = &pol->refcnt;
544} 550}
545 551
546static struct xfrm_policy *xfrm_sk_policy_lookup(struct sock *sk, int dir, struct flowi *fl) 552static inline int policy_to_flow_dir(int dir)
553{
554 if (XFRM_POLICY_IN == FLOW_DIR_IN &&
555 XFRM_POLICY_OUT == FLOW_DIR_OUT &&
556 XFRM_POLICY_FWD == FLOW_DIR_FWD)
557 return dir;
558 switch (dir) {
559 default:
560 case XFRM_POLICY_IN:
561 return FLOW_DIR_IN;
562 case XFRM_POLICY_OUT:
563 return FLOW_DIR_OUT;
564 case XFRM_POLICY_FWD:
565 return FLOW_DIR_FWD;
566 };
567}
568
569static struct xfrm_policy *xfrm_sk_policy_lookup(struct sock *sk, int dir, struct flowi *fl, u32 sk_sid)
547{ 570{
548 struct xfrm_policy *pol; 571 struct xfrm_policy *pol;
549 572
550 read_lock_bh(&xfrm_policy_lock); 573 read_lock_bh(&xfrm_policy_lock);
551 if ((pol = sk->sk_policy[dir]) != NULL) { 574 if ((pol = sk->sk_policy[dir]) != NULL) {
552 int match = xfrm_selector_match(&pol->selector, fl, 575 int match = xfrm_selector_match(&pol->selector, fl,
553 sk->sk_family); 576 sk->sk_family);
577 int err = 0;
578
554 if (match) 579 if (match)
580 err = security_xfrm_policy_lookup(pol, sk_sid, policy_to_flow_dir(dir));
581
582 if (match && !err)
555 xfrm_pol_hold(pol); 583 xfrm_pol_hold(pol);
556 else 584 else
557 pol = NULL; 585 pol = NULL;
@@ -624,6 +652,10 @@ static struct xfrm_policy *clone_policy(struct xfrm_policy *old, int dir)
624 652
625 if (newp) { 653 if (newp) {
626 newp->selector = old->selector; 654 newp->selector = old->selector;
655 if (security_xfrm_policy_clone(old, newp)) {
656 kfree(newp);
657 return NULL; /* ENOMEM */
658 }
627 newp->lft = old->lft; 659 newp->lft = old->lft;
628 newp->curlft = old->curlft; 660 newp->curlft = old->curlft;
629 newp->action = old->action; 661 newp->action = old->action;
@@ -735,22 +767,6 @@ xfrm_bundle_create(struct xfrm_policy *policy, struct xfrm_state **xfrm, int nx,
735 return err; 767 return err;
736} 768}
737 769
738static inline int policy_to_flow_dir(int dir)
739{
740 if (XFRM_POLICY_IN == FLOW_DIR_IN &&
741 XFRM_POLICY_OUT == FLOW_DIR_OUT &&
742 XFRM_POLICY_FWD == FLOW_DIR_FWD)
743 return dir;
744 switch (dir) {
745 default:
746 case XFRM_POLICY_IN:
747 return FLOW_DIR_IN;
748 case XFRM_POLICY_OUT:
749 return FLOW_DIR_OUT;
750 case XFRM_POLICY_FWD:
751 return FLOW_DIR_FWD;
752 };
753}
754 770
755static int stale_bundle(struct dst_entry *dst); 771static int stale_bundle(struct dst_entry *dst);
756 772
@@ -769,19 +785,20 @@ int xfrm_lookup(struct dst_entry **dst_p, struct flowi *fl,
769 int err; 785 int err;
770 u32 genid; 786 u32 genid;
771 u16 family = dst_orig->ops->family; 787 u16 family = dst_orig->ops->family;
788 u8 dir = policy_to_flow_dir(XFRM_POLICY_OUT);
789 u32 sk_sid = security_sk_sid(sk, fl, dir);
772restart: 790restart:
773 genid = atomic_read(&flow_cache_genid); 791 genid = atomic_read(&flow_cache_genid);
774 policy = NULL; 792 policy = NULL;
775 if (sk && sk->sk_policy[1]) 793 if (sk && sk->sk_policy[1])
776 policy = xfrm_sk_policy_lookup(sk, XFRM_POLICY_OUT, fl); 794 policy = xfrm_sk_policy_lookup(sk, XFRM_POLICY_OUT, fl, sk_sid);
777 795
778 if (!policy) { 796 if (!policy) {
779 /* To accelerate a bit... */ 797 /* To accelerate a bit... */
780 if ((dst_orig->flags & DST_NOXFRM) || !xfrm_policy_list[XFRM_POLICY_OUT]) 798 if ((dst_orig->flags & DST_NOXFRM) || !xfrm_policy_list[XFRM_POLICY_OUT])
781 return 0; 799 return 0;
782 800
783 policy = flow_cache_lookup(fl, family, 801 policy = flow_cache_lookup(fl, sk_sid, family, dir,
784 policy_to_flow_dir(XFRM_POLICY_OUT),
785 xfrm_policy_lookup); 802 xfrm_policy_lookup);
786 } 803 }
787 804
@@ -962,16 +979,20 @@ int __xfrm_policy_check(struct sock *sk, int dir, struct sk_buff *skb,
962{ 979{
963 struct xfrm_policy *pol; 980 struct xfrm_policy *pol;
964 struct flowi fl; 981 struct flowi fl;
982 u8 fl_dir = policy_to_flow_dir(dir);
983 u32 sk_sid;
965 984
966 if (_decode_session(skb, &fl, family) < 0) 985 if (_decode_session(skb, &fl, family) < 0)
967 return 0; 986 return 0;
968 987
988 sk_sid = security_sk_sid(sk, &fl, fl_dir);
989
969 /* First, check used SA against their selectors. */ 990 /* First, check used SA against their selectors. */
970 if (skb->sp) { 991 if (skb->sp) {
971 int i; 992 int i;
972 993
973 for (i=skb->sp->len-1; i>=0; i--) { 994 for (i=skb->sp->len-1; i>=0; i--) {
974 struct sec_decap_state *xvec = &(skb->sp->x[i]); 995 struct sec_decap_state *xvec = &(skb->sp->x[i]);
975 if (!xfrm_selector_match(&xvec->xvec->sel, &fl, family)) 996 if (!xfrm_selector_match(&xvec->xvec->sel, &fl, family))
976 return 0; 997 return 0;
977 998
@@ -986,11 +1007,10 @@ int __xfrm_policy_check(struct sock *sk, int dir, struct sk_buff *skb,
986 1007
987 pol = NULL; 1008 pol = NULL;
988 if (sk && sk->sk_policy[dir]) 1009 if (sk && sk->sk_policy[dir])
989 pol = xfrm_sk_policy_lookup(sk, dir, &fl); 1010 pol = xfrm_sk_policy_lookup(sk, dir, &fl, sk_sid);
990 1011
991 if (!pol) 1012 if (!pol)
992 pol = flow_cache_lookup(&fl, family, 1013 pol = flow_cache_lookup(&fl, sk_sid, family, fl_dir,
993 policy_to_flow_dir(dir),
994 xfrm_policy_lookup); 1014 xfrm_policy_lookup);
995 1015
996 if (!pol) 1016 if (!pol)
diff --git a/net/xfrm/xfrm_state.c b/net/xfrm/xfrm_state.c
index 479effc97666..e12d0be5f976 100644
--- a/net/xfrm/xfrm_state.c
+++ b/net/xfrm/xfrm_state.c
@@ -10,7 +10,7 @@
10 * Split up af-specific functions 10 * Split up af-specific functions
11 * Derek Atkins <derek@ihtfp.com> 11 * Derek Atkins <derek@ihtfp.com>
12 * Add UDP Encapsulation 12 * Add UDP Encapsulation
13 * 13 *
14 */ 14 */
15 15
16#include <linux/workqueue.h> 16#include <linux/workqueue.h>
@@ -70,6 +70,7 @@ static void xfrm_state_gc_destroy(struct xfrm_state *x)
70 x->type->destructor(x); 70 x->type->destructor(x);
71 xfrm_put_type(x->type); 71 xfrm_put_type(x->type);
72 } 72 }
73 security_xfrm_state_free(x);
73 kfree(x); 74 kfree(x);
74} 75}
75 76
@@ -343,7 +344,8 @@ xfrm_state_find(xfrm_address_t *daddr, xfrm_address_t *saddr,
343 selector. 344 selector.
344 */ 345 */
345 if (x->km.state == XFRM_STATE_VALID) { 346 if (x->km.state == XFRM_STATE_VALID) {
346 if (!xfrm_selector_match(&x->sel, fl, family)) 347 if (!xfrm_selector_match(&x->sel, fl, family) ||
348 !xfrm_sec_ctx_match(pol->security, x->security))
347 continue; 349 continue;
348 if (!best || 350 if (!best ||
349 best->km.dying > x->km.dying || 351 best->km.dying > x->km.dying ||
@@ -354,7 +356,8 @@ xfrm_state_find(xfrm_address_t *daddr, xfrm_address_t *saddr,
354 acquire_in_progress = 1; 356 acquire_in_progress = 1;
355 } else if (x->km.state == XFRM_STATE_ERROR || 357 } else if (x->km.state == XFRM_STATE_ERROR ||
356 x->km.state == XFRM_STATE_EXPIRED) { 358 x->km.state == XFRM_STATE_EXPIRED) {
357 if (xfrm_selector_match(&x->sel, fl, family)) 359 if (xfrm_selector_match(&x->sel, fl, family) &&
360 xfrm_sec_ctx_match(pol->security, x->security))
358 error = -ESRCH; 361 error = -ESRCH;
359 } 362 }
360 } 363 }
diff --git a/net/xfrm/xfrm_user.c b/net/xfrm/xfrm_user.c
index 0cdd9a07e043..92e2b804c606 100644
--- a/net/xfrm/xfrm_user.c
+++ b/net/xfrm/xfrm_user.c
@@ -7,7 +7,7 @@
7 * Kazunori MIYAZAWA @USAGI 7 * Kazunori MIYAZAWA @USAGI
8 * Kunihiro Ishiguro <kunihiro@ipinfusion.com> 8 * Kunihiro Ishiguro <kunihiro@ipinfusion.com>
9 * IPv6 support 9 * IPv6 support
10 * 10 *
11 */ 11 */
12 12
13#include <linux/module.h> 13#include <linux/module.h>
@@ -88,6 +88,34 @@ static int verify_encap_tmpl(struct rtattr **xfrma)
88 return 0; 88 return 0;
89} 89}
90 90
91
92static inline int verify_sec_ctx_len(struct rtattr **xfrma)
93{
94 struct rtattr *rt = xfrma[XFRMA_SEC_CTX - 1];
95 struct xfrm_user_sec_ctx *uctx;
96 int len = 0;
97
98 if (!rt)
99 return 0;
100
101 if (rt->rta_len < sizeof(*uctx))
102 return -EINVAL;
103
104 uctx = RTA_DATA(rt);
105
106 if (uctx->ctx_len > PAGE_SIZE)
107 return -EINVAL;
108
109 len += sizeof(struct xfrm_user_sec_ctx);
110 len += uctx->ctx_len;
111
112 if (uctx->len != len)
113 return -EINVAL;
114
115 return 0;
116}
117
118
91static int verify_newsa_info(struct xfrm_usersa_info *p, 119static int verify_newsa_info(struct xfrm_usersa_info *p,
92 struct rtattr **xfrma) 120 struct rtattr **xfrma)
93{ 121{
@@ -145,6 +173,8 @@ static int verify_newsa_info(struct xfrm_usersa_info *p,
145 goto out; 173 goto out;
146 if ((err = verify_encap_tmpl(xfrma))) 174 if ((err = verify_encap_tmpl(xfrma)))
147 goto out; 175 goto out;
176 if ((err = verify_sec_ctx_len(xfrma)))
177 goto out;
148 178
149 err = -EINVAL; 179 err = -EINVAL;
150 switch (p->mode) { 180 switch (p->mode) {
@@ -209,6 +239,30 @@ static int attach_encap_tmpl(struct xfrm_encap_tmpl **encapp, struct rtattr *u_a
209 return 0; 239 return 0;
210} 240}
211 241
242
243static inline int xfrm_user_sec_ctx_size(struct xfrm_policy *xp)
244{
245 struct xfrm_sec_ctx *xfrm_ctx = xp->security;
246 int len = 0;
247
248 if (xfrm_ctx) {
249 len += sizeof(struct xfrm_user_sec_ctx);
250 len += xfrm_ctx->ctx_len;
251 }
252 return len;
253}
254
255static int attach_sec_ctx(struct xfrm_state *x, struct rtattr *u_arg)
256{
257 struct xfrm_user_sec_ctx *uctx;
258
259 if (!u_arg)
260 return 0;
261
262 uctx = RTA_DATA(u_arg);
263 return security_xfrm_state_alloc(x, uctx);
264}
265
212static void copy_from_user_state(struct xfrm_state *x, struct xfrm_usersa_info *p) 266static void copy_from_user_state(struct xfrm_state *x, struct xfrm_usersa_info *p)
213{ 267{
214 memcpy(&x->id, &p->id, sizeof(x->id)); 268 memcpy(&x->id, &p->id, sizeof(x->id));
@@ -253,6 +307,9 @@ static struct xfrm_state *xfrm_state_construct(struct xfrm_usersa_info *p,
253 if (err) 307 if (err)
254 goto error; 308 goto error;
255 309
310 if ((err = attach_sec_ctx(x, xfrma[XFRMA_SEC_CTX-1])))
311 goto error;
312
256 x->km.seq = p->seq; 313 x->km.seq = p->seq;
257 314
258 return x; 315 return x;
@@ -272,11 +329,11 @@ static int xfrm_add_sa(struct sk_buff *skb, struct nlmsghdr *nlh, void **xfrma)
272 int err; 329 int err;
273 struct km_event c; 330 struct km_event c;
274 331
275 err = verify_newsa_info(p, (struct rtattr **) xfrma); 332 err = verify_newsa_info(p, (struct rtattr **)xfrma);
276 if (err) 333 if (err)
277 return err; 334 return err;
278 335
279 x = xfrm_state_construct(p, (struct rtattr **) xfrma, &err); 336 x = xfrm_state_construct(p, (struct rtattr **)xfrma, &err);
280 if (!x) 337 if (!x)
281 return err; 338 return err;
282 339
@@ -390,6 +447,19 @@ static int dump_one_state(struct xfrm_state *x, int count, void *ptr)
390 if (x->encap) 447 if (x->encap)
391 RTA_PUT(skb, XFRMA_ENCAP, sizeof(*x->encap), x->encap); 448 RTA_PUT(skb, XFRMA_ENCAP, sizeof(*x->encap), x->encap);
392 449
450 if (x->security) {
451 int ctx_size = sizeof(struct xfrm_sec_ctx) +
452 x->security->ctx_len;
453 struct rtattr *rt = __RTA_PUT(skb, XFRMA_SEC_CTX, ctx_size);
454 struct xfrm_user_sec_ctx *uctx = RTA_DATA(rt);
455
456 uctx->exttype = XFRMA_SEC_CTX;
457 uctx->len = ctx_size;
458 uctx->ctx_doi = x->security->ctx_doi;
459 uctx->ctx_alg = x->security->ctx_alg;
460 uctx->ctx_len = x->security->ctx_len;
461 memcpy(uctx + 1, x->security->ctx_str, x->security->ctx_len);
462 }
393 nlh->nlmsg_len = skb->tail - b; 463 nlh->nlmsg_len = skb->tail - b;
394out: 464out:
395 sp->this_idx++; 465 sp->this_idx++;
@@ -603,6 +673,18 @@ static int verify_newpolicy_info(struct xfrm_userpolicy_info *p)
603 return verify_policy_dir(p->dir); 673 return verify_policy_dir(p->dir);
604} 674}
605 675
676static int copy_from_user_sec_ctx(struct xfrm_policy *pol, struct rtattr **xfrma)
677{
678 struct rtattr *rt = xfrma[XFRMA_SEC_CTX-1];
679 struct xfrm_user_sec_ctx *uctx;
680
681 if (!rt)
682 return 0;
683
684 uctx = RTA_DATA(rt);
685 return security_xfrm_policy_alloc(pol, uctx);
686}
687
606static void copy_templates(struct xfrm_policy *xp, struct xfrm_user_tmpl *ut, 688static void copy_templates(struct xfrm_policy *xp, struct xfrm_user_tmpl *ut,
607 int nr) 689 int nr)
608{ 690{
@@ -681,7 +763,10 @@ static struct xfrm_policy *xfrm_policy_construct(struct xfrm_userpolicy_info *p,
681 } 763 }
682 764
683 copy_from_user_policy(xp, p); 765 copy_from_user_policy(xp, p);
684 err = copy_from_user_tmpl(xp, xfrma); 766
767 if (!(err = copy_from_user_tmpl(xp, xfrma)))
768 err = copy_from_user_sec_ctx(xp, xfrma);
769
685 if (err) { 770 if (err) {
686 *errp = err; 771 *errp = err;
687 kfree(xp); 772 kfree(xp);
@@ -702,8 +787,11 @@ static int xfrm_add_policy(struct sk_buff *skb, struct nlmsghdr *nlh, void **xfr
702 err = verify_newpolicy_info(p); 787 err = verify_newpolicy_info(p);
703 if (err) 788 if (err)
704 return err; 789 return err;
790 err = verify_sec_ctx_len((struct rtattr **)xfrma);
791 if (err)
792 return err;
705 793
706 xp = xfrm_policy_construct(p, (struct rtattr **) xfrma, &err); 794 xp = xfrm_policy_construct(p, (struct rtattr **)xfrma, &err);
707 if (!xp) 795 if (!xp)
708 return err; 796 return err;
709 797
@@ -761,6 +849,27 @@ rtattr_failure:
761 return -1; 849 return -1;
762} 850}
763 851
852static int copy_to_user_sec_ctx(struct xfrm_policy *xp, struct sk_buff *skb)
853{
854 if (xp->security) {
855 int ctx_size = sizeof(struct xfrm_sec_ctx) +
856 xp->security->ctx_len;
857 struct rtattr *rt = __RTA_PUT(skb, XFRMA_SEC_CTX, ctx_size);
858 struct xfrm_user_sec_ctx *uctx = RTA_DATA(rt);
859
860 uctx->exttype = XFRMA_SEC_CTX;
861 uctx->len = ctx_size;
862 uctx->ctx_doi = xp->security->ctx_doi;
863 uctx->ctx_alg = xp->security->ctx_alg;
864 uctx->ctx_len = xp->security->ctx_len;
865 memcpy(uctx + 1, xp->security->ctx_str, xp->security->ctx_len);
866 }
867 return 0;
868
869 rtattr_failure:
870 return -1;
871}
872
764static int dump_one_policy(struct xfrm_policy *xp, int dir, int count, void *ptr) 873static int dump_one_policy(struct xfrm_policy *xp, int dir, int count, void *ptr)
765{ 874{
766 struct xfrm_dump_info *sp = ptr; 875 struct xfrm_dump_info *sp = ptr;
@@ -782,6 +891,8 @@ static int dump_one_policy(struct xfrm_policy *xp, int dir, int count, void *ptr
782 copy_to_user_policy(xp, p, dir); 891 copy_to_user_policy(xp, p, dir);
783 if (copy_to_user_tmpl(xp, skb) < 0) 892 if (copy_to_user_tmpl(xp, skb) < 0)
784 goto nlmsg_failure; 893 goto nlmsg_failure;
894 if (copy_to_user_sec_ctx(xp, skb))
895 goto nlmsg_failure;
785 896
786 nlh->nlmsg_len = skb->tail - b; 897 nlh->nlmsg_len = skb->tail - b;
787out: 898out:
@@ -852,8 +963,25 @@ static int xfrm_get_policy(struct sk_buff *skb, struct nlmsghdr *nlh, void **xfr
852 963
853 if (p->index) 964 if (p->index)
854 xp = xfrm_policy_byid(p->dir, p->index, delete); 965 xp = xfrm_policy_byid(p->dir, p->index, delete);
855 else 966 else {
856 xp = xfrm_policy_bysel(p->dir, &p->sel, delete); 967 struct rtattr **rtattrs = (struct rtattr **)xfrma;
968 struct rtattr *rt = rtattrs[XFRMA_SEC_CTX-1];
969 struct xfrm_policy tmp;
970
971 err = verify_sec_ctx_len(rtattrs);
972 if (err)
973 return err;
974
975 memset(&tmp, 0, sizeof(struct xfrm_policy));
976 if (rt) {
977 struct xfrm_user_sec_ctx *uctx = RTA_DATA(rt);
978
979 if ((err = security_xfrm_policy_alloc(&tmp, uctx)))
980 return err;
981 }
982 xp = xfrm_policy_bysel_ctx(p->dir, &p->sel, tmp.security, delete);
983 security_xfrm_policy_free(&tmp);
984 }
857 if (xp == NULL) 985 if (xp == NULL)
858 return -ENOENT; 986 return -ENOENT;
859 987
@@ -1224,6 +1352,8 @@ static int build_acquire(struct sk_buff *skb, struct xfrm_state *x,
1224 1352
1225 if (copy_to_user_tmpl(xp, skb) < 0) 1353 if (copy_to_user_tmpl(xp, skb) < 0)
1226 goto nlmsg_failure; 1354 goto nlmsg_failure;
1355 if (copy_to_user_sec_ctx(xp, skb))
1356 goto nlmsg_failure;
1227 1357
1228 nlh->nlmsg_len = skb->tail - b; 1358 nlh->nlmsg_len = skb->tail - b;
1229 return skb->len; 1359 return skb->len;
@@ -1241,6 +1371,7 @@ static int xfrm_send_acquire(struct xfrm_state *x, struct xfrm_tmpl *xt,
1241 1371
1242 len = RTA_SPACE(sizeof(struct xfrm_user_tmpl) * xp->xfrm_nr); 1372 len = RTA_SPACE(sizeof(struct xfrm_user_tmpl) * xp->xfrm_nr);
1243 len += NLMSG_SPACE(sizeof(struct xfrm_user_acquire)); 1373 len += NLMSG_SPACE(sizeof(struct xfrm_user_acquire));
1374 len += RTA_SPACE(xfrm_user_sec_ctx_size(xp));
1244 skb = alloc_skb(len, GFP_ATOMIC); 1375 skb = alloc_skb(len, GFP_ATOMIC);
1245 if (skb == NULL) 1376 if (skb == NULL)
1246 return -ENOMEM; 1377 return -ENOMEM;
@@ -1324,6 +1455,8 @@ static int build_polexpire(struct sk_buff *skb, struct xfrm_policy *xp,
1324 copy_to_user_policy(xp, &upe->pol, dir); 1455 copy_to_user_policy(xp, &upe->pol, dir);
1325 if (copy_to_user_tmpl(xp, skb) < 0) 1456 if (copy_to_user_tmpl(xp, skb) < 0)
1326 goto nlmsg_failure; 1457 goto nlmsg_failure;
1458 if (copy_to_user_sec_ctx(xp, skb))
1459 goto nlmsg_failure;
1327 upe->hard = !!hard; 1460 upe->hard = !!hard;
1328 1461
1329 nlh->nlmsg_len = skb->tail - b; 1462 nlh->nlmsg_len = skb->tail - b;
@@ -1341,6 +1474,7 @@ static int xfrm_exp_policy_notify(struct xfrm_policy *xp, int dir, struct km_eve
1341 1474
1342 len = RTA_SPACE(sizeof(struct xfrm_user_tmpl) * xp->xfrm_nr); 1475 len = RTA_SPACE(sizeof(struct xfrm_user_tmpl) * xp->xfrm_nr);
1343 len += NLMSG_SPACE(sizeof(struct xfrm_user_polexpire)); 1476 len += NLMSG_SPACE(sizeof(struct xfrm_user_polexpire));
1477 len += RTA_SPACE(xfrm_user_sec_ctx_size(xp));
1344 skb = alloc_skb(len, GFP_ATOMIC); 1478 skb = alloc_skb(len, GFP_ATOMIC);
1345 if (skb == NULL) 1479 if (skb == NULL)
1346 return -ENOMEM; 1480 return -ENOMEM;
diff --git a/security/Kconfig b/security/Kconfig
index 64d3f1e9ca85..34f593410d57 100644
--- a/security/Kconfig
+++ b/security/Kconfig
@@ -54,6 +54,19 @@ config SECURITY_NETWORK
54 implement socket and networking access controls. 54 implement socket and networking access controls.
55 If you are unsure how to answer this question, answer N. 55 If you are unsure how to answer this question, answer N.
56 56
57config SECURITY_NETWORK_XFRM
58 bool "XFRM (IPSec) Networking Security Hooks"
59 depends on XFRM && SECURITY_NETWORK
60 help
61 This enables the XFRM (IPSec) networking security hooks.
62 If enabled, a security module can use these hooks to
63 implement per-packet access controls based on labels
64 derived from IPSec policy. Non-IPSec communications are
65 designated as unlabelled, and only sockets authorized
66 to communicate unlabelled data can send without using
67 IPSec.
68 If you are unsure how to answer this question, answer N.
69
57config SECURITY_CAPABILITIES 70config SECURITY_CAPABILITIES
58 tristate "Default Linux Capabilities" 71 tristate "Default Linux Capabilities"
59 depends on SECURITY 72 depends on SECURITY
diff --git a/security/dummy.c b/security/dummy.c
index 3ca5f2b828a0..a15c54709fde 100644
--- a/security/dummy.c
+++ b/security/dummy.c
@@ -776,8 +776,42 @@ static inline int dummy_sk_alloc_security (struct sock *sk, int family, gfp_t pr
776static inline void dummy_sk_free_security (struct sock *sk) 776static inline void dummy_sk_free_security (struct sock *sk)
777{ 777{
778} 778}
779
780static unsigned int dummy_sk_getsid(struct sock *sk, struct flowi *fl, u8 dir)
781{
782 return 0;
783}
779#endif /* CONFIG_SECURITY_NETWORK */ 784#endif /* CONFIG_SECURITY_NETWORK */
780 785
786#ifdef CONFIG_SECURITY_NETWORK_XFRM
787static int dummy_xfrm_policy_alloc_security(struct xfrm_policy *xp, struct xfrm_user_sec_ctx *sec_ctx)
788{
789 return 0;
790}
791
792static inline int dummy_xfrm_policy_clone_security(struct xfrm_policy *old, struct xfrm_policy *new)
793{
794 return 0;
795}
796
797static void dummy_xfrm_policy_free_security(struct xfrm_policy *xp)
798{
799}
800
801static int dummy_xfrm_state_alloc_security(struct xfrm_state *x, struct xfrm_user_sec_ctx *sec_ctx)
802{
803 return 0;
804}
805
806static void dummy_xfrm_state_free_security(struct xfrm_state *x)
807{
808}
809
810static int dummy_xfrm_policy_lookup(struct xfrm_policy *xp, u32 sk_sid, u8 dir)
811{
812 return 0;
813}
814#endif /* CONFIG_SECURITY_NETWORK_XFRM */
781static int dummy_register_security (const char *name, struct security_operations *ops) 815static int dummy_register_security (const char *name, struct security_operations *ops)
782{ 816{
783 return -EINVAL; 817 return -EINVAL;
@@ -970,7 +1004,16 @@ void security_fixup_ops (struct security_operations *ops)
970 set_to_dummy_if_null(ops, socket_getpeersec); 1004 set_to_dummy_if_null(ops, socket_getpeersec);
971 set_to_dummy_if_null(ops, sk_alloc_security); 1005 set_to_dummy_if_null(ops, sk_alloc_security);
972 set_to_dummy_if_null(ops, sk_free_security); 1006 set_to_dummy_if_null(ops, sk_free_security);
973#endif /* CONFIG_SECURITY_NETWORK */ 1007 set_to_dummy_if_null(ops, sk_getsid);
1008 #endif /* CONFIG_SECURITY_NETWORK */
1009#ifdef CONFIG_SECURITY_NETWORK_XFRM
1010 set_to_dummy_if_null(ops, xfrm_policy_alloc_security);
1011 set_to_dummy_if_null(ops, xfrm_policy_clone_security);
1012 set_to_dummy_if_null(ops, xfrm_policy_free_security);
1013 set_to_dummy_if_null(ops, xfrm_state_alloc_security);
1014 set_to_dummy_if_null(ops, xfrm_state_free_security);
1015 set_to_dummy_if_null(ops, xfrm_policy_lookup);
1016#endif /* CONFIG_SECURITY_NETWORK_XFRM */
974#ifdef CONFIG_KEYS 1017#ifdef CONFIG_KEYS
975 set_to_dummy_if_null(ops, key_alloc); 1018 set_to_dummy_if_null(ops, key_alloc);
976 set_to_dummy_if_null(ops, key_free); 1019 set_to_dummy_if_null(ops, key_free);