Message ID | 20170725154423.24845-9-roberto.sassu@huawei.com (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
Hi Roberto, [auto build test WARNING on integrity/next] [also build test WARNING on v4.13-rc2 next-20170726] [if your patch is applied to the wrong git tree, please drop us a note to help improve the system] url: https://github.com/0day-ci/linux/commits/Roberto-Sassu/ima-measure-digest-lists-instead-of-individual-files/20170727-123131 base: https://git.kernel.org/pub/scm/linux/kernel/git/zohar/linux-integrity.git next config: xtensa-allyesconfig (attached as .config) compiler: xtensa-linux-gcc (GCC) 4.9.0 reproduce: wget https://raw.githubusercontent.com/01org/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross chmod +x ~/bin/make.cross # save the attached .config to linux build tree make.cross ARCH=xtensa All warnings (new ones prefixed by >>): security/integrity/ima/ima_digest_list.c: In function 'ima_parse_rpm': >> security/integrity/ima/ima_digest_list.c:147:4: warning: ignoring return value of 'hex2bin', declared with attribute warn_unused_result [-Wunused-result] hex2bin(digest, datap, digest_len); ^ vim +/hex2bin +147 security/integrity/ima/ima_digest_list.c 98 99 static int ima_parse_rpm(loff_t size, void *buf) 100 { 101 void *bufp = buf, *bufendp = buf + size; 102 struct rpm_hdr *hdr = bufp; 103 u32 tags = be32_to_cpu(hdr->tags); 104 struct rpm_entryinfo *entry; 105 void *datap = bufp + sizeof(*hdr) + tags * sizeof(struct rpm_entryinfo); 106 int digest_len = hash_digest_size[ima_hash_algo]; 107 u8 digest[digest_len]; 108 int ret, i, j; 109 110 const unsigned char rpm_header_magic[8] = { 111 0x8e, 0xad, 0xe8, 0x01, 0x00, 0x00, 0x00, 0x00 112 }; 113 114 if (size < sizeof(*hdr)) { 115 pr_err("Missing RPM header\n"); 116 return -EINVAL; 117 } 118 119 if (memcmp(bufp, rpm_header_magic, sizeof(rpm_header_magic))) { 120 pr_err("Invalid RPM header\n"); 121 return -EINVAL; 122 } 123 124 bufp += sizeof(*hdr); 125 126 for (i = 0; i < tags && (bufp + sizeof(*entry)) <= bufendp; 127 i++, bufp += sizeof(*entry)) { 128 entry = bufp; 129 130 if (be32_to_cpu(entry->tag) != RPMTAG_FILEDIGESTS) 131 continue; 132 133 datap += be32_to_cpu(entry->offset); 134 135 for (j = 0; j < be32_to_cpu(entry->count) && 136 datap < bufendp; j++) { 137 if (strlen(datap) == 0) { 138 datap++; 139 continue; 140 } 141 142 if (datap + digest_len * 2 + 1 > bufendp) { 143 pr_err("RPM header read at invalid offset\n"); 144 return -EINVAL; 145 } 146 > 147 hex2bin(digest, datap, digest_len); 148 149 ret = ima_add_digest_data_entry(digest); 150 if (ret < 0 && ret != -EEXIST) 151 return ret; 152 153 datap += digest_len * 2 + 1; 154 } 155 156 break; 157 } 158 159 return 0; 160 } 161 --- 0-DAY kernel test infrastructure Open Source Technology Center https://lists.01.org/pipermail/kbuild-all Intel Corporation
diff --git a/security/integrity/ima/ima_digest_list.c b/security/integrity/ima/ima_digest_list.c index c1ef79a..11ee77e 100644 --- a/security/integrity/ima/ima_digest_list.c +++ b/security/integrity/ima/ima_digest_list.c @@ -19,11 +19,13 @@ #include "ima.h" #include "ima_template_lib.h" +#define RPMTAG_FILEDIGESTS 1035 + enum digest_metadata_fields {DATA_ALGO, DATA_DIGEST, DATA_SIGNATURE, DATA_FILE_PATH, DATA_REF_ID, DATA_TYPE, DATA__LAST}; -enum digest_data_types {DATA_TYPE_COMPACT_LIST}; +enum digest_data_types {DATA_TYPE_COMPACT_LIST, DATA_TYPE_RPM}; enum compact_list_entry_ids {COMPACT_LIST_ID_DIGEST}; @@ -33,6 +35,20 @@ struct compact_list_hdr { u32 datalen; } __packed; +struct rpm_hdr { + u32 magic; + u32 reserved; + u32 tags; + u32 datasize; +} __packed; + +struct rpm_entryinfo { + int32_t tag; + u32 type; + int32_t offset; + u32 count; +} __packed; + static int ima_parse_compact_list(loff_t size, void *buf) { void *bufp = buf, *bufendp = buf + size; @@ -80,6 +96,69 @@ static int ima_parse_compact_list(loff_t size, void *buf) return 0; } +static int ima_parse_rpm(loff_t size, void *buf) +{ + void *bufp = buf, *bufendp = buf + size; + struct rpm_hdr *hdr = bufp; + u32 tags = be32_to_cpu(hdr->tags); + struct rpm_entryinfo *entry; + void *datap = bufp + sizeof(*hdr) + tags * sizeof(struct rpm_entryinfo); + int digest_len = hash_digest_size[ima_hash_algo]; + u8 digest[digest_len]; + int ret, i, j; + + const unsigned char rpm_header_magic[8] = { + 0x8e, 0xad, 0xe8, 0x01, 0x00, 0x00, 0x00, 0x00 + }; + + if (size < sizeof(*hdr)) { + pr_err("Missing RPM header\n"); + return -EINVAL; + } + + if (memcmp(bufp, rpm_header_magic, sizeof(rpm_header_magic))) { + pr_err("Invalid RPM header\n"); + return -EINVAL; + } + + bufp += sizeof(*hdr); + + for (i = 0; i < tags && (bufp + sizeof(*entry)) <= bufendp; + i++, bufp += sizeof(*entry)) { + entry = bufp; + + if (be32_to_cpu(entry->tag) != RPMTAG_FILEDIGESTS) + continue; + + datap += be32_to_cpu(entry->offset); + + for (j = 0; j < be32_to_cpu(entry->count) && + datap < bufendp; j++) { + if (strlen(datap) == 0) { + datap++; + continue; + } + + if (datap + digest_len * 2 + 1 > bufendp) { + pr_err("RPM header read at invalid offset\n"); + return -EINVAL; + } + + hex2bin(digest, datap, digest_len); + + ret = ima_add_digest_data_entry(digest); + if (ret < 0 && ret != -EEXIST) + return ret; + + datap += digest_len * 2 + 1; + } + + break; + } + + return 0; +} + static int ima_parse_digest_list_data(struct ima_field_data *data) { void *digest_list; @@ -107,6 +186,9 @@ static int ima_parse_digest_list_data(struct ima_field_data *data) case DATA_TYPE_COMPACT_LIST: ret = ima_parse_compact_list(digest_list_size, digest_list); break; + case DATA_TYPE_RPM: + ret = ima_parse_rpm(digest_list_size, digest_list); + break; default: pr_err("Parser for data type %d not implemented\n", data_type); ret = -EINVAL;
This patch introduces a parser for RPM packages. It extracts the digests from the RPMTAG_FILEDIGESTS header section and converts them to binary data before adding them to the hash table. The advantage of this data type is that verifiers can determine who produced that data, as headers are signed by Linux distributions vendors. RPM headers signatures can be provided as digest list metadata. Signed-off-by: Roberto Sassu <roberto.sassu@huawei.com> --- security/integrity/ima/ima_digest_list.c | 84 +++++++++++++++++++++++++++++++- 1 file changed, 83 insertions(+), 1 deletion(-)