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 context? 136 */ 137 rc = avc_has_perm(tsec->sid, ctx->ctx_sid, 138 SECCLASS_ASSOCIATION, 139 ASSOCIATION__SETCONTEXT, NULL); 140 if (rc) 141 goto out; 142 143 return rc; 144 145 out: 146 *ctxp = NULL; 147 kfree(ctx); 148 return rc; 149 } 150 151 /* 152 * LSM hook implementation that allocs and transfers uctx spec to 153 * xfrm_policy. 154 */ 155 int selinux_xfrm_policy_alloc(struct xfrm_policy *xp, struct xfrm_user_sec_ctx *uctx) 156 { 157 int err; 158 159 BUG_ON(!xp); 160 161 err = selinux_xfrm_sec_ctx_alloc(&xp->security, uctx); 162 return err; 163 } 164 165 166 /* 167 * LSM hook implementation that copies security data structure from old to 168 * new for policy cloning. 169 */ 170 int selinux_xfrm_policy_clone(struct xfrm_policy *old, struct xfrm_policy *new) 171 { 172 struct xfrm_sec_ctx *old_ctx, *new_ctx; 173 174 old_ctx = old->security; 175 176 if (old_ctx) { 177 new_ctx = new->security = kmalloc(sizeof(*new_ctx) + 178 old_ctx->ctx_len, 179 GFP_KERNEL); 180 181 if (!new_ctx) 182 return -ENOMEM; 183 184 memcpy(new_ctx, old_ctx, sizeof(*new_ctx)); 185 memcpy(new_ctx->ctx_str, old_ctx->ctx_str, new_ctx->ctx_len); 186 } 187 return 0; 188 } 189 190 /* 191 * LSM hook implementation that frees xfrm_policy security information. 192 */ 193 void selinux_xfrm_policy_free(struct xfrm_policy *xp) 194 { 195 struct xfrm_sec_ctx *ctx = xp->security; 196 if (ctx) 197 kfree(ctx); 198 } 199 200 /* 201 * LSM hook implementation that authorizes deletion of labeled policies. 202 */ 203 int selinux_xfrm_policy_delete(struct xfrm_policy *xp) 204 { 205 struct task_security_struct *tsec = current->security; 206 struct xfrm_sec_ctx *ctx = xp->security; 207 int rc = 0; 208 209 if (ctx) 210 rc = avc_has_perm(tsec->sid, ctx->ctx_sid, 211 SECCLASS_ASSOCIATION, 212 ASSOCIATION__SETCONTEXT, NULL); 213 214 return rc; 215 } 216 217 /* 218 * LSM hook implementation that allocs and transfers sec_ctx spec to 219 * xfrm_state. 220 */ 221 int selinux_xfrm_state_alloc(struct xfrm_state *x, struct xfrm_user_sec_ctx *uctx) 222 { 223 int err; 224 225 BUG_ON(!x); 226 227 err = selinux_xfrm_sec_ctx_alloc(&x->security, uctx); 228 return err; 229 } 230 231 /* 232 * LSM hook implementation that frees xfrm_state security information. 233 */ 234 void selinux_xfrm_state_free(struct xfrm_state *x) 235 { 236 struct xfrm_sec_ctx *ctx = x->security; 237 if (ctx) 238 kfree(ctx); 239 } 240 241 /* 242 * SELinux internal function to retrieve the context of a connected 243 * (sk->sk_state == TCP_ESTABLISHED) TCP socket based on its security 244 * association used to connect to the remote socket. 245 * 246 * Retrieve via getsockopt SO_PEERSEC. 247 */ 248 u32 selinux_socket_getpeer_stream(struct sock *sk) 249 { 250 struct dst_entry *dst, *dst_test; 251 u32 peer_sid = SECSID_NULL; 252 253 if (sk->sk_state != TCP_ESTABLISHED) 254 goto out; 255 256 dst = sk_dst_get(sk); 257 if (!dst) 258 goto out; 259 260 for (dst_test = dst; dst_test != 0; 261 dst_test = dst_test->child) { 262 struct xfrm_state *x = dst_test->xfrm; 263 264 if (x && selinux_authorizable_xfrm(x)) { 265 struct xfrm_sec_ctx *ctx = x->security; 266 peer_sid = ctx->ctx_sid; 267 break; 268 } 269 } 270 dst_release(dst); 271 272 out: 273 return peer_sid; 274 } 275 276 /* 277 * SELinux internal function to retrieve the context of a UDP packet 278 * based on its security association used to connect to the remote socket. 279 * 280 * Retrieve via setsockopt IP_PASSSEC and recvmsg with control message 281 * type SCM_SECURITY. 282 */ 283 u32 selinux_socket_getpeer_dgram(struct sk_buff *skb) 284 { 285 struct sec_path *sp; 286 287 if (skb == NULL) 288 return SECSID_NULL; 289 290 if (skb->sk->sk_protocol != IPPROTO_UDP) 291 return SECSID_NULL; 292 293 sp = skb->sp; 294 if (sp) { 295 int i; 296 297 for (i = sp->len-1; i >= 0; i--) { 298 struct xfrm_state *x = sp->xvec[i]; 299 if (selinux_authorizable_xfrm(x)) { 300 struct xfrm_sec_ctx *ctx = x->security; 301 return ctx->ctx_sid; 302 } 303 } 304 } 305 306 return SECSID_NULL; 307 } 308 309 /* 310 * LSM hook implementation that authorizes deletion of labeled SAs. 311 */ 312 int selinux_xfrm_state_delete(struct xfrm_state *x) 313 { 314 struct task_security_struct *tsec = current->security; 315 struct xfrm_sec_ctx *ctx = x->security; 316 int rc = 0; 317 318 if (ctx) 319 rc = avc_has_perm(tsec->sid, ctx->ctx_sid, 320 SECCLASS_ASSOCIATION, 321 ASSOCIATION__SETCONTEXT, NULL); 322 323 return rc; 324 } 325 326 /* 327 * LSM hook that controls access to unlabelled packets. If 328 * a xfrm_state is authorizable (defined by macro) then it was 329 * already authorized by the IPSec process. If not, then 330 * we need to check for unlabelled access since this may not have 331 * gone thru the IPSec process. 332 */ 333 int selinux_xfrm_sock_rcv_skb(u32 isec_sid, struct sk_buff *skb) 334 { 335 int i, rc = 0; 336 struct sec_path *sp; 337 338 sp = skb->sp; 339 340 if (sp) { 341 /* 342 * __xfrm_policy_check does not approve unless xfrm_policy_ok 343 * says that spi's match for policy and the socket. 344 * 345 * Only need to verify the existence of an authorizable sp. 346 */ 347 for (i = 0; i < sp->len; i++) { 348 struct xfrm_state *x = sp->xvec[i]; 349 350 if (x && selinux_authorizable_xfrm(x)) 351 goto accept; 352 } 353 } 354 355 /* check SELinux sock for unlabelled access */ 356 rc = avc_has_perm(isec_sid, SECINITSID_UNLABELED, SECCLASS_ASSOCIATION, 357 ASSOCIATION__RECVFROM, NULL); 358 if (rc) 359 goto drop; 360 361 accept: 362 return 0; 363 364 drop: 365 return rc; 366 } 367 368 /* 369 * POSTROUTE_LAST hook's XFRM processing: 370 * If we have no security association, then we need to determine 371 * whether the socket is allowed to send to an unlabelled destination. 372 * If we do have a authorizable security association, then it has already been 373 * checked in xfrm_policy_lookup hook. 374 */ 375 int selinux_xfrm_postroute_last(u32 isec_sid, struct sk_buff *skb) 376 { 377 struct dst_entry *dst; 378 int rc = 0; 379 380 dst = skb->dst; 381 382 if (dst) { 383 struct dst_entry *dst_test; 384 385 for (dst_test = dst; dst_test != 0; 386 dst_test = dst_test->child) { 387 struct xfrm_state *x = dst_test->xfrm; 388 389 if (x && selinux_authorizable_xfrm(x)) 390 goto out; 391 } 392 } 393 394 rc = avc_has_perm(isec_sid, SECINITSID_UNLABELED, SECCLASS_ASSOCIATION, 395 ASSOCIATION__SENDTO, NULL); 396 out: 397 return rc; 398 } 399