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