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
This commit is contained in:
commit
a25a2b8409
|
@ -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/
|
||||||
|
|
|
@ -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 */
|
||||||
|
|
|
@ -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
|
||||||
|
|
19
lib/Kconfig
19
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.
|
Additional sources of multiprecision maths library from GnuPG.
|
||||||
It is used to implement RSA digital signature verification,
|
This code is unnecessary for RSA digital signature verification,
|
||||||
which is used by IMA/EVM digital signature extension.
|
but can be compiled if needed.
|
||||||
This code in unnecessary for RSA digital signature verification,
|
|
||||||
and can be compiled if needed.
|
|
||||||
|
|
||||||
config DIGSIG
|
config SIGNATURE
|
||||||
tristate "In-kernel signature checker"
|
tristate
|
||||||
depends on KEYS
|
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.
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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:
|
||||||
|
|
|
@ -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))
|
||||||
|
|
|
@ -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)
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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))
|
if (c <= ' ' || c >= 127)
|
||||||
continue; /* pattern is not \000 */
|
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;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue