Эх сурвалжийг харах

Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/jmorris/linux-security

* 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/jmorris/linux-security:
  integrity: digital signature config option name change
  lib: Removed MPILIB, MPILIB_EXTRA, and SIGNATURE prompts
  lib: MPILIB Kconfig description update
  lib: digital signature dependency fix
  lib: digital signature config option name change
  encrypted-keys: fix rcu and sparse messages
  keys: fix trusted/encrypted keys sparse rcu_assign_pointer messages
  KEYS: Add missing smp_rmb() primitives to the keyring search code
  TOMOYO: Accept \000 as a valid character.
  security: update MAINTAINERS file with new git repo
Linus Torvalds 13 жил өмнө
parent
commit
a25a2b8409

+ 1 - 1
MAINTAINERS

@@ -5846,7 +5846,7 @@ F:	drivers/mmc/host/sdhci-spear.c
 SECURITY SUBSYSTEM
 SECURITY SUBSYSTEM
 M:	James Morris <jmorris@namei.org>
 M:	James Morris <jmorris@namei.org>
 L:	linux-security-module@vger.kernel.org (suggested Cc:)
 L:	linux-security-module@vger.kernel.org (suggested Cc:)
-T:	git git://git.kernel.org/pub/scm/linux/kernel/git/jmorris/security-testing-2.6.git
+T:	git git://git.kernel.org/pub/scm/linux/kernel/git/jmorris/linux-security.git
 W:	http://security.wiki.kernel.org/
 W:	http://security.wiki.kernel.org/
 S:	Supported
 S:	Supported
 F:	security/
 F:	security/

+ 2 - 2
include/linux/digsig.h

@@ -46,7 +46,7 @@ struct signature_hdr {
 	char		mpi[0];
 	char		mpi[0];
 } __packed;
 } __packed;
 
 
-#if defined(CONFIG_DIGSIG) || defined(CONFIG_DIGSIG_MODULE)
+#if defined(CONFIG_SIGNATURE) || defined(CONFIG_SIGNATURE_MODULE)
 
 
 int digsig_verify(struct key *keyring, const char *sig, int siglen,
 int digsig_verify(struct key *keyring, const char *sig, int siglen,
 					const char *digest, int digestlen);
 					const char *digest, int digestlen);
@@ -59,6 +59,6 @@ static inline int digsig_verify(struct key *keyring, const char *sig,
 	return -EOPNOTSUPP;
 	return -EOPNOTSUPP;
 }
 }
 
 
-#endif /* CONFIG_DIGSIG */
+#endif /* CONFIG_SIGNATURE */
 
 
 #endif /* _DIGSIG_H */
 #endif /* _DIGSIG_H */

+ 3 - 0
include/linux/key.h

@@ -293,6 +293,9 @@ static inline bool key_is_instantiated(const struct key *key)
 	(rcu_dereference_protected((KEY)->payload.rcudata,		\
 	(rcu_dereference_protected((KEY)->payload.rcudata,		\
 				   rwsem_is_locked(&((struct key *)(KEY))->sem)))
 				   rwsem_is_locked(&((struct key *)(KEY))->sem)))
 
 
+#define rcu_assign_keypointer(KEY, PAYLOAD)				\
+	(rcu_assign_pointer((KEY)->payload.rcudata, PAYLOAD))
+
 #ifdef CONFIG_SYSCTL
 #ifdef CONFIG_SYSCTL
 extern ctl_table key_sysctls[];
 extern ctl_table key_sysctls[];
 #endif
 #endif

+ 9 - 10
lib/Kconfig

@@ -286,25 +286,24 @@ config CORDIC
 	  calculations are in fixed point. Module will be called cordic.
 	  calculations are in fixed point. Module will be called cordic.
 
 
 config MPILIB
 config MPILIB
-	tristate "Multiprecision maths library"
+	tristate
 	help
 	help
 	  Multiprecision maths library from GnuPG.
 	  Multiprecision maths library from GnuPG.
 	  It is used to implement RSA digital signature verification,
 	  It is used to implement RSA digital signature verification,
 	  which is used by IMA/EVM digital signature extension.
 	  which is used by IMA/EVM digital signature extension.
 
 
 config MPILIB_EXTRA
 config MPILIB_EXTRA
-	bool "Multiprecision maths library - additional sources"
+	bool
 	depends on MPILIB
 	depends on MPILIB
 	help
 	help
