From: Roberto Sassu <roberto.sassu@huawei.com> To: <zohar@linux.ibm.com>, <dmitry.kasatkin@huawei.com>, <mjg59@google.com> Cc: <linux-integrity@vger.kernel.org>, <linux-security-module@vger.kernel.org>, <linux-fsdevel@vger.kernel.org>, <linux-doc@vger.kernel.org>, <linux-kernel@vger.kernel.org>, <silviu.vlasceanu@huawei.com>, Roberto Sassu <roberto.sassu@huawei.com> Subject: [PATCH v4 01/14] ima: read hash algorithm from security.ima even if appraisal is not enabled Date: Fri, 14 Jun 2019 19:55:00 +0200 Message-ID: <20190614175513.27097-2-roberto.sassu@huawei.com> (raw) In-Reply-To: <20190614175513.27097-1-roberto.sassu@huawei.com> IMA reads the hash algorithm from security.ima, if exists, so that a signature can be verified even if the algorithm used for the signature differs from IMA algorithm. This patch moves ima_read_xattr() and ima_get_hash_algo() to ima_main.c, to retrieve the algorithm even if appraisal is not enabled. Knowing the algorithm in advance would be useful also for measurement. The new Digest Lists extension does not add a new entry to the measurement list if the actual file digest is found in a loaded list. It might be possible that the algorithm used for the digest lists differs from IMA algorithm. This patch also changes the requirement that security.ima must contain a signature, if the type is EVM_IMA_XATTR_DIGSIG. A signature with length zero is accepted. Signed-off-by: Roberto Sassu <roberto.sassu@huawei.com> --- security/integrity/ima/ima.h | 16 -------- security/integrity/ima/ima_appraise.c | 55 ++------------------------- security/integrity/ima/ima_main.c | 51 +++++++++++++++++++++++++ 3 files changed, 55 insertions(+), 67 deletions(-) diff --git a/security/integrity/ima/ima.h b/security/integrity/ima/ima.h index ee509c68fe14..b4a0d2a02ff2 100644 --- a/security/integrity/ima/ima.h +++ b/security/integrity/ima/ima.h @@ -248,10 +248,6 @@ int ima_must_appraise(struct inode *inode, int mask, enum ima_hooks func); void ima_update_xattr(struct integrity_iint_cache *iint, struct file *file); enum integrity_status ima_get_cache_status(struct integrity_iint_cache *iint, enum ima_hooks func); -enum hash_algo ima_get_hash_algo(struct evm_ima_xattr_data *xattr_value, - int xattr_len); -int ima_read_xattr(struct dentry *dentry, - struct evm_ima_xattr_data **xattr_value); #else static inline int ima_appraise_measurement(enum ima_hooks func, @@ -282,18 +278,6 @@ static inline enum integrity_status ima_get_cache_status(struct integrity_iint_c return INTEGRITY_UNKNOWN; } -static inline enum hash_algo -ima_get_hash_algo(struct evm_ima_xattr_data *xattr_value, int xattr_len) -{ - return ima_hash_algo; -} - -static inline int ima_read_xattr(struct dentry *dentry, - struct evm_ima_xattr_data **xattr_value) -{ - return 0; -} - #endif /* CONFIG_IMA_APPRAISE */ /* LSM based policy rules require audit */ diff --git a/security/integrity/ima/ima_appraise.c b/security/integrity/ima/ima_appraise.c index 9b3b172f9748..2566dbfd2464 100644 --- a/security/integrity/ima/ima_appraise.c +++ b/security/integrity/ima/ima_appraise.c @@ -151,57 +151,6 @@ static void ima_cache_flags(struct integrity_iint_cache *iint, } } -enum hash_algo ima_get_hash_algo(struct evm_ima_xattr_data *xattr_value, - int xattr_len) -{ - struct signature_v2_hdr *sig; - enum hash_algo ret; - - if (!xattr_value || xattr_len < 2) - /* return default hash algo */ - return ima_hash_algo; - - switch (xattr_value->type) { - case EVM_IMA_XATTR_DIGSIG: - sig = (typeof(sig))xattr_value; - if (sig->version != 2 || xattr_len <= sizeof(*sig)) - return ima_hash_algo; - return sig->hash_algo; - break; - case IMA_XATTR_DIGEST_NG: - ret = xattr_value->digest[0]; - if (ret < HASH_ALGO__LAST) - return ret; - break; - case IMA_XATTR_DIGEST: - /* this is for backward compatibility */ - if (xattr_len == 21) { - unsigned int zero = 0; - if (!memcmp(&xattr_value->digest[16], &zero, 4)) - return HASH_ALGO_MD5; - else - return HASH_ALGO_SHA1; - } else if (xattr_len == 17) - return HASH_ALGO_MD5; - break; - } - - /* return default hash algo */ - return ima_hash_algo; -} - -int ima_read_xattr(struct dentry *dentry, - struct evm_ima_xattr_data **xattr_value) -{ - ssize_t ret; - - ret = vfs_getxattr_alloc(dentry, XATTR_NAME_IMA, (char **)xattr_value, - 0, GFP_NOFS); - if (ret == -EOPNOTSUPP) - ret = 0; - return ret; -} - /* * ima_appraise_measurement - appraise file measurement * @@ -226,6 +175,10 @@ int ima_appraise_measurement(enum ima_hooks func, if (!(inode->i_opflags & IOP_XATTR)) return INTEGRITY_UNKNOWN; + if (xattr_len == sizeof(struct signature_v2_hdr) && + xattr_value->type == EVM_IMA_XATTR_DIGSIG) + rc = -ENODATA; + if (rc <= 0) { if (rc && rc != -ENODATA) goto out; diff --git a/security/integrity/ima/ima_main.c b/security/integrity/ima/ima_main.c index 0c49cf6470a4..dc53ed8b0dd0 100644 --- a/security/integrity/ima/ima_main.c +++ b/security/integrity/ima/ima_main.c @@ -143,6 +143,57 @@ static void ima_rdwr_violation_check(struct file *file, "invalid_pcr", "open_writers"); } +static enum hash_algo ima_get_hash_algo(struct evm_ima_xattr_data *xattr_value, + int xattr_len) +{ + struct signature_v2_hdr *sig; + enum hash_algo ret; + + if (!xattr_value || xattr_len < 2) + /* return default hash algo */ + return ima_hash_algo; + + switch (xattr_value->type) { + case EVM_IMA_XATTR_DIGSIG: + sig = (typeof(sig))xattr_value; + if (sig->version != 2 || xattr_len < sizeof(*sig)) + return ima_hash_algo; + return sig->hash_algo; + case IMA_XATTR_DIGEST_NG: + ret = xattr_value->digest[0]; + if (ret < HASH_ALGO__LAST) + return ret; + break; + case IMA_XATTR_DIGEST: + /* this is for backward compatibility */ + if (xattr_len == 21) { + unsigned int zero = 0; + + if (!memcmp(&xattr_value->digest[16], &zero, 4)) + return HASH_ALGO_MD5; + else + return HASH_ALGO_SHA1; + } else if (xattr_len == 17) + return HASH_ALGO_MD5; + break; + } + + /* return default hash algo */ + return ima_hash_algo; +} + +static int ima_read_xattr(struct dentry *dentry, + struct evm_ima_xattr_data **xattr_value) +{ + ssize_t ret; + + ret = vfs_getxattr_alloc(dentry, XATTR_NAME_IMA, (char **)xattr_value, + 0, GFP_NOFS); + if (ret == -EOPNOTSUPP) + ret = 0; + return ret; +} + static void ima_check_last_writer(struct integrity_iint_cache *iint, struct inode *inode, struct file *file) { -- 2.17.1
next prev parent reply index Thread overview: 19+ messages / expand[flat|nested] mbox.gz Atom feed top 2019-06-14 17:54 [PATCH v4 00/14] ima: introduce IMA Digest Lists extension Roberto Sassu 2019-06-14 17:55 ` Roberto Sassu [this message] 2019-06-14 17:55 ` [PATCH v4 02/14] ima: generalize ima_read_policy() Roberto Sassu 2019-06-14 17:55 ` [PATCH v4 03/14] ima: generalize ima_write_policy() and raise uploaded data size limit Roberto Sassu 2019-06-14 17:55 ` [PATCH v4 04/14] ima: generalize policy file operations Roberto Sassu 2019-06-14 17:55 ` [PATCH v4 05/14] ima: use ima_show_htable_value to show violations and hash table data Roberto Sassu 2019-06-14 17:55 ` [PATCH v4 06/14] ima: add parser of compact digest list Roberto Sassu 2019-06-14 17:55 ` [PATCH v4 07/14] ima: restrict upload of converted digest lists Roberto Sassu 2019-06-14 17:55 ` [PATCH v4 08/14] ima: prevent usage of digest lists that are not measured/appraised Roberto Sassu 2019-06-14 17:55 ` [PATCH v4 09/14] ima: introduce new securityfs files Roberto Sassu 2019-06-14 17:55 ` [PATCH v4 10/14] ima: load parser digests and execute the parser at boot time Roberto Sassu 2019-06-14 17:55 ` [PATCH v4 11/14] ima: add support for measurement with digest lists Roberto Sassu 2019-06-14 17:55 ` [PATCH v4 12/14] ima: add support for appraisal " Roberto Sassu 2019-06-14 17:55 ` [PATCH v4 13/14] ima: introduce new policies initrd and appraise_initrd Roberto Sassu 2019-06-14 17:55 ` [PATCH v4 14/14] ima: add Documentation/security/IMA-digest-lists.txt Roberto Sassu 2019-06-17 6:56 ` [PATCH v4 00/14] ima: introduce IMA Digest Lists extension Roberto Sassu 2019-06-25 12:57 ` Roberto Sassu 2019-06-25 17:35 ` Mimi Zohar 2019-06-26 11:38 ` Roberto Sassu
Reply instructions: You may reply publicly to this message via plain-text email using any one of the following methods: * Save the following mbox file, import it into your mail client, and reply-to-all from there: mbox Avoid top-posting and favor interleaved quoting: https://en.wikipedia.org/wiki/Posting_style#Interleaved_style * Reply using the --to, --cc, and --in-reply-to switches of git-send-email(1): git send-email \ --in-reply-to=20190614175513.27097-2-roberto.sassu@huawei.com \ --to=roberto.sassu@huawei.com \ --cc=dmitry.kasatkin@huawei.com \ --cc=linux-doc@vger.kernel.org \ --cc=linux-fsdevel@vger.kernel.org \ --cc=linux-integrity@vger.kernel.org \ --cc=linux-kernel@vger.kernel.org \ --cc=linux-security-module@vger.kernel.org \ --cc=mjg59@google.com \ --cc=silviu.vlasceanu@huawei.com \ --cc=zohar@linux.ibm.com \ /path/to/YOUR_REPLY https://kernel.org/pub/software/scm/git/docs/git-send-email.html * If your mail client supports setting the In-Reply-To header via mailto: links, try the mailto: link
Linux-Integrity Archive on lore.kernel.org Archives are clonable: git clone --mirror https://lore.kernel.org/linux-integrity/0 linux-integrity/git/0.git # If you have public-inbox 1.1+ installed, you may # initialize and index your mirror using the following commands: public-inbox-init -V2 linux-integrity linux-integrity/ https://lore.kernel.org/linux-integrity \ linux-integrity@vger.kernel.org public-inbox-index linux-integrity Example config snippet for mirrors Newsgroup available over NNTP: nntp://nntp.lore.kernel.org/org.kernel.vger.linux-integrity AGPL code for this site: git clone https://public-inbox.org/public-inbox.git