diff options
Diffstat (limited to 'net')
| -rw-r--r-- | net/core/sock.c | 11 | ||||
| -rw-r--r-- | net/unix/af_unix.c | 27 |
2 files changed, 38 insertions, 0 deletions
diff --git a/net/core/sock.c b/net/core/sock.c index 5d820c376653..204a8dec65cc 100644 --- a/net/core/sock.c +++ b/net/core/sock.c | |||
| @@ -565,6 +565,13 @@ set_rcvbuf: | |||
| 565 | ret = -ENONET; | 565 | ret = -ENONET; |
| 566 | break; | 566 | break; |
| 567 | 567 | ||
| 568 | case SO_PASSSEC: | ||
| 569 | if (valbool) | ||
| 570 | set_bit(SOCK_PASSSEC, &sock->flags); | ||
| 571 | else | ||
| 572 | clear_bit(SOCK_PASSSEC, &sock->flags); | ||
| 573 | break; | ||
| 574 | |||
| 568 | /* We implement the SO_SNDLOWAT etc to | 575 | /* We implement the SO_SNDLOWAT etc to |
| 569 | not be settable (1003.1g 5.3) */ | 576 | not be settable (1003.1g 5.3) */ |
| 570 | default: | 577 | default: |
| @@ -723,6 +730,10 @@ int sock_getsockopt(struct socket *sock, int level, int optname, | |||
| 723 | v.val = sk->sk_state == TCP_LISTEN; | 730 | v.val = sk->sk_state == TCP_LISTEN; |
| 724 | break; | 731 | break; |
| 725 | 732 | ||
| 733 | case SO_PASSSEC: | ||
| 734 | v.val = test_bit(SOCK_PASSSEC, &sock->flags) ? 1 : 0; | ||
| 735 | break; | ||
| 736 | |||
| 726 | case SO_PEERSEC: | 737 | case SO_PEERSEC: |
| 727 | return security_socket_getpeersec_stream(sock, optval, optlen, len); | 738 | return security_socket_getpeersec_stream(sock, optval, optlen, len); |
| 728 | 739 | ||
diff --git a/net/unix/af_unix.c b/net/unix/af_unix.c index d901465ce013..fd11d4048b52 100644 --- a/net/unix/af_unix.c +++ b/net/unix/af_unix.c | |||
| @@ -128,6 +128,30 @@ static atomic_t unix_nr_socks = ATOMIC_INIT(0); | |||
| 128 | 128 | ||
| 129 | #define UNIX_ABSTRACT(sk) (unix_sk(sk)->addr->hash != UNIX_HASH_SIZE) | 129 | #define UNIX_ABSTRACT(sk) (unix_sk(sk)->addr->hash != UNIX_HASH_SIZE) |
| 130 | 130 | ||
| 131 | #ifdef CONFIG_SECURITY_NETWORK | ||
| 132 | static void unix_get_peersec_dgram(struct sk_buff *skb) | ||
| 133 | { | ||
| 134 | int err; | ||
| 135 | |||
| 136 | err = security_socket_getpeersec_dgram(skb, UNIXSECDATA(skb), | ||
| 137 | UNIXSECLEN(skb)); | ||
| 138 | if (err) | ||
| 139 | *(UNIXSECDATA(skb)) = NULL; | ||
| 140 | } | ||
| 141 | |||
| 142 | static inline void unix_set_secdata(struct scm_cookie *scm, struct sk_buff *skb) | ||
| 143 | { | ||
| 144 | scm->secdata = *UNIXSECDATA(skb); | ||
| 145 | scm->seclen = *UNIXSECLEN(skb); | ||
| 146 | } | ||
| 147 | #else | ||
| 148 | static void unix_get_peersec_dgram(struct sk_buff *skb) | ||
| 149 | { } | ||
| 150 | |||
| 151 | static inline void unix_set_secdata(struct scm_cookie *scm, struct sk_buff *skb) | ||
| 152 | { } | ||
| 153 | #endif /* CONFIG_SECURITY_NETWORK */ | ||
| 154 | |||
| 131 | /* | 155 | /* |
| 132 | * SMP locking strategy: | 156 | * SMP locking strategy: |
| 133 | * hash table is protected with spinlock unix_table_lock | 157 | * hash table is protected with spinlock unix_table_lock |
| @@ -1291,6 +1315,8 @@ static int unix_dgram_sendmsg(struct kiocb *kiocb, struct socket *sock, | |||
| 1291 | if (siocb->scm->fp) | 1315 | if (siocb->scm->fp) |
| 1292 | unix_attach_fds(siocb->scm, skb); | 1316 | unix_attach_fds(siocb->scm, skb); |
| 1293 | 1317 | ||
| 1318 | unix_get_peersec_dgram(skb); | ||
| 1319 | |||
| 1294 | skb->h.raw = skb->data; | 1320 | skb->h.raw = skb->data; |
| 1295 | err = memcpy_fromiovec(skb_put(skb,len), msg->msg_iov, len); | 1321 | err = memcpy_fromiovec(skb_put(skb,len), msg->msg_iov, len); |
| 1296 | if (err) | 1322 | if (err) |
| @@ -1570,6 +1596,7 @@ static int unix_dgram_recvmsg(struct kiocb *iocb, struct socket *sock, | |||
| 1570 | memset(&tmp_scm, 0, sizeof(tmp_scm)); | 1596 | memset(&tmp_scm, 0, sizeof(tmp_scm)); |
| 1571 | } | 1597 | } |
| 1572 | siocb->scm->creds = *UNIXCREDS(skb); | 1598 | siocb->scm->creds = *UNIXCREDS(skb); |
| 1599 | unix_set_secdata(siocb->scm, skb); | ||
| 1573 | 1600 | ||
| 1574 | if (!(flags & MSG_PEEK)) | 1601 | if (!(flags & MSG_PEEK)) |
| 1575 | { | 1602 | { |
