1 /* 2 * NSA Security-Enhanced Linux (SELinux) security module 3 * 4 * This file contains the SELinux XFRM hook function implementations. 5 * 6 * Authors: Serge Hallyn <sergeh@us.ibm.com> 7 * Trent Jaeger <jaegert@us.ibm.com> 8 * 9 * Copyright (C) 2005 International Business Machines Corporation 10 * 11 * This program is free software; you can redistribute it and/or modify 12 * it under the terms of the GNU General Public License version 2, 13 * as published by the Free Software Foundation. 14 */ 15 16 /* 17 * USAGE: 18 * NOTES: 19 * 1. Make sure to enable the following options in your kernel config: 20 * CONFIG_SECURITY=y 21 * CONFIG_SECURITY_NETWORK=y 22 * CONFIG_SECURITY_NETWORK_XFRM=y 23 * CONFIG_SECURITY_SELINUX=m/y 24 * ISSUES: 25 * 1. Caching packets, so they are not dropped during negotiation 26 * 2. Emulating a reasonable SO_PEERSEC across machines 27 * 3. Testing addition of sk_policy's with security context via setsockopt 28 */ 29 #include <linux/config.h> 30 #include <linux/module.h> 31 #include <linux/kernel.h> 32 #include <linux/init.h> 33 #include <linux/security.h> 34 #include <linux/types.h> 35 #include <linux/netfilter.h> 36 #include <linux/netfilter_ipv4.h> 37 #include <linux/netfilter_ipv6.h> 38 #include <linux/ip.h> 39 #include <linux/tcp.h> 40 #include <linux/skbuff.h> 41 #include <linux/xfrm.h> 42 #include <net/xfrm.h> 43 #include <net/checksum.h> 44 #include <net/udp.h> 45 #include <asm/semaphore.h> 46 47 #include "avc.h" 48 #include "objsec.h" 49 #include "xfrm.h" 50 51 52 /* 53 * Returns true if an LSM/SELinux context 54 */ 55 static inline int selinux_authorizable_ctx(struct xfrm_sec_ctx *ctx) 56 { 57 return (ctx && 58 (ctx->ctx_doi == XFRM_SC_DOI_LSM) && 59 (ctx->ctx_alg == XFRM_SC_ALG_SELINUX)); 60 } 61 62 /* 63 * Returns true if the xfrm contains a security blob for SELinux 64 */ 65 static inline int selinux_authorizable_xfrm(struct xfrm_state *x) 66 { 67 return selinux_authorizable_ctx(x->security); 68 } 69 70 /* 71 * LSM hook implementation that authorizes that a socket can be used 72 * with the corresponding xfrm_sec_ctx and direction. 73 */ 74 int selinux_xfrm_policy_lookup(struct xfrm_policy *xp, u32 sk_sid, u8 dir) 75 { 76 int rc = 0; 77 u32 sel_sid = SECINITSID_UNLABELED; 78 struct xfrm_sec_ctx *ctx; 79 80 /* Context sid is either set to label or ANY_ASSOC */ 81 if ((ctx = xp->security)) { 82 if (!selinux_authorizable_ctx(ctx)) 83 return -EINVAL; 84 85 sel_sid = ctx->ctx_sid; 86 } 87 88 rc = avc_has_perm(sk_sid, sel_sid, SECCLASS_ASSOCIATION, 89 ((dir == FLOW_DIR_IN) ? ASSOCIATION__RECVFROM : 90 ((dir == FLOW_DIR_OUT) ? ASSOCIATION__SENDTO : 91 (ASSOCIATION__SENDTO | ASSOCIATION__RECVFROM))), 92 NULL); 93 94 return rc; 95 } 96 97 /* 98 * Security blob allocation for xfrm_policy and xfrm_state 99 * CTX does not have a meaningful value on input 100 */ 101 static int selinux_xfrm_sec_ctx_alloc(struct xfrm_sec_ctx **ctxp, struct xfrm_user_sec_ctx *uctx) 102 { 103 int rc = 0; 104 struct task_security_struct *tsec = current->security; 105 struct xfrm_sec_ctx *ctx; 106 107 BUG_ON(!uctx); 108 BUG_ON(uctx->ctx_doi != XFRM_SC_ALG_SELINUX); 109 110 if (uctx->ctx_len >= PAGE_SIZE) 111 return -ENOMEM; 112 113 *ctxp = ctx = kmalloc(sizeof(*ctx) + 114 uctx->ctx_len, 115 GFP_KERNEL); 116 117 if (!ctx) 118 return -ENOMEM; 119 120 ctx->ctx_doi = uctx->ctx_doi; 121 ctx->ctx_len = uctx->ctx_len; 122 ctx->ctx_alg = uctx->ctx_alg; 123 124 memcpy(ctx->ctx_str, 125 uctx+1, 126 ctx->ctx_len); 127 rc = security_context_to_sid(ctx->ctx_str, 128 ctx->ctx_len, 129 &ctx->ctx_sid); 130 131 if (rc) 132 goto out; 133 134 /* 135 * Does the subject have permission to set security or permission to 136 * do the relabel? 137 * Must be permitted to relabel from default socket type (process type) 138 * to specified context 139 */ 140 rc = avc_has_perm(tsec->sid, ctx->ctx_sid, 141 SECCLASS_ASSOCIATION, 142 ASSOCIATION__SETCONTEXT, NULL); 143 if (rc) 144 goto out; 145 146 return rc; 147 148 out: 149 *ctxp = NULL; 150 kfree(ctx); 151 return rc; 152 } 153 154 /* 155 * LSM hook implementation that allocs and transfers uctx spec to 156 * xfrm_policy. 157 */ 158 int selinux_xfrm_policy_alloc(struct xfrm_policy *xp, struct xfrm_user_sec_ctx *uctx) 159 { 160 int err; 161 162 BUG_ON(!xp); 163 164 err = selinux_xfrm_sec_ctx_alloc(&xp->security, uctx); 165 return err; 166 } 167 168 169 /* 170 * LSM hook implementation that copies security data structure from old to 171 * new for policy cloning. 172 */ 173 int selinux_xfrm_policy_clone(struct xfrm_policy *old, struct xfrm_policy *new) 174 { 175 struct xfrm_sec_ctx *old_ctx, *new_ctx; 176 177 old_ctx = old->security; 178 179 if (old_ctx) { 180 new_ctx = new->security = kmalloc(sizeof(*new_ctx) + 181 old_ctx->ctx_len, 182 GFP_KERNEL); 183 184 if (!new_ctx) 185 return -ENOMEM; 186 187 memcpy(new_ctx, old_ctx, sizeof(*new_ctx)); 188 memcpy(new_ctx->ctx_str, old_ctx->ctx_str, new_ctx->ctx_len); 189 } 190 return 0; 191 } 192 193 /* 194 * LSM hook implementation that frees xfrm_policy security information. 195 */ 196 void selinux_xfrm_policy_free(struct xfrm_policy *xp) 197 { 198 struct xfrm_sec_ctx *ctx = xp->security; 199 if (ctx) 200 kfree(ctx); 201 } 202 203 /* 204 * LSM hook implementation that allocs and transfers sec_ctx spec to 205 * xfrm_state. 206 */ 207 int selinux_xfrm_state_alloc(struct xfrm_state *x, struct xfrm_user_sec_ctx *uctx) 208 { 209 int err; 210 211 BUG_ON(!x); 212 213 err = selinux_xfrm_sec_ctx_alloc(&x->security, uctx); 214 return err; 215 } 216 217 /* 218 * LSM hook implementation that frees xfrm_state security information. 219 */ 220 void selinux_xfrm_state_free(struct xfrm_state *x) 221 { 222 struct xfrm_sec_ctx *ctx = x->security; 223 if (ctx) 224 kfree(ctx); 225 } 226 227 /* 228 * SELinux internal function to retrieve the context of a connected 229 * (sk->sk_state == TCP_ESTABLISHED) TCP socket based on its security 230 * association used to connect to the remote socket. 231 * 232 * Retrieve via getsockopt SO_PEERSEC. 233 */ 234 u32 selinux_socket_getpeer_stream(struct sock *sk) 235 { 236 struct dst_entry *dst, *dst_test; 237 u32 peer_sid = SECSID_NULL; 238 239 if (sk->sk_state != TCP_ESTABLISHED) 240 goto out; 241 242 dst = sk_dst_get(sk); 243 if (!dst) 244 goto out; 245 246 for (dst_test = dst; dst_test != 0; 247 dst_test = dst_test->child) { 248 struct xfrm_state *x = dst_test->xfrm; 249 250 if (x && selinux_authorizable_xfrm(x)) { 251 struct xfrm_sec_ctx *ctx = x->security; 252 peer_sid = ctx->ctx_sid; 253 break; 254 } 255 } 256 dst_release(dst); 257 258 out: 259 return peer_sid; 260 } 261 262 /* 263 * SELinux internal function to retrieve the context of a UDP packet 264 * based on its security association used to connect to the remote socket. 265 * 266 * Retrieve via setsockopt IP_PASSSEC and recvmsg with control message 267 * type SCM_SECURITY. 268 */ 269 u32 selinux_socket_getpeer_dgram(struct sk_buff *skb) 270 { 271 struct sec_path *sp; 272 273 if (skb == NULL) 274 return SECSID_NULL; 275 276 if (skb->sk->sk_protocol != IPPROTO_UDP) 277 return SECSID_NULL; 278 279 sp = skb->sp; 280 if (sp) { 281 int i; 282 283 for (i = sp->len-1; i >= 0; i--) { 284 struct xfrm_state *x = sp->x[i].xvec; 285 if (selinux_authorizable_xfrm(x)) { 286 struct xfrm_sec_ctx *ctx = x->security; 287 return ctx->ctx_sid; 288 } 289 } 290 } 291 292 return SECSID_NULL; 293 } 294 295 /* 296 * LSM hook that controls access to unlabelled packets. If 297 * a xfrm_state is authorizable (defined by macro) then it was 298 * already authorized by the IPSec process. If not, then 299 * we need to check for unlabelled access since this may not have 300 * gone thru the IPSec process. 301 */ 302 int selinux_xfrm_sock_rcv_skb(u32 isec_sid, struct sk_buff *skb) 303 { 304 int i, rc = 0; 305 struct sec_path *sp; 306 307 sp = skb->sp; 308 309 if (sp) { 310 /* 311 * __xfrm_policy_check does not approve unless xfrm_policy_ok 312 * says that spi's match for policy and the socket. 313 * 314 * Only need to verify the existence of an authorizable sp. 315 */ 316 for (i = 0; i < sp->len; i++) { 317 struct xfrm_state *x = sp->x[i].xvec; 318 319 if (x && selinux_authorizable_xfrm(x)) 320 goto accept; 321 } 322 } 323 324 /* check SELinux sock for unlabelled access */ 325 rc = avc_has_perm(isec_sid, SECINITSID_UNLABELED, SECCLASS_ASSOCIATION, 326 ASSOCIATION__RECVFROM, NULL); 327 if (rc) 328 goto drop; 329 330 accept: 331 return 0; 332 333 drop: 334 return rc; 335 } 336 337 /* 338 * POSTROUTE_LAST hook's XFRM processing: 339 * If we have no security association, then we need to determine 340 * whether the socket is allowed to send to an unlabelled destination. 341 * If we do have a authorizable security association, then it has already been 342 * checked in xfrm_policy_lookup hook. 343 */ 344 int selinux_xfrm_postroute_last(u32 isec_sid, struct sk_buff *skb) 345 { 346 struct dst_entry *dst; 347 int rc = 0; 348 349 dst = skb->dst; 350 351 if (dst) { 352 struct dst_entry *dst_test; 353 354 for (dst_test = dst; dst_test != 0; 355 dst_test = dst_test->child) { 356 struct xfrm_state *x = dst_test->xfrm; 357 358 if (x && selinux_authorizable_xfrm(x)) 359 goto accept; 360 } 361 } 362 363 rc = avc_has_perm(isec_sid, SECINITSID_UNLABELED, SECCLASS_ASSOCIATION, 364 ASSOCIATION__SENDTO, NULL); 365 if (rc) 366 goto drop; 367 368 accept: 369 return NF_ACCEPT; 370 371 drop: 372 return NF_DROP; 373 } 374