diff options
author | James Bottomley <jejb@sparkweed.localdomain> | 2006-09-23 22:03:52 -0400 |
---|---|---|
committer | James Bottomley <jejb@sparkweed.localdomain> | 2006-09-23 22:03:52 -0400 |
commit | 1aedf2ccc60fade26c46fae12e28664d0da3f199 (patch) | |
tree | d91083e3079f1ddb942a382ac2b5a7525570ad59 /security/selinux/hooks.c | |
parent | dfdc58ba354adb80d67c99f7be84f95a8e02e466 (diff) | |
parent | 1ab9dd0902df4f4ff56fbf672220549090ab28ba (diff) |
Merge mulgrave-w:git/linux-2.6
Conflicts:
include/linux/blkdev.h
Trivial merge to incorporate tag prototypes.
Diffstat (limited to 'security/selinux/hooks.c')
-rw-r--r-- | security/selinux/hooks.c | 245 |
1 files changed, 174 insertions, 71 deletions
diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c index 5d1b8c733199..5a66c4c09f7a 100644 --- a/security/selinux/hooks.c +++ b/security/selinux/hooks.c | |||
@@ -12,6 +12,8 @@ | |||
12 | * Copyright (C) 2003 Red Hat, Inc., James Morris <jmorris@redhat.com> | 12 | * Copyright (C) 2003 Red Hat, Inc., James Morris <jmorris@redhat.com> |
13 | * Copyright (C) 2004-2005 Trusted Computer Solutions, Inc. | 13 | * Copyright (C) 2004-2005 Trusted Computer Solutions, Inc. |
14 | * <dgoeddel@trustedcs.com> | 14 | * <dgoeddel@trustedcs.com> |
15 | * Copyright (C) 2006 Hewlett-Packard Development Company, L.P. | ||
16 | * Paul Moore, <paul.moore@hp.com> | ||
15 | * | 17 | * |
16 | * This program is free software; you can redistribute it and/or modify | 18 | * This program is free software; you can redistribute it and/or modify |
17 | * it under the terms of the GNU General Public License version 2, | 19 | * it under the terms of the GNU General Public License version 2, |
@@ -74,6 +76,7 @@ | |||
74 | #include "objsec.h" | 76 | #include "objsec.h" |
75 | #include "netif.h" | 77 | #include "netif.h" |
76 | #include "xfrm.h" | 78 | #include "xfrm.h" |
79 | #include "selinux_netlabel.h" | ||
77 | 80 | ||
78 | #define XATTR_SELINUX_SUFFIX "selinux" | 81 | #define XATTR_SELINUX_SUFFIX "selinux" |
79 | #define XATTR_NAME_SELINUX XATTR_SECURITY_PREFIX XATTR_SELINUX_SUFFIX | 82 | #define XATTR_NAME_SELINUX XATTR_SECURITY_PREFIX XATTR_SELINUX_SUFFIX |
@@ -269,17 +272,17 @@ static int sk_alloc_security(struct sock *sk, int family, gfp_t priority) | |||
269 | { | 272 | { |
270 | struct sk_security_struct *ssec; | 273 | struct sk_security_struct *ssec; |
271 | 274 | ||
272 | if (family != PF_UNIX) | ||
273 | return 0; | ||
274 | |||
275 | ssec = kzalloc(sizeof(*ssec), priority); | 275 | ssec = kzalloc(sizeof(*ssec), priority); |
276 | if (!ssec) | 276 | if (!ssec) |
277 | return -ENOMEM; | 277 | return -ENOMEM; |
278 | 278 | ||
279 | ssec->sk = sk; | 279 | ssec->sk = sk; |
280 | ssec->peer_sid = SECINITSID_UNLABELED; | 280 | ssec->peer_sid = SECINITSID_UNLABELED; |
281 | ssec->sid = SECINITSID_UNLABELED; | ||
281 | sk->sk_security = ssec; | 282 | sk->sk_security = ssec; |
282 | 283 | ||
284 | selinux_netlbl_sk_security_init(ssec, family); | ||
285 | |||
283 | return 0; | 286 | return 0; |
284 | } | 287 | } |
285 | 288 | ||
@@ -287,9 +290,6 @@ static void sk_free_security(struct sock *sk) | |||
287 | { | 290 | { |
288 | struct sk_security_struct *ssec = sk->sk_security; | 291 | struct sk_security_struct *ssec = sk->sk_security; |
289 | 292 | ||
290 | if (sk->sk_family != PF_UNIX) | ||
291 | return; | ||
292 | |||
293 | sk->sk_security = NULL; | 293 | sk->sk_security = NULL; |
294 | kfree(ssec); | 294 | kfree(ssec); |
295 | } | 295 | } |
@@ -2400,6 +2400,7 @@ static int selinux_inode_listsecurity(struct inode *inode, char *buffer, size_t | |||
2400 | 2400 | ||
2401 | static int selinux_file_permission(struct file *file, int mask) | 2401 | static int selinux_file_permission(struct file *file, int mask) |
2402 | { | 2402 | { |
2403 | int rc; | ||
2403 | struct inode *inode = file->f_dentry->d_inode; | 2404 | struct inode *inode = file->f_dentry->d_inode; |
2404 | 2405 | ||
2405 | if (!mask) { | 2406 | if (!mask) { |
@@ -2411,8 +2412,12 @@ static int selinux_file_permission(struct file *file, int mask) | |||
2411 | if ((file->f_flags & O_APPEND) && (mask & MAY_WRITE)) | 2412 | if ((file->f_flags & O_APPEND) && (mask & MAY_WRITE)) |
2412 | mask |= MAY_APPEND; | 2413 | mask |= MAY_APPEND; |
2413 | 2414 | ||
2414 | return file_has_perm(current, file, | 2415 | rc = file_has_perm(current, file, |
2415 | file_mask_to_av(inode->i_mode, mask)); | 2416 | file_mask_to_av(inode->i_mode, mask)); |
2417 | if (rc) | ||
2418 | return rc; | ||
2419 | |||
2420 | return selinux_netlbl_inode_permission(inode, mask); | ||
2416 | } | 2421 | } |
2417 | 2422 | ||
2418 | static int selinux_file_alloc_security(struct file *file) | 2423 | static int selinux_file_alloc_security(struct file *file) |
@@ -3063,11 +3068,13 @@ out: | |||
3063 | return err; | 3068 | return err; |
3064 | } | 3069 | } |
3065 | 3070 | ||
3066 | static void selinux_socket_post_create(struct socket *sock, int family, | 3071 | static int selinux_socket_post_create(struct socket *sock, int family, |
3067 | int type, int protocol, int kern) | 3072 | int type, int protocol, int kern) |
3068 | { | 3073 | { |
3074 | int err = 0; | ||
3069 | struct inode_security_struct *isec; | 3075 | struct inode_security_struct *isec; |
3070 | struct task_security_struct *tsec; | 3076 | struct task_security_struct *tsec; |
3077 | struct sk_security_struct *sksec; | ||
3071 | u32 newsid; | 3078 | u32 newsid; |
3072 | 3079 | ||
3073 | isec = SOCK_INODE(sock)->i_security; | 3080 | isec = SOCK_INODE(sock)->i_security; |
@@ -3078,7 +3085,15 @@ static void selinux_socket_post_create(struct socket *sock, int family, | |||
3078 | isec->sid = kern ? SECINITSID_KERNEL : newsid; | 3085 | isec->sid = kern ? SECINITSID_KERNEL : newsid; |
3079 | isec->initialized = 1; | 3086 | isec->initialized = 1; |
3080 | 3087 | ||
3081 | return; | 3088 | if (sock->sk) { |
3089 | sksec = sock->sk->sk_security; | ||
3090 | sksec->sid = isec->sid; | ||
3091 | err = selinux_netlbl_socket_post_create(sock, | ||
3092 | family, | ||
3093 | isec->sid); | ||
3094 | } | ||
3095 | |||
3096 | return err; | ||
3082 | } | 3097 | } |
3083 | 3098 | ||
3084 | /* Range of port numbers used to automatically bind. | 3099 | /* Range of port numbers used to automatically bind. |
@@ -3259,7 +3274,13 @@ static int selinux_socket_accept(struct socket *sock, struct socket *newsock) | |||
3259 | static int selinux_socket_sendmsg(struct socket *sock, struct msghdr *msg, | 3274 | static int selinux_socket_sendmsg(struct socket *sock, struct msghdr *msg, |
3260 | int size) | 3275 | int size) |
3261 | { | 3276 | { |
3262 | return socket_has_perm(current, sock, SOCKET__WRITE); | 3277 | int rc; |
3278 | |||
3279 | rc = socket_has_perm(current, sock, SOCKET__WRITE); | ||
3280 | if (rc) | ||
3281 | return rc; | ||
3282 | |||
3283 | return selinux_netlbl_inode_permission(SOCK_INODE(sock), MAY_WRITE); | ||
3263 | } | 3284 | } |
3264 | 3285 | ||
3265 | static int selinux_socket_recvmsg(struct socket *sock, struct msghdr *msg, | 3286 | static int selinux_socket_recvmsg(struct socket *sock, struct msghdr *msg, |
@@ -3327,8 +3348,9 @@ static int selinux_socket_unix_stream_connect(struct socket *sock, | |||
3327 | /* server child socket */ | 3348 | /* server child socket */ |
3328 | ssec = newsk->sk_security; | 3349 | ssec = newsk->sk_security; |
3329 | ssec->peer_sid = isec->sid; | 3350 | ssec->peer_sid = isec->sid; |
3330 | 3351 | err = security_sid_mls_copy(other_isec->sid, ssec->peer_sid, &ssec->sid); | |
3331 | return 0; | 3352 | |
3353 | return err; | ||
3332 | } | 3354 | } |
3333 | 3355 | ||
3334 | static int selinux_socket_unix_may_send(struct socket *sock, | 3356 | static int selinux_socket_unix_may_send(struct socket *sock, |
@@ -3354,11 +3376,29 @@ static int selinux_socket_unix_may_send(struct socket *sock, | |||
3354 | } | 3376 | } |
3355 | 3377 | ||
3356 | static int selinux_sock_rcv_skb_compat(struct sock *sk, struct sk_buff *skb, | 3378 | static int selinux_sock_rcv_skb_compat(struct sock *sk, struct sk_buff *skb, |
3357 | struct avc_audit_data *ad, u32 sock_sid, u16 sock_class, | 3379 | struct avc_audit_data *ad, u16 family, char *addrp, int len) |
3358 | u16 family, char *addrp, int len) | ||
3359 | { | 3380 | { |
3360 | int err = 0; | 3381 | int err = 0; |
3361 | u32 netif_perm, node_perm, node_sid, if_sid, recv_perm = 0; | 3382 | u32 netif_perm, node_perm, node_sid, if_sid, recv_perm = 0; |
3383 | struct socket *sock; | ||
3384 | u16 sock_class = 0; | ||
3385 | u32 sock_sid = 0; | ||
3386 | |||
3387 | read_lock_bh(&sk->sk_callback_lock); | ||
3388 | sock = sk->sk_socket; | ||
3389 | if (sock) { | ||
3390 | struct inode *inode; | ||
3391 | inode = SOCK_INODE(sock); | ||
3392 | if (inode) { | ||
3393 | struct inode_security_struct *isec; | ||
3394 | isec = inode->i_security; | ||
3395 | sock_sid = isec->sid; | ||
3396 | sock_class = isec->sclass; | ||
3397 | } | ||
3398 | } | ||
3399 | read_unlock_bh(&sk->sk_callback_lock); | ||
3400 | if (!sock_sid) | ||
3401 | goto out; | ||
3362 | 3402 | ||
3363 | if (!skb->dev) | 3403 | if (!skb->dev) |
3364 | goto out; | 3404 | goto out; |
@@ -3418,12 +3458,10 @@ out: | |||
3418 | static int selinux_socket_sock_rcv_skb(struct sock *sk, struct sk_buff *skb) | 3458 | static int selinux_socket_sock_rcv_skb(struct sock *sk, struct sk_buff *skb) |
3419 | { | 3459 | { |
3420 | u16 family; | 3460 | u16 family; |
3421 | u16 sock_class = 0; | ||
3422 | char *addrp; | 3461 | char *addrp; |
3423 | int len, err = 0; | 3462 | int len, err = 0; |
3424 | u32 sock_sid = 0; | ||
3425 | struct socket *sock; | ||
3426 | struct avc_audit_data ad; | 3463 | struct avc_audit_data ad; |
3464 | struct sk_security_struct *sksec = sk->sk_security; | ||
3427 | 3465 | ||
3428 | family = sk->sk_family; | 3466 | family = sk->sk_family; |
3429 | if (family != PF_INET && family != PF_INET6) | 3467 | if (family != PF_INET && family != PF_INET6) |
@@ -3433,22 +3471,6 @@ static int selinux_socket_sock_rcv_skb(struct sock *sk, struct sk_buff *skb) | |||
3433 | if (family == PF_INET6 && skb->protocol == ntohs(ETH_P_IP)) | 3471 | if (family == PF_INET6 && skb->protocol == ntohs(ETH_P_IP)) |
3434 | family = PF_INET; | 3472 | family = PF_INET; |
3435 | 3473 | ||
3436 | read_lock_bh(&sk->sk_callback_lock); | ||
3437 | sock = sk->sk_socket; | ||
3438 | if (sock) { | ||
3439 | struct inode *inode; | ||
3440 | inode = SOCK_INODE(sock); | ||
3441 | if (inode) { | ||
3442 | struct inode_security_struct *isec; | ||
3443 | isec = inode->i_security; | ||
3444 | sock_sid = isec->sid; | ||
3445 | sock_class = isec->sclass; | ||
3446 | } | ||
3447 | } | ||
3448 | read_unlock_bh(&sk->sk_callback_lock); | ||
3449 | if (!sock_sid) | ||
3450 | goto out; | ||
3451 | |||
3452 | AVC_AUDIT_DATA_INIT(&ad, NET); | 3474 | AVC_AUDIT_DATA_INIT(&ad, NET); |
3453 | ad.u.net.netif = skb->dev ? skb->dev->name : "[unknown]"; | 3475 | ad.u.net.netif = skb->dev ? skb->dev->name : "[unknown]"; |
3454 | ad.u.net.family = family; | 3476 | ad.u.net.family = family; |
@@ -3458,16 +3480,19 @@ static int selinux_socket_sock_rcv_skb(struct sock *sk, struct sk_buff *skb) | |||
3458 | goto out; | 3480 | goto out; |
3459 | 3481 | ||
3460 | if (selinux_compat_net) | 3482 | if (selinux_compat_net) |
3461 | err = selinux_sock_rcv_skb_compat(sk, skb, &ad, sock_sid, | 3483 | err = selinux_sock_rcv_skb_compat(sk, skb, &ad, family, |
3462 | sock_class, family, | ||
3463 | addrp, len); | 3484 | addrp, len); |
3464 | else | 3485 | else |
3465 | err = avc_has_perm(sock_sid, skb->secmark, SECCLASS_PACKET, | 3486 | err = avc_has_perm(sksec->sid, skb->secmark, SECCLASS_PACKET, |
3466 | PACKET__RECV, &ad); | 3487 | PACKET__RECV, &ad); |
3467 | if (err) | 3488 | if (err) |
3468 | goto out; | 3489 | goto out; |
3469 | 3490 | ||
3470 | err = selinux_xfrm_sock_rcv_skb(sock_sid, skb); | 3491 | err = selinux_netlbl_sock_rcv_skb(sksec, skb, &ad); |
3492 | if (err) | ||
3493 | goto out; | ||
3494 | |||
3495 | err = selinux_xfrm_sock_rcv_skb(sksec->sid, skb, &ad); | ||
3471 | out: | 3496 | out: |
3472 | return err; | 3497 | return err; |
3473 | } | 3498 | } |
@@ -3490,8 +3515,9 @@ static int selinux_socket_getpeersec_stream(struct socket *sock, char __user *op | |||
3490 | peer_sid = ssec->peer_sid; | 3515 | peer_sid = ssec->peer_sid; |
3491 | } | 3516 | } |
3492 | else if (isec->sclass == SECCLASS_TCP_SOCKET) { | 3517 | else if (isec->sclass == SECCLASS_TCP_SOCKET) { |
3493 | peer_sid = selinux_socket_getpeer_stream(sock->sk); | 3518 | peer_sid = selinux_netlbl_socket_getpeersec_stream(sock); |
3494 | 3519 | if (peer_sid == SECSID_NULL) | |
3520 | peer_sid = selinux_socket_getpeer_stream(sock->sk); | ||
3495 | if (peer_sid == SECSID_NULL) { | 3521 | if (peer_sid == SECSID_NULL) { |
3496 | err = -ENOPROTOOPT; | 3522 | err = -ENOPROTOOPT; |
3497 | goto out; | 3523 | goto out; |
@@ -3531,8 +3557,11 @@ static int selinux_socket_getpeersec_dgram(struct socket *sock, struct sk_buff * | |||
3531 | 3557 | ||
3532 | if (sock && (sock->sk->sk_family == PF_UNIX)) | 3558 | if (sock && (sock->sk->sk_family == PF_UNIX)) |
3533 | selinux_get_inode_sid(SOCK_INODE(sock), &peer_secid); | 3559 | selinux_get_inode_sid(SOCK_INODE(sock), &peer_secid); |
3534 | else if (skb) | 3560 | else if (skb) { |
3535 | peer_secid = selinux_socket_getpeer_dgram(skb); | 3561 | peer_secid = selinux_netlbl_socket_getpeersec_dgram(skb); |
3562 | if (peer_secid == SECSID_NULL) | ||
3563 | peer_secid = selinux_socket_getpeer_dgram(skb); | ||
3564 | } | ||
3536 | 3565 | ||
3537 | if (peer_secid == SECSID_NULL) | 3566 | if (peer_secid == SECSID_NULL) |
3538 | err = -EINVAL; | 3567 | err = -EINVAL; |
@@ -3551,22 +3580,86 @@ static void selinux_sk_free_security(struct sock *sk) | |||
3551 | sk_free_security(sk); | 3580 | sk_free_security(sk); |
3552 | } | 3581 | } |
3553 | 3582 | ||
3554 | static unsigned int selinux_sk_getsid_security(struct sock *sk, struct flowi *fl, u8 dir) | 3583 | static void selinux_sk_clone_security(const struct sock *sk, struct sock *newsk) |
3555 | { | 3584 | { |
3556 | struct inode_security_struct *isec; | 3585 | struct sk_security_struct *ssec = sk->sk_security; |
3557 | u32 sock_sid = SECINITSID_ANY_SOCKET; | 3586 | struct sk_security_struct *newssec = newsk->sk_security; |
3587 | |||
3588 | newssec->sid = ssec->sid; | ||
3589 | newssec->peer_sid = ssec->peer_sid; | ||
3558 | 3590 | ||
3591 | selinux_netlbl_sk_clone_security(ssec, newssec); | ||
3592 | } | ||
3593 | |||
3594 | static void selinux_sk_getsecid(struct sock *sk, u32 *secid) | ||
3595 | { | ||
3559 | if (!sk) | 3596 | if (!sk) |
3560 | return selinux_no_sk_sid(fl); | 3597 | *secid = SECINITSID_ANY_SOCKET; |
3598 | else { | ||
3599 | struct sk_security_struct *sksec = sk->sk_security; | ||
3600 | |||
3601 | *secid = sksec->sid; | ||
3602 | } | ||
3603 | } | ||
3604 | |||
3605 | static void selinux_sock_graft(struct sock* sk, struct socket *parent) | ||
3606 | { | ||
3607 | struct inode_security_struct *isec = SOCK_INODE(parent)->i_security; | ||
3608 | struct sk_security_struct *sksec = sk->sk_security; | ||
3609 | |||
3610 | isec->sid = sksec->sid; | ||
3611 | |||
3612 | selinux_netlbl_sock_graft(sk, parent); | ||
3613 | } | ||
3614 | |||
3615 | static int selinux_inet_conn_request(struct sock *sk, struct sk_buff *skb, | ||
3616 | struct request_sock *req) | ||
3617 | { | ||
3618 | struct sk_security_struct *sksec = sk->sk_security; | ||
3619 | int err; | ||
3620 | u32 newsid; | ||
3621 | u32 peersid; | ||
3622 | |||
3623 | newsid = selinux_netlbl_inet_conn_request(skb, sksec->sid); | ||
3624 | if (newsid != SECSID_NULL) { | ||
3625 | req->secid = newsid; | ||
3626 | return 0; | ||
3627 | } | ||
3628 | |||
3629 | err = selinux_xfrm_decode_session(skb, &peersid, 0); | ||
3630 | BUG_ON(err); | ||
3631 | |||
3632 | if (peersid == SECSID_NULL) { | ||
3633 | req->secid = sksec->sid; | ||
3634 | return 0; | ||
3635 | } | ||
3636 | |||
3637 | err = security_sid_mls_copy(sksec->sid, peersid, &newsid); | ||
3638 | if (err) | ||
3639 | return err; | ||
3640 | |||
3641 | req->secid = newsid; | ||
3642 | return 0; | ||
3643 | } | ||
3644 | |||
3645 | static void selinux_inet_csk_clone(struct sock *newsk, | ||
3646 | const struct request_sock *req) | ||
3647 | { | ||
3648 | struct sk_security_struct *newsksec = newsk->sk_security; | ||
3561 | 3649 | ||
3562 | read_lock_bh(&sk->sk_callback_lock); | 3650 | newsksec->sid = req->secid; |
3563 | isec = get_sock_isec(sk); | 3651 | /* NOTE: Ideally, we should also get the isec->sid for the |
3652 | new socket in sync, but we don't have the isec available yet. | ||
3653 | So we will wait until sock_graft to do it, by which | ||
3654 | time it will have been created and available. */ | ||
3564 | 3655 | ||
3565 | if (isec) | 3656 | selinux_netlbl_sk_security_init(newsksec, req->rsk_ops->family); |
3566 | sock_sid = isec->sid; | 3657 | } |
3567 | 3658 | ||
3568 | read_unlock_bh(&sk->sk_callback_lock); | 3659 | static void selinux_req_classify_flow(const struct request_sock *req, |
3569 | return sock_sid; | 3660 | struct flowi *fl) |
3661 | { | ||
3662 | fl->secid = req->secid; | ||
3570 | } | 3663 | } |
3571 | 3664 | ||
3572 | static int selinux_nlmsg_perm(struct sock *sk, struct sk_buff *skb) | 3665 | static int selinux_nlmsg_perm(struct sock *sk, struct sk_buff *skb) |
@@ -3608,12 +3701,24 @@ out: | |||
3608 | #ifdef CONFIG_NETFILTER | 3701 | #ifdef CONFIG_NETFILTER |
3609 | 3702 | ||
3610 | static int selinux_ip_postroute_last_compat(struct sock *sk, struct net_device *dev, | 3703 | static int selinux_ip_postroute_last_compat(struct sock *sk, struct net_device *dev, |
3611 | struct inode_security_struct *isec, | ||
3612 | struct avc_audit_data *ad, | 3704 | struct avc_audit_data *ad, |
3613 | u16 family, char *addrp, int len) | 3705 | u16 family, char *addrp, int len) |
3614 | { | 3706 | { |
3615 | int err; | 3707 | int err = 0; |
3616 | u32 netif_perm, node_perm, node_sid, if_sid, send_perm = 0; | 3708 | u32 netif_perm, node_perm, node_sid, if_sid, send_perm = 0; |
3709 | struct socket *sock; | ||
3710 | struct inode *inode; | ||
3711 | struct inode_security_struct *isec; | ||
3712 | |||
3713 | sock = sk->sk_socket; | ||
3714 | if (!sock) | ||
3715 | goto out; | ||
3716 | |||
3717 | inode = SOCK_INODE(sock); | ||
3718 | if (!inode) | ||
3719 | goto out; | ||
3720 | |||
3721 | isec = inode->i_security; | ||
3617 | 3722 | ||
3618 | err = sel_netif_sids(dev, &if_sid, NULL); | 3723 | err = sel_netif_sids(dev, &if_sid, NULL); |
3619 | if (err) | 3724 | if (err) |
@@ -3678,26 +3783,16 @@ static unsigned int selinux_ip_postroute_last(unsigned int hooknum, | |||
3678 | char *addrp; | 3783 | char *addrp; |
3679 | int len, err = 0; | 3784 | int len, err = 0; |
3680 | struct sock *sk; | 3785 | struct sock *sk; |
3681 | struct socket *sock; | ||
3682 | struct inode *inode; | ||
3683 | struct sk_buff *skb = *pskb; | 3786 | struct sk_buff *skb = *pskb; |
3684 | struct inode_security_struct *isec; | ||
3685 | struct avc_audit_data ad; | 3787 | struct avc_audit_data ad; |
3686 | struct net_device *dev = (struct net_device *)out; | 3788 | struct net_device *dev = (struct net_device *)out; |
3789 | struct sk_security_struct *sksec; | ||
3687 | 3790 | ||
3688 | sk = skb->sk; | 3791 | sk = skb->sk; |
3689 | if (!sk) | 3792 | if (!sk) |
3690 | goto out; | 3793 | goto out; |
3691 | 3794 | ||
3692 | sock = sk->sk_socket; | 3795 | sksec = sk->sk_security; |
3693 | if (!sock) | ||
3694 | goto out; | ||
3695 | |||
3696 | inode = SOCK_INODE(sock); | ||
3697 | if (!inode) | ||
3698 | goto out; | ||
3699 | |||
3700 | isec = inode->i_security; | ||
3701 | 3796 | ||
3702 | AVC_AUDIT_DATA_INIT(&ad, NET); | 3797 | AVC_AUDIT_DATA_INIT(&ad, NET); |
3703 | ad.u.net.netif = dev->name; | 3798 | ad.u.net.netif = dev->name; |
@@ -3708,16 +3803,16 @@ static unsigned int selinux_ip_postroute_last(unsigned int hooknum, | |||
3708 | goto out; | 3803 | goto out; |
3709 | 3804 | ||
3710 | if (selinux_compat_net) | 3805 | if (selinux_compat_net) |
3711 | err = selinux_ip_postroute_last_compat(sk, dev, isec, &ad, | 3806 | err = selinux_ip_postroute_last_compat(sk, dev, &ad, |
3712 | family, addrp, len); | 3807 | family, addrp, len); |
3713 | else | 3808 | else |
3714 | err = avc_has_perm(isec->sid, skb->secmark, SECCLASS_PACKET, | 3809 | err = avc_has_perm(sksec->sid, skb->secmark, SECCLASS_PACKET, |
3715 | PACKET__SEND, &ad); | 3810 | PACKET__SEND, &ad); |
3716 | 3811 | ||
3717 | if (err) | 3812 | if (err) |
3718 | goto out; | 3813 | goto out; |
3719 | 3814 | ||
3720 | err = selinux_xfrm_postroute_last(isec->sid, skb); | 3815 | err = selinux_xfrm_postroute_last(sksec->sid, skb, &ad); |
3721 | out: | 3816 | out: |
3722 | return err ? NF_DROP : NF_ACCEPT; | 3817 | return err ? NF_DROP : NF_ACCEPT; |
3723 | } | 3818 | } |
@@ -4618,7 +4713,12 @@ static struct security_operations selinux_ops = { | |||
4618 | .socket_getpeersec_dgram = selinux_socket_getpeersec_dgram, | 4713 | .socket_getpeersec_dgram = selinux_socket_getpeersec_dgram, |
4619 | .sk_alloc_security = selinux_sk_alloc_security, | 4714 | .sk_alloc_security = selinux_sk_alloc_security, |
4620 | .sk_free_security = selinux_sk_free_security, | 4715 | .sk_free_security = selinux_sk_free_security, |
4621 | .sk_getsid = selinux_sk_getsid_security, | 4716 | .sk_clone_security = selinux_sk_clone_security, |
4717 | .sk_getsecid = selinux_sk_getsecid, | ||
4718 | .sock_graft = selinux_sock_graft, | ||
4719 | .inet_conn_request = selinux_inet_conn_request, | ||
4720 | .inet_csk_clone = selinux_inet_csk_clone, | ||
4721 | .req_classify_flow = selinux_req_classify_flow, | ||
4622 | 4722 | ||
4623 | #ifdef CONFIG_SECURITY_NETWORK_XFRM | 4723 | #ifdef CONFIG_SECURITY_NETWORK_XFRM |
4624 | .xfrm_policy_alloc_security = selinux_xfrm_policy_alloc, | 4724 | .xfrm_policy_alloc_security = selinux_xfrm_policy_alloc, |
@@ -4629,6 +4729,9 @@ static struct security_operations selinux_ops = { | |||
4629 | .xfrm_state_free_security = selinux_xfrm_state_free, | 4729 | .xfrm_state_free_security = selinux_xfrm_state_free, |
4630 | .xfrm_state_delete_security = selinux_xfrm_state_delete, | 4730 | .xfrm_state_delete_security = selinux_xfrm_state_delete, |
4631 | .xfrm_policy_lookup = selinux_xfrm_policy_lookup, | 4731 | .xfrm_policy_lookup = selinux_xfrm_policy_lookup, |
4732 | .xfrm_state_pol_flow_match = selinux_xfrm_state_pol_flow_match, | ||
4733 | .xfrm_flow_state_match = selinux_xfrm_flow_state_match, | ||
4734 | .xfrm_decode_session = selinux_xfrm_decode_session, | ||
4632 | #endif | 4735 | #endif |
4633 | 4736 | ||
4634 | #ifdef CONFIG_KEYS | 4737 | #ifdef CONFIG_KEYS |