diff options
| author | Steven Whitehouse <swhiteho@redhat.com> | 2006-09-25 12:26:59 -0400 |
|---|---|---|
| committer | Steven Whitehouse <swhiteho@redhat.com> | 2006-09-25 12:26:59 -0400 |
| commit | 363e065c02b1273364d5356711a83e7f548fc0c8 (patch) | |
| tree | 0df0e65da403ade33ade580c2770c97437b1b1af /security/selinux/hooks.c | |
| parent | 907b9bceb41fa46beae93f79cc4a2247df502c0f (diff) | |
| parent | 7c250413e5b7c3dfae89354725b70c76d7621395 (diff) | |
[GFS2] Fix up merge of Linus' kernel into GFS2
This fixes up a couple of conflicts when merging up with
Linus' latest kernel. This will hopefully allow GFS2 to
be more easily merged into forthcoming -mm and FC kernels
due to the "one line per header" format now used for the
kernel headers.
Signed-off-by: Steven Whitehouse <swhiteho@redhat.com>
Conflicts:
include/linux/Kbuild
include/linux/kernel.h
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 |
