diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2014-10-29 14:47:42 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2014-10-29 14:47:42 -0400 |
commit | 8c782932138e477fa352c5c7cfa1e3d2361e1351 (patch) | |
tree | b66efea31c0e55d41e7ac28d90ac1cb3c4c0d0c7 | |
parent | 19be9e8aa7820e4a8266d779476e057af7b798be (diff) | |
parent | 6c880ad51b829006c5387df88967954c0e874993 (diff) |
Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/jmorris/linux-security
Pull Integrity subsystem fix from James Morris:
"These changes fix a bug in xattr handling, where the evm and ima
inode_setxattr() functions do not check for empty xattrs being passed
from userspace (leading to user-triggerable null pointer
dereferences)"
* 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/jmorris/linux-security:
evm: check xattr value length and type in evm_inode_setxattr()
ima: check xattr value length and type in the ima_inode_setxattr()
-rw-r--r-- | security/integrity/evm/evm_main.c | 9 | ||||
-rw-r--r-- | security/integrity/ima/ima_appraise.c | 2 | ||||
-rw-r--r-- | security/integrity/integrity.h | 1 |
3 files changed, 9 insertions, 3 deletions
diff --git a/security/integrity/evm/evm_main.c b/security/integrity/evm/evm_main.c index 9685af330de5..c5ee1a7c5e8a 100644 --- a/security/integrity/evm/evm_main.c +++ b/security/integrity/evm/evm_main.c | |||
@@ -319,9 +319,12 @@ int evm_inode_setxattr(struct dentry *dentry, const char *xattr_name, | |||
319 | { | 319 | { |
320 | const struct evm_ima_xattr_data *xattr_data = xattr_value; | 320 | const struct evm_ima_xattr_data *xattr_data = xattr_value; |
321 | 321 | ||
322 | if ((strcmp(xattr_name, XATTR_NAME_EVM) == 0) | 322 | if (strcmp(xattr_name, XATTR_NAME_EVM) == 0) { |
323 | && (xattr_data->type == EVM_XATTR_HMAC)) | 323 | if (!xattr_value_len) |
324 | return -EPERM; | 324 | return -EINVAL; |
325 | if (xattr_data->type != EVM_IMA_XATTR_DIGSIG) | ||
326 | return -EPERM; | ||
327 | } | ||
325 | return evm_protect_xattr(dentry, xattr_name, xattr_value, | 328 | return evm_protect_xattr(dentry, xattr_name, xattr_value, |
326 | xattr_value_len); | 329 | xattr_value_len); |
327 | } | 330 | } |
diff --git a/security/integrity/ima/ima_appraise.c b/security/integrity/ima/ima_appraise.c index 922685483bd3..7c8f41e618b6 100644 --- a/security/integrity/ima/ima_appraise.c +++ b/security/integrity/ima/ima_appraise.c | |||
@@ -378,6 +378,8 @@ int ima_inode_setxattr(struct dentry *dentry, const char *xattr_name, | |||
378 | result = ima_protect_xattr(dentry, xattr_name, xattr_value, | 378 | result = ima_protect_xattr(dentry, xattr_name, xattr_value, |
379 | xattr_value_len); | 379 | xattr_value_len); |
380 | if (result == 1) { | 380 | if (result == 1) { |
381 | if (!xattr_value_len || (xvalue->type >= IMA_XATTR_LAST)) | ||
382 | return -EINVAL; | ||
381 | ima_reset_appraise_flags(dentry->d_inode, | 383 | ima_reset_appraise_flags(dentry->d_inode, |
382 | (xvalue->type == EVM_IMA_XATTR_DIGSIG) ? 1 : 0); | 384 | (xvalue->type == EVM_IMA_XATTR_DIGSIG) ? 1 : 0); |
383 | result = 0; | 385 | result = 0; |
diff --git a/security/integrity/integrity.h b/security/integrity/integrity.h index c0379d13dbe1..9d1c2ebfe12a 100644 --- a/security/integrity/integrity.h +++ b/security/integrity/integrity.h | |||
@@ -61,6 +61,7 @@ enum evm_ima_xattr_type { | |||
61 | EVM_XATTR_HMAC, | 61 | EVM_XATTR_HMAC, |
62 | EVM_IMA_XATTR_DIGSIG, | 62 | EVM_IMA_XATTR_DIGSIG, |
63 | IMA_XATTR_DIGEST_NG, | 63 | IMA_XATTR_DIGEST_NG, |
64 | IMA_XATTR_LAST | ||
64 | }; | 65 | }; |
65 | 66 | ||
66 | struct evm_ima_xattr_data { | 67 | struct evm_ima_xattr_data { |