Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 10b1eb7d authored by Linus Torvalds's avatar Linus Torvalds
Browse files
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
parents d75ae5bd 890e2abe
Loading
Loading
Loading
Loading
+7 −0
Original line number Diff line number Diff line
@@ -757,6 +757,11 @@
 *	@type contains the requested communications type.
 *	@protocol contains the requested protocol.
 *	@kern set to 1 if a kernel socket.
 * @socket_socketpair:
 *	Check permissions before creating a fresh pair of sockets.
 *	@socka contains the first socket structure.
 *	@sockb contains the second socket structure.
 *	Return 0 if permission is granted and the connection was established.
 * @socket_bind:
 *	Check permission before socket protocol layer bind operation is
 *	performed and the socket @sock is bound to the address specified in the
@@ -1656,6 +1661,7 @@ union security_list_options {
	int (*socket_create)(int family, int type, int protocol, int kern);
	int (*socket_post_create)(struct socket *sock, int family, int type,
					int protocol, int kern);
	int (*socket_socketpair)(struct socket *socka, struct socket *sockb);
	int (*socket_bind)(struct socket *sock, struct sockaddr *address,
				int addrlen);
	int (*socket_connect)(struct socket *sock, struct sockaddr *address,
@@ -1922,6 +1928,7 @@ struct security_hook_heads {
	struct hlist_head unix_may_send;
	struct hlist_head socket_create;
	struct hlist_head socket_post_create;
	struct hlist_head socket_socketpair;
	struct hlist_head socket_bind;
	struct hlist_head socket_connect;
	struct hlist_head socket_listen;
+7 −14
Original line number Diff line number Diff line
@@ -220,12 +220,6 @@ int security_quotactl(int cmds, int type, int id, struct super_block *sb);
int security_quota_on(struct dentry *dentry);
int security_syslog(int type);
int security_settime64(const struct timespec64 *ts, const struct timezone *tz);
static inline int security_settime(const struct timespec *ts, const struct timezone *tz)
{
	struct timespec64 ts64 = timespec_to_timespec64(*ts);

	return security_settime64(&ts64, tz);
}
int security_vm_enough_memory_mm(struct mm_struct *mm, long pages);
int security_bprm_set_creds(struct linux_binprm *bprm);
int security_bprm_check(struct linux_binprm *bprm);
@@ -508,14 +502,6 @@ static inline int security_settime64(const struct timespec64 *ts,
	return cap_settime(ts, tz);
}

static inline int security_settime(const struct timespec *ts,
				   const struct timezone *tz)
{
	struct timespec64 ts64 = timespec_to_timespec64(*ts);

	return cap_settime(&ts64, tz);
}

static inline int security_vm_enough_memory_mm(struct mm_struct *mm, long pages)
{
	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);
int security_socket_create(int family, int type, int protocol, int kern);
int security_socket_post_create(struct socket *sock, int family,
				int type, int protocol, int kern);
int security_socket_socketpair(struct socket *socka, struct socket *sockb);
int security_socket_bind(struct socket *sock, struct sockaddr *address, int addrlen);
int security_socket_connect(struct socket *sock, struct sockaddr *address, int addrlen);
int security_socket_listen(struct socket *sock, int backlog);
@@ -1262,6 +1249,12 @@ static inline int security_socket_post_create(struct socket *sock,
	return 0;
}

static inline int security_socket_socketpair(struct socket *socka,
					     struct socket *sockb)
{
	return 0;
}

static inline int security_socket_bind(struct socket *sock,
				       struct sockaddr *address,
				       int addrlen)
+7 −0
Original line number Diff line number Diff line
@@ -1445,6 +1445,13 @@ int __sys_socketpair(int family, int type, int protocol, int __user *usockvec)
		goto out;
	}

	err = security_socket_socketpair(sock1, sock2);
	if (unlikely(err)) {
		sock_release(sock2);
		sock_release(sock1);
		goto out;
	}

	err = sock1->ops->socketpair(sock1, sock2);
	if (unlikely(err < 0)) {
		sock_release(sock2);
+10 −1
Original line number Diff line number Diff line
@@ -22,6 +22,7 @@
#include <keys/user-type.h>
#include <keys/big_key-type.h>
#include <crypto/aead.h>
#include <crypto/gcm.h>

struct big_key_buf {
	unsigned int		nr_pages;
@@ -85,6 +86,7 @@ struct key_type key_type_big_key = {
 * Crypto names for big_key data authenticated encryption
 */
static const char big_key_alg_name[] = "gcm(aes)";
#define BIG_KEY_IV_SIZE		GCM_AES_IV_SIZE

/*
 * 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
	 * an .update function, so there's no chance we'll wind up reusing the
	 * key to encrypt updated data. Simply put: one key, one encryption.
	 */
	u8 zero_nonce[crypto_aead_ivsize(big_key_aead)];
	u8 zero_nonce[BIG_KEY_IV_SIZE];

	aead_req = aead_request_alloc(big_key_aead, GFP_KERNEL);
	if (!aead_req)
@@ -425,6 +427,13 @@ static int __init big_key_init(void)
		pr_err("Can't alloc crypto: %d\n", ret);
		return ret;
	}

	if (unlikely(crypto_aead_ivsize(big_key_aead) != BIG_KEY_IV_SIZE)) {
		WARN(1, "big key algorithm changed?");
		ret = -EINVAL;
		goto free_aead;
	}

	ret = crypto_aead_setauthsize(big_key_aead, ENC_AUTHTAG_SIZE);
	if (ret < 0) {
		pr_err("Can't set crypto auth tag len: %d\n", ret);
+13 −22
Original line number Diff line number Diff line
@@ -162,8 +162,8 @@ static int kdf_ctr(struct kdf_sdesc *sdesc, const u8 *src, unsigned int slen,
			goto err;

		if (zlen && h) {
			u8 tmpbuffer[h];
			size_t chunk = min_t(size_t, zlen, h);
			u8 tmpbuffer[32];
			size_t chunk = min_t(size_t, zlen, sizeof(tmpbuffer));
			memset(tmpbuffer, 0, chunk);

			do {
@@ -173,7 +173,7 @@ static int kdf_ctr(struct kdf_sdesc *sdesc, const u8 *src, unsigned int slen,
					goto err;

				zlen -= chunk;
				chunk = min_t(size_t, zlen, h);
				chunk = min_t(size_t, zlen, sizeof(tmpbuffer));
			} while (zlen);
		}

@@ -183,16 +183,6 @@ static int kdf_ctr(struct kdf_sdesc *sdesc, const u8 *src, unsigned int slen,
				goto err;
		}

		if (dlen < h) {
			u8 tmpbuffer[h];

			err = crypto_shash_final(desc, tmpbuffer);
			if (err)
				goto err;
			memcpy(dst, tmpbuffer, dlen);
			memzero_explicit(tmpbuffer, h);
			return 0;
		} else {
		err = crypto_shash_final(desc, dst);
		if (err)
			goto err;
@@ -201,7 +191,6 @@ static int kdf_ctr(struct kdf_sdesc *sdesc, const u8 *src, unsigned int slen,
		dst += h;
		counter = cpu_to_be32(be32_to_cpu(counter) + 1);
	}
	}

	return 0;

@@ -216,14 +205,16 @@ static int keyctl_dh_compute_kdf(struct kdf_sdesc *sdesc,
{
	uint8_t *outbuf = NULL;
	int ret;
	size_t outbuf_len = round_up(buflen,
			             crypto_shash_digestsize(sdesc->shash.tfm));

	outbuf = kmalloc(buflen, GFP_KERNEL);
	outbuf = kmalloc(outbuf_len, GFP_KERNEL);
	if (!outbuf) {
		ret = -ENOMEM;
		goto err;
	}

	ret = kdf_ctr(sdesc, kbuf, kbuflen, outbuf, buflen, lzero);
	ret = kdf_ctr(sdesc, kbuf, kbuflen, outbuf, outbuf_len, lzero);
	if (ret)
		goto err;

Loading