diff options
| author | Linus Torvalds <torvalds@linux-foundation.org> | 2018-06-06 19:15:56 -0400 |
|---|---|---|
| committer | Linus Torvalds <torvalds@linux-foundation.org> | 2018-06-06 19:15:56 -0400 |
| commit | 10b1eb7d8ce5635a7deb273f8291d8a0a7681de1 (patch) | |
| tree | 946b7d496a4e24db5120be376e075b52982fae83 | |
| parent | d75ae5bdf2353e5c6a1f83da5f6f2d31582f09a3 (diff) | |
| parent | 890e2abe1028c39e5399101a2c277219cd637aaa (diff) | |
Merge branch 'next-general' of git://git.kernel.org/pub/scm/linux/kernel/git/jmorris/linux-security
Pull security system updates from James Morris:
- incorporate new socketpair() hook into LSM and wire up the SELinux
and Smack modules. From David Herrmann:
"The idea is to allow SO_PEERSEC to be called on AF_UNIX sockets
created via socketpair(2), and return the same information as if
you emulated socketpair(2) via a temporary listener socket.
Right now SO_PEERSEC will return the unlabeled credentials for a
socketpair, rather than the actual credentials of the creating
process."
- remove the unused security_settime LSM hook (Sargun Dhillon).
- remove some stack allocated arrays from the keys code (Tycho
Andersen)
* 'next-general' of git://git.kernel.org/pub/scm/linux/kernel/git/jmorris/linux-security:
dh key: get rid of stack allocated array for zeroes
dh key: get rid of stack allocated array
big key: get rid of stack array allocation
smack: provide socketpair callback
selinux: provide socketpair callback
net: hook socketpair() into LSM
security: add hook for socketpair()
security: remove security_settime
| -rw-r--r-- | include/linux/lsm_hooks.h | 7 | ||||
| -rw-r--r-- | include/linux/security.h | 21 | ||||
| -rw-r--r-- | net/socket.c | 7 | ||||
| -rw-r--r-- | security/keys/big_key.c | 11 | ||||
| -rw-r--r-- | security/keys/dh.c | 35 | ||||
| -rw-r--r-- | security/security.c | 6 | ||||
| -rw-r--r-- | security/selinux/hooks.c | 13 | ||||
| -rw-r--r-- | security/smack/smack_lsm.c | 22 |
8 files changed, 85 insertions, 37 deletions
diff --git a/include/linux/lsm_hooks.h b/include/linux/lsm_hooks.h index 9d0b286f3dba..8f1131c8dd54 100644 --- a/include/linux/lsm_hooks.h +++ b/include/linux/lsm_hooks.h | |||
| @@ -757,6 +757,11 @@ | |||
| 757 | * @type contains the requested communications type. | 757 | * @type contains the requested communications type. |
| 758 | * @protocol contains the requested protocol. | 758 | * @protocol contains the requested protocol. |
| 759 | * @kern set to 1 if a kernel socket. | 759 | * @kern set to 1 if a kernel socket. |
| 760 | * @socket_socketpair: | ||
| 761 | * Check permissions before creating a fresh pair of sockets. | ||
| 762 | * @socka contains the first socket structure. | ||
| 763 | * @sockb contains the second socket structure. | ||
| 764 | * Return 0 if permission is granted and the connection was established. | ||
| 760 | * @socket_bind: | 765 | * @socket_bind: |
| 761 | * Check permission before socket protocol layer bind operation is | 766 | * Check permission before socket protocol layer bind operation is |
| 762 | * performed and the socket @sock is bound to the address specified in the | 767 | * performed and the socket @sock is bound to the address specified in the |
| @@ -1656,6 +1661,7 @@ union security_list_options { | |||
| 1656 | int (*socket_create)(int family, int type, int protocol, int kern); | 1661 | int (*socket_create)(int family, int type, int protocol, int kern); |
| 1657 | int (*socket_post_create)(struct socket *sock, int family, int type, | 1662 | int (*socket_post_create)(struct socket *sock, int family, int type, |
| 1658 | int protocol, int kern); | 1663 | int protocol, int kern); |
| 1664 | int (*socket_socketpair)(struct socket *socka, struct socket *sockb); | ||
| 1659 | int (*socket_bind)(struct socket *sock, struct sockaddr *address, | 1665 | int (*socket_bind)(struct socket *sock, struct sockaddr *address, |
| 1660 | int addrlen); | 1666 | int addrlen); |
| 1661 | int (*socket_connect)(struct socket *sock, struct sockaddr *address, | 1667 | int (*socket_connect)(struct socket *sock, struct sockaddr *address, |
| @@ -1922,6 +1928,7 @@ struct security_hook_heads { | |||
| 1922 | struct hlist_head unix_may_send; | 1928 | struct hlist_head unix_may_send; |
| 1923 | struct hlist_head socket_create; | 1929 | struct hlist_head socket_create; |
| 1924 | struct hlist_head socket_post_create; | 1930 | struct hlist_head socket_post_create; |
| 1931 | struct hlist_head socket_socketpair; | ||
| 1925 | struct hlist_head socket_bind; | 1932 | struct hlist_head socket_bind; |
| 1926 | struct hlist_head socket_connect; | 1933 | struct hlist_head socket_connect; |
| 1927 | struct hlist_head socket_listen; | 1934 | struct hlist_head socket_listen; |
diff --git a/include/linux/security.h b/include/linux/security.h index 200920f521a1..63030c85ee19 100644 --- a/include/linux/security.h +++ b/include/linux/security.h | |||
| @@ -220,12 +220,6 @@ int security_quotactl(int cmds, int type, int id, struct super_block *sb); | |||
| 220 | int security_quota_on(struct dentry *dentry); | 220 | int security_quota_on(struct dentry *dentry); |
| 221 | int security_syslog(int type); | 221 | int security_syslog(int type); |
| 222 | int security_settime64(const struct timespec64 *ts, const struct timezone *tz); | 222 | int security_settime64(const struct timespec64 *ts, const struct timezone *tz); |
| 223 | static inline int security_settime(const struct timespec *ts, const struct timezone *tz) | ||
| 224 | { | ||
| 225 | struct timespec64 ts64 = timespec_to_timespec64(*ts); | ||
| 226 | |||
| 227 | return security_settime64(&ts64, tz); | ||
| 228 | } | ||
| 229 | int security_vm_enough_memory_mm(struct mm_struct *mm, long pages); | 223 | int security_vm_enough_memory_mm(struct mm_struct *mm, long pages); |
| 230 | int security_bprm_set_creds(struct linux_binprm *bprm); | 224 | int security_bprm_set_creds(struct linux_binprm *bprm); |
| 231 | int security_bprm_check(struct linux_binprm *bprm); | 225 | int security_bprm_check(struct linux_binprm *bprm); |
| @@ -508,14 +502,6 @@ static inline int security_settime64(const struct timespec64 *ts, | |||
| 508 | return cap_settime(ts, tz); | 502 | return cap_settime(ts, tz); |
| 509 | } | 503 | } |
| 510 | 504 | ||
| 511 | static inline int security_settime(const struct timespec *ts, | ||
| 512 | const struct timezone *tz) | ||
| 513 | { | ||
| 514 | struct timespec64 ts64 = timespec_to_timespec64(*ts); | ||
| 515 | |||
| 516 | return cap_settime(&ts64, tz); | ||
| 517 | } | ||
| 518 | |||
| 519 | static inline int security_vm_enough_memory_mm(struct mm_struct *mm, long pages) | 505 | static inline int security_vm_enough_memory_mm(struct mm_struct *mm, long pages) |
| 520 | { | 506 | { |
| 521 | return __vm_enough_memory(mm, pages, cap_vm_enough_memory(mm, pages)); | 507 | return __vm_enough_memory(mm, pages, cap_vm_enough_memory(mm, pages)); |
| @@ -1191,6 +1177,7 @@ int security_unix_may_send(struct socket *sock, struct socket *other); | |||
| 1191 | int security_socket_create(int family, int type, int protocol, int kern); | 1177 | int security_socket_create(int family, int type, int protocol, int kern); |
| 1192 | int security_socket_post_create(struct socket *sock, int family, | 1178 | int security_socket_post_create(struct socket *sock, int family, |
| 1193 | int type, int protocol, int kern); | 1179 | int type, int protocol, int kern); |
| 1180 | int security_socket_socketpair(struct socket *socka, struct socket *sockb); | ||
| 1194 | int security_socket_bind(struct socket *sock, struct sockaddr *address, int addrlen); | 1181 | int security_socket_bind(struct socket *sock, struct sockaddr *address, int addrlen); |
| 1195 | int security_socket_connect(struct socket *sock, struct sockaddr *address, int addrlen); | 1182 | int security_socket_connect(struct socket *sock, struct sockaddr *address, int addrlen); |
| 1196 | int security_socket_listen(struct socket *sock, int backlog); | 1183 | int security_socket_listen(struct socket *sock, int backlog); |
| @@ -1262,6 +1249,12 @@ static inline int security_socket_post_create(struct socket *sock, | |||
| 1262 | return 0; | 1249 | return 0; |
| 1263 | } | 1250 | } |
| 1264 | 1251 | ||
| 1252 | static inline int security_socket_socketpair(struct socket *socka, | ||
| 1253 | struct socket *sockb) | ||
| 1254 | { | ||
| 1255 | return 0; | ||
| 1256 | } | ||
| 1257 | |||
| 1265 | static inline int security_socket_bind(struct socket *sock, | 1258 | static inline int security_socket_bind(struct socket *sock, |
| 1266 | struct sockaddr *address, | 1259 | struct sockaddr *address, |
| 1267 | int addrlen) | 1260 | int addrlen) |
diff --git a/net/socket.c b/net/socket.c index 2d752e9eb3f9..af57d85bcb48 100644 --- a/net/socket.c +++ b/net/socket.c | |||
| @@ -1445,6 +1445,13 @@ int __sys_socketpair(int family, int type, int protocol, int __user *usockvec) | |||
| 1445 | goto out; | 1445 | goto out; |
| 1446 | } | 1446 | } |
| 1447 | 1447 | ||
| 1448 | err = security_socket_socketpair(sock1, sock2); | ||
| 1449 | if (unlikely(err)) { | ||
| 1450 | sock_release(sock2); | ||
| 1451 | sock_release(sock1); | ||
| 1452 | goto out; | ||
| 1453 | } | ||
| 1454 | |||
| 1448 | err = sock1->ops->socketpair(sock1, sock2); | 1455 | err = sock1->ops->socketpair(sock1, sock2); |
| 1449 | if (unlikely(err < 0)) { | 1456 | if (unlikely(err < 0)) { |
| 1450 | sock_release(sock2); | 1457 | sock_release(sock2); |
diff --git a/security/keys/big_key.c b/security/keys/big_key.c index 933623784ccd..2806e70d7f8f 100644 --- a/security/keys/big_key.c +++ b/security/keys/big_key.c | |||
| @@ -22,6 +22,7 @@ | |||
| 22 | #include <keys/user-type.h> | 22 | #include <keys/user-type.h> |
| 23 | #include <keys/big_key-type.h> | 23 | #include <keys/big_key-type.h> |
| 24 | #include <crypto/aead.h> | 24 | #include <crypto/aead.h> |
| 25 | #include <crypto/gcm.h> | ||
| 25 | 26 | ||
| 26 | struct big_key_buf { | 27 | struct big_key_buf { |
| 27 | unsigned int nr_pages; | 28 | unsigned int nr_pages; |
| @@ -85,6 +86,7 @@ struct key_type key_type_big_key = { | |||
| 85 | * Crypto names for big_key data authenticated encryption | 86 | * Crypto names for big_key data authenticated encryption |
| 86 | */ | 87 | */ |
| 87 | static const char big_key_alg_name[] = "gcm(aes)"; | 88 | static const char big_key_alg_name[] = "gcm(aes)"; |
| 89 | #define BIG_KEY_IV_SIZE GCM_AES_IV_SIZE | ||
| 88 | 90 | ||
| 89 | /* | 91 | /* |
| 90 | * Crypto algorithms for big_key data authenticated encryption | 92 | * Crypto algorithms for big_key data authenticated encryption |
| @@ -109,7 +111,7 @@ static int big_key_crypt(enum big_key_op op, struct big_key_buf *buf, size_t dat | |||
| 109 | * an .update function, so there's no chance we'll wind up reusing the | 111 | * an .update function, so there's no chance we'll wind up reusing the |
| 110 | * key to encrypt updated data. Simply put: one key, one encryption. | 112 | * key to encrypt updated data. Simply put: one key, one encryption. |
| 111 | */ | 113 | */ |
| 112 | u8 zero_nonce[crypto_aead_ivsize(big_key_aead)]; | 114 | u8 zero_nonce[BIG_KEY_IV_SIZE]; |
| 113 | 115 | ||
| 114 | aead_req = aead_request_alloc(big_key_aead, GFP_KERNEL); | 116 | aead_req = aead_request_alloc(big_key_aead, GFP_KERNEL); |
| 115 | if (!aead_req) | 117 | if (!aead_req) |
| @@ -425,6 +427,13 @@ static int __init big_key_init(void) | |||
| 425 | pr_err("Can't alloc crypto: %d\n", ret); | 427 | pr_err("Can't alloc crypto: %d\n", ret); |
| 426 | return ret; | 428 | return ret; |
| 427 | } | 429 | } |
| 430 | |||
| 431 | if (unlikely(crypto_aead_ivsize(big_key_aead) != BIG_KEY_IV_SIZE)) { | ||
| 432 | WARN(1, "big key algorithm changed?"); | ||
| 433 | ret = -EINVAL; | ||
| 434 | goto free_aead; | ||
| 435 | } | ||
| 436 | |||
| 428 | ret = crypto_aead_setauthsize(big_key_aead, ENC_AUTHTAG_SIZE); | 437 | ret = crypto_aead_setauthsize(big_key_aead, ENC_AUTHTAG_SIZE); |
| 429 | if (ret < 0) { | 438 | if (ret < 0) { |
| 430 | pr_err("Can't set crypto auth tag len: %d\n", ret); | 439 | pr_err("Can't set crypto auth tag len: %d\n", ret); |
diff --git a/security/keys/dh.c b/security/keys/dh.c index d1ea9f325f94..f7403821db7f 100644 --- a/security/keys/dh.c +++ b/security/keys/dh.c | |||
| @@ -162,8 +162,8 @@ static int kdf_ctr(struct kdf_sdesc *sdesc, const u8 *src, unsigned int slen, | |||
| 162 | goto err; | 162 | goto err; |
| 163 | 163 | ||
| 164 | if (zlen && h) { | 164 | if (zlen && h) { |
| 165 | u8 tmpbuffer[h]; | 165 | u8 tmpbuffer[32]; |
| 166 | size_t chunk = min_t(size_t, zlen, h); | 166 | size_t chunk = min_t(size_t, zlen, sizeof(tmpbuffer)); |
| 167 | memset(tmpbuffer, 0, chunk); | 167 | memset(tmpbuffer, 0, chunk); |
| 168 | 168 | ||
| 169 | do { | 169 | do { |
| @@ -173,7 +173,7 @@ static int kdf_ctr(struct kdf_sdesc *sdesc, const u8 *src, unsigned int slen, | |||
| 173 | goto err; | 173 | goto err; |
| 174 | 174 | ||
| 175 | zlen -= chunk; | ||