-	  Multiprecision maths library from GnuPG.
-	  It is used to implement RSA digital signature verification,
-	  which is used by IMA/EVM digital signature extension.
-	  This code in unnecessary for RSA digital signature verification,
-	  and can be compiled if needed.
+	  Additional sources of multiprecision maths library from GnuPG.
+	  This code is unnecessary for RSA digital signature verification,
+	  but can be compiled if needed.
 
 
-config DIGSIG
-	tristate "In-kernel signature checker"
-	depends on KEYS
+config SIGNATURE
+	tristate
+	depends on KEYS && CRYPTO
+	select CRYPTO_SHA1
 	select MPILIB
 	select MPILIB
 	help
 	help
 	  Digital signature verification. Currently only RSA is supported.
 	  Digital signature verification. Currently only RSA is supported.

+ 1 - 1
lib/Makefile

@@ -119,7 +119,7 @@ obj-$(CONFIG_CORDIC) += cordic.o
 obj-$(CONFIG_DQL) += dynamic_queue_limits.o
 obj-$(CONFIG_DQL) += dynamic_queue_limits.o
 
 
 obj-$(CONFIG_MPILIB) += mpi/
 obj-$(CONFIG_MPILIB) += mpi/
-obj-$(CONFIG_DIGSIG) += digsig.o
+obj-$(CONFIG_SIGNATURE) += digsig.o
 
 
 hostprogs-y	:= gen_crc32table
 hostprogs-y	:= gen_crc32table
 clean-files	:= crc32table.h
 clean-files	:= crc32table.h

+ 2 - 2
security/integrity/Kconfig

@@ -3,11 +3,11 @@ config INTEGRITY
 	def_bool y
 	def_bool y
 	depends on IMA || EVM
 	depends on IMA || EVM
 
 
-config INTEGRITY_DIGSIG
+config INTEGRITY_SIGNATURE
 	boolean "Digital signature verification using multiple keyrings"
 	boolean "Digital signature verification using multiple keyrings"
 	depends on INTEGRITY && KEYS
 	depends on INTEGRITY && KEYS
 	default n
 	default n
-	select DIGSIG
+	select SIGNATURE
 	help
 	help
 	  This option enables digital signature verification support
 	  This option enables digital signature verification support
 	  using multiple keyrings. It defines separate keyrings for each
 	  using multiple keyrings. It defines separate keyrings for each

+ 1 - 1
security/integrity/Makefile

@@ -3,7 +3,7 @@
 #
 #
 
 
 obj-$(CONFIG_INTEGRITY) += integrity.o
 obj-$(CONFIG_INTEGRITY) += integrity.o
-obj-$(CONFIG_INTEGRITY_DIGSIG) += digsig.o
+obj-$(CONFIG_INTEGRITY_SIGNATURE) += digsig.o
 
 
 integrity-y := iint.o
 integrity-y := iint.o
 
 

+ 2 - 2
security/integrity/integrity.h

@@ -51,7 +51,7 @@ struct integrity_iint_cache *integrity_iint_find(struct inode *inode);
 #define INTEGRITY_KEYRING_IMA		2
 #define INTEGRITY_KEYRING_IMA		2
 #define INTEGRITY_KEYRING_MAX		3
 #define INTEGRITY_KEYRING_MAX		3
 
 
-#ifdef CONFIG_INTEGRITY_DIGSIG
+#ifdef CONFIG_INTEGRITY_SIGNATURE
 
 
 int integrity_digsig_verify(const unsigned int id, const char *sig, int siglen,
 int integrity_digsig_verify(const unsigned int id, const char *sig, int siglen,
 					const char *digest, int digestlen);
 					const char *digest, int digestlen);
@@ -65,7 +65,7 @@ static inline int integrity_digsig_verify(const unsigned int id,
 	return -EOPNOTSUPP;
 	return -EOPNOTSUPP;
 }
 }
 
 
-#endif /* CONFIG_INTEGRITY_DIGSIG */
+#endif /* CONFIG_INTEGRITY_SIGNATURE */
 
 
 /* set during initialization */
 /* set during initialization */
 extern int iint_initialized;
 extern int iint_initialized;

+ 3 - 3
security/keys/encrypted-keys/encrypted.c

@@ -314,7 +314,7 @@ static struct key *request_user_key(const char *master_desc, u8 **master_key,
 		goto error;
 		goto error;
 
 
 	down_read(&ukey->sem);
 	down_read(&ukey->sem);
-	upayload = rcu_dereference(ukey->payload.data);
+	upayload = ukey->payload.data;
 	*master_key = upayload->data;
 	*master_key = upayload->data;
 	*master_keylen = upayload->datalen;
 	*master_keylen = upayload->datalen;
 error:
 error:
@@ -810,7 +810,7 @@ static int encrypted_instantiate(struct key *key, const void *data,
 		goto out;
 		goto out;
 	}
 	}
 
 
-	rcu_assign_pointer(key->payload.data, epayload);
+	rcu_assign_keypointer(key, epayload);
 out:
 out:
 	kfree(datablob);
 	kfree(datablob);
 	return ret;
 	return ret;
@@ -874,7 +874,7 @@ static int encrypted_update(struct key *key, const void *data, size_t datalen)
 	memcpy(new_epayload->payload_data, epayload->payload_data,
 	memcpy(new_epayload->payload_data, epayload->payload_data,
 	       epayload->payload_datalen);
 	       epayload->payload_datalen);
 
 
-	rcu_assign_pointer(key->payload.data, new_epayload);
+	rcu_assign_keypointer(key, new_epayload);
 	call_rcu(&epayload->rcu, encrypted_rcu_free);
 	call_rcu(&epayload->rcu, encrypted_rcu_free);
 out:
 out:
 	kfree(buf);
 	kfree(buf);

+ 3 - 1
security/keys/encrypted-keys/masterkey_trusted.c

@@ -18,6 +18,8 @@
 #include <linux/module.h>
 #include <linux/module.h>
 #include <linux/err.h>
 #include <linux/err.h>
 #include <keys/trusted-type.h>
 #include <keys/trusted-type.h>
+#include <keys/encrypted-type.h>
+#include "encrypted.h"
 
 
 /*
 /*
  * request_trusted_key - request the trusted key
  * request_trusted_key - request the trusted key
@@ -37,7 +39,7 @@ struct key *request_trusted_key(const char *trusted_desc,
 		goto error;
 		goto error;
 
 
 	down_read(&tkey->sem);
 	down_read(&tkey->sem);
-	tpayload = rcu_dereference(tkey->payload.data);
+	tpayload = tkey->payload.data;
 	*master_key = tpayload->key;
 	*master_key = tpayload->key;
 	*master_keylen = tpayload->key_len;
 	*master_keylen = tpayload->key_len;
 error:
 error:

+ 3 - 1
security/keys/gc.c

@@ -145,7 +145,9 @@ static void key_gc_keyring(struct key *keyring, time_t limit)
 	if (!klist)
 	if (!klist)
 		goto unlock_dont_gc;
 		goto unlock_dont_gc;
 
 
-	for (loop = klist->nkeys - 1; loop >= 0; loop--) {
+	loop = klist->nkeys;
+	smp_rmb();
+	for (loop--; loop >= 0; loop--) {
 		key = klist->keys[loop];
 		key = klist->keys[loop];
 		if (test_bit(KEY_FLAG_DEAD, &key->flags) ||
 		if (test_bit(KEY_FLAG_DEAD, &key->flags) ||
 		    (key->expiry > 0 && key->expiry <= limit))
 		    (key->expiry > 0 && key->expiry <= limit))

+ 15 - 7
security/keys/keyring.c

@@ -319,7 +319,7 @@ key_ref_t keyring_search_aux(key_ref_t keyring_ref,
 	struct key *keyring, *key;
 	struct key *keyring, *key;
 	key_ref_t key_ref;
 	key_ref_t key_ref;
 	long err;
 	long err;
-	int sp, kix;
+	int sp, nkeys, kix;
 
 
 	keyring = key_ref_to_ptr(keyring_ref);
 	keyring = key_ref_to_ptr(keyring_ref);
 	possessed = is_key_possessed(keyring_ref);
 	possessed = is_key_possessed(keyring_ref);
@@ -380,7 +380,9 @@ descend:
 		goto not_this_keyring;
 		goto not_this_keyring;
 
 
 	/* iterate through the keys in this keyring first */
 	/* iterate through the keys in this keyring first */
