diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2009-09-23 18:18:57 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2009-09-23 18:18:57 -0400 |
commit | c82ffab9a857f8286ed2b559624b7005a367b638 (patch) | |
tree | a5d0895a0b55c2db1bf36f517ca273e7e0abdf71 | |
parent | a724eada8c2a7b62463b73ccf73fd0bb6e928aeb (diff) | |
parent | 5224ee086321fec78970e2f2805892d2b34e8957 (diff) |
Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/jmorris/security-testing-2.6
* 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/jmorris/security-testing-2.6:
SELinux: do not destroy the avc_cache_nodep
KEYS: Have the garbage collector set its timer for live expired keys
tpm-fixup-pcrs-sysfs-file-update
creds_are_invalid() needs to be exported for use by modules:
include/linux/cred.h: fix build
Fix trivial BUILD_BUG_ON-induced conflicts in drivers/char/tpm/tpm.c
-rw-r--r-- | drivers/char/tpm/tpm.c | 5 | ||||
-rw-r--r-- | include/linux/cred.h | 18 | ||||
-rw-r--r-- | kernel/cred.c | 19 | ||||
-rw-r--r-- | security/keys/gc.c | 4 | ||||
-rw-r--r-- | security/selinux/avc.c | 19 |
5 files changed, 39 insertions, 26 deletions
diff --git a/drivers/char/tpm/tpm.c b/drivers/char/tpm/tpm.c index 32b957efa420..45d58002b06c 100644 --- a/drivers/char/tpm/tpm.c +++ b/drivers/char/tpm/tpm.c | |||
@@ -742,7 +742,7 @@ EXPORT_SYMBOL_GPL(tpm_pcr_read); | |||
742 | * the module usage count. | 742 | * the module usage count. |
743 | */ | 743 | */ |
744 | #define TPM_ORD_PCR_EXTEND cpu_to_be32(20) | 744 | #define TPM_ORD_PCR_EXTEND cpu_to_be32(20) |
745 | #define EXTEND_PCR_SIZE 34 | 745 | #define EXTEND_PCR_RESULT_SIZE 34 |
746 | static struct tpm_input_header pcrextend_header = { | 746 | static struct tpm_input_header pcrextend_header = { |
747 | .tag = TPM_TAG_RQU_COMMAND, | 747 | .tag = TPM_TAG_RQU_COMMAND, |
748 | .length = cpu_to_be32(34), | 748 | .length = cpu_to_be32(34), |
@@ -760,10 +760,9 @@ int tpm_pcr_extend(u32 chip_num, int pcr_idx, const u8 *hash) | |||
760 | return -ENODEV; | 760 | return -ENODEV; |
761 | 761 | ||
762 | cmd.header.in = pcrextend_header; | 762 | cmd.header.in = pcrextend_header; |
763 | BUG_ON(be32_to_cpu(cmd.header.in.length) > EXTEND_PCR_SIZE); | ||
764 | cmd.params.pcrextend_in.pcr_idx = cpu_to_be32(pcr_idx); | 763 | cmd.params.pcrextend_in.pcr_idx = cpu_to_be32(pcr_idx); |
765 | memcpy(cmd.params.pcrextend_in.hash, hash, TPM_DIGEST_SIZE); | 764 | memcpy(cmd.params.pcrextend_in.hash, hash, TPM_DIGEST_SIZE); |
766 | rc = transmit_cmd(chip, &cmd, cmd.header.in.length, | 765 | rc = transmit_cmd(chip, &cmd, EXTEND_PCR_RESULT_SIZE, |
767 | "attempting extend a PCR value"); | 766 | "attempting extend a PCR value"); |
768 | 767 | ||
769 | module_put(chip->dev->driver->owner); | 768 | module_put(chip->dev->driver->owner); |
diff --git a/include/linux/cred.h b/include/linux/cred.h index fb371601a3b4..4e3387a89cb9 100644 --- a/include/linux/cred.h +++ b/include/linux/cred.h | |||
@@ -176,23 +176,7 @@ extern void __invalid_creds(const struct cred *, const char *, unsigned); | |||
176 | extern void __validate_process_creds(struct task_struct *, | 176 | extern void __validate_process_creds(struct task_struct *, |
177 | const char *, unsigned); | 177 | const char *, unsigned); |
178 | 178 | ||
179 | static inline bool creds_are_invalid(const struct cred *cred) | 179 | extern bool creds_are_invalid(const struct cred *cred); |
180 | { | ||
181 | if (cred->magic != CRED_MAGIC) | ||
182 | return true; | ||
183 | if (atomic_read(&cred->usage) < atomic_read(&cred->subscribers)) | ||
184 | return true; | ||
185 | #ifdef CONFIG_SECURITY_SELINUX | ||
186 | if (selinux_is_enabled()) { | ||
187 | if ((unsigned long) cred->security < PAGE_SIZE) | ||
188 | return true; | ||
189 | if ((*(u32 *)cred->security & 0xffffff00) == | ||
190 | (POISON_FREE << 24 | POISON_FREE << 16 | POISON_FREE << 8)) | ||
191 | return true; | ||
192 | } | ||
193 | #endif | ||
194 | return false; | ||
195 | } | ||
196 | 180 | ||
197 | static inline void __validate_creds(const struct cred *cred, | 181 | static inline void __validate_creds(const struct cred *cred, |
198 | const char *file, unsigned line) | 182 | const char *file, unsigned line) |
diff --git a/kernel/cred.c b/kernel/cred.c index d7f7a01082eb..dd76cfe5f5b0 100644 --- a/kernel/cred.c +++ b/kernel/cred.c | |||
@@ -782,6 +782,25 @@ EXPORT_SYMBOL(set_create_files_as); | |||
782 | 782 | ||
783 | #ifdef CONFIG_DEBUG_CREDENTIALS | 783 | #ifdef CONFIG_DEBUG_CREDENTIALS |
784 | 784 | ||
785 | bool creds_are_invalid(const struct cred *cred) | ||
786 | { | ||
787 | if (cred->magic != CRED_MAGIC) | ||
788 | return true; | ||
789 | if (atomic_read(&cred->usage) < atomic_read(&cred->subscribers)) | ||
790 | return true; | ||
791 | #ifdef CONFIG_SECURITY_SELINUX | ||
792 | if (selinux_is_enabled()) { | ||
793 | if ((unsigned long) cred->security < PAGE_SIZE) | ||
794 | return true; | ||
795 | if ((*(u32 *)cred->security & 0xffffff00) == | ||
796 | (POISON_FREE << 24 | POISON_FREE << 16 | POISON_FREE << 8)) | ||
797 | return true; | ||
798 | } | ||
799 | #endif | ||
800 | return false; | ||
801 | } | ||
802 | EXPORT_SYMBOL(creds_are_invalid); | ||
803 | |||
785 | /* | 804 | /* |
786 | * dump invalid credentials | 805 | * dump invalid credentials |
787 | */ | 806 | */ |
diff --git a/security/keys/gc.c b/security/keys/gc.c index 485fc6233c38..4770be375ffe 100644 --- a/security/keys/gc.c +++ b/security/keys/gc.c | |||
@@ -169,9 +169,9 @@ static void key_garbage_collector(struct work_struct *work) | |||
169 | 169 | ||
170 | /* trawl through the keys looking for keyrings */ | 170 | /* trawl through the keys looking for keyrings */ |
171 | for (;;) { | 171 | for (;;) { |
172 | if (key->expiry > now && key->expiry < new_timer) { | 172 | if (key->expiry > limit && key->expiry < new_timer) { |
173 | kdebug("will expire %x in %ld", | 173 | kdebug("will expire %x in %ld", |
174 | key_serial(key), key->expiry - now); | 174 | key_serial(key), key->expiry - limit); |
175 | new_timer = key->expiry; | 175 | new_timer = key->expiry; |
176 | } | 176 | } |
177 | 177 | ||
diff --git a/security/selinux/avc.c b/security/selinux/avc.c index 1ed0f076aadc..b4b5da1c0a42 100644 --- a/security/selinux/avc.c +++ b/security/selinux/avc.c | |||
@@ -868,8 +868,19 @@ u32 avc_policy_seqno(void) | |||
868 | 868 | ||
869 | void avc_disable(void) | 869 | void avc_disable(void) |
870 | { | 870 | { |
871 | avc_flush(); | 871 | /* |
872 | synchronize_rcu(); | 872 | * If you are looking at this because you have realized that we are |
873 | if (avc_node_cachep) | 873 | * not destroying the avc_node_cachep it might be easy to fix, but |
874 | kmem_cache_destroy(avc_node_cachep); | 874 | * I don't know the memory barrier semantics well enough to know. It's |
875 | * possible that some other task dereferenced security_ops when | ||
876 | * it still pointed to selinux operations. If that is the case it's | ||
877 | * possible that it is about to use the avc and is about to need the | ||
878 | * avc_node_cachep. I know I could wrap the security.c security_ops call | ||
879 | * in an rcu_lock, but seriously, it's not worth it. Instead I just flush | ||
880 | * the cache and get that memory back. | ||
881 | */ | ||
882 | if (avc_node_cachep) { | ||
883 | avc_flush(); | ||
884 | /* kmem_cache_destroy(avc_node_cachep); */ | ||
885 | } | ||
875 | } | 886 | } |