-	for (kix = 0; kix < keylist->nkeys; kix++) {
+	nkeys = keylist->nkeys;
+	smp_rmb();
+	for (kix = 0; kix < nkeys; kix++) {
 		key = keylist->keys[kix];
 		key = keylist->keys[kix];
 		kflags = key->flags;
 		kflags = key->flags;
 
 
@@ -421,7 +423,9 @@ descend:
 	/* search through the keyrings nested in this one */
 	/* search through the keyrings nested in this one */
 	kix = 0;
 	kix = 0;
 ascend:
 ascend:
-	for (; kix < keylist->nkeys; kix++) {
+	nkeys = keylist->nkeys;
+	smp_rmb();
+	for (; kix < nkeys; kix++) {
 		key = keylist->keys[kix];
 		key = keylist->keys[kix];
 		if (key->type != &key_type_keyring)
 		if (key->type != &key_type_keyring)
 			continue;
 			continue;
@@ -515,7 +519,7 @@ key_ref_t __keyring_search_one(key_ref_t keyring_ref,
 	struct keyring_list *klist;
 	struct keyring_list *klist;
 	unsigned long possessed;
 	unsigned long possessed;
 	struct key *keyring, *key;
 	struct key *keyring, *key;
-	int loop;
+	int nkeys, loop;
 
 
 	keyring = key_ref_to_ptr(keyring_ref);
 	keyring = key_ref_to_ptr(keyring_ref);
 	possessed = is_key_possessed(keyring_ref);
 	possessed = is_key_possessed(keyring_ref);
@@ -524,7 +528,9 @@ key_ref_t __keyring_search_one(key_ref_t keyring_ref,
 
 
 	klist = rcu_dereference(keyring->payload.subscriptions);
 	klist = rcu_dereference(keyring->payload.subscriptions);
 	if (klist) {
 	if (klist) {
-		for (loop = 0; loop < klist->nkeys; loop++) {
+		nkeys = klist->nkeys;
+		smp_rmb();
+		for (loop = 0; loop < nkeys ; loop++) {
 			key = klist->keys[loop];
 			key = klist->keys[loop];
 
 
 			if (key->type == ktype &&
 			if (key->type == ktype &&
@@ -622,7 +628,7 @@ static int keyring_detect_cycle(struct key *A, struct key *B)
 
 
 	struct keyring_list *keylist;
 	struct keyring_list *keylist;
 	struct key *subtree, *key;
 	struct key *subtree, *key;
-	int sp, kix, ret;
+	int sp, nkeys, kix, ret;
 
 
 	rcu_read_lock();
 	rcu_read_lock();
 
 
@@ -645,7 +651,9 @@ descend:
 
 
 ascend:
 ascend:
 	/* iterate through the remaining keys in this keyring */
 	/* iterate through the remaining keys in this keyring */
-	for (; kix < keylist->nkeys; kix++) {
+	nkeys = keylist->nkeys;
+	smp_rmb();
+	for (; kix < nkeys; kix++) {
 		key = keylist->keys[kix];
 		key = keylist->keys[kix];
 
 
 		if (key == A)
 		if (key == A)

+ 2 - 2
security/keys/trusted.c

@@ -993,7 +993,7 @@ out:
 	kfree(datablob);
 	kfree(datablob);
 	kfree(options);
 	kfree(options);
 	if (!ret)
 	if (!ret)
-		rcu_assign_pointer(key->payload.data, payload);
+		rcu_assign_keypointer(key, payload);
 	else
 	else
 		kfree(payload);
 		kfree(payload);
 	return ret;
 	return ret;
@@ -1067,7 +1067,7 @@ static int trusted_update(struct key *key, const void *data, size_t datalen)
 			goto out;
 			goto out;
 		}
 		}
 	}
 	}
-	rcu_assign_pointer(key->payload.data, new_p);
+	rcu_assign_keypointer(key, new_p);
 	call_rcu(&p->rcu, trusted_rcu_free);
 	call_rcu(&p->rcu, trusted_rcu_free);
 out:
 out:
 	kfree(datablob);
 	kfree(datablob);

+ 3 - 3
security/tomoyo/util.c

@@ -492,13 +492,13 @@ static bool tomoyo_correct_word2(const char *string, size_t len)
 				if (d < '0' || d > '7' || e < '0' || e > '7')
 				if (d < '0' || d > '7' || e < '0' || e > '7')
 					break;
 					break;
 				c = tomoyo_make_byte(c, d, e);
 				c = tomoyo_make_byte(c, d, e);
-				if (tomoyo_invalid(c))
-					continue; /* pattern is not \000 */
+				if (c <= ' ' || c >= 127)
+					continue;
 			}
 			}
 			goto out;
 			goto out;
 		} else if (in_repetition && c == '/') {
 		} else if (in_repetition && c == '/') {
 			goto out;
 			goto out;
-		} else if (tomoyo_invalid(c)) {
+		} else if (c <= ' ' || c >= 127) {
 			goto out;
 			goto out;
 		}
 		}
 	}
 	}