integrity: Avoid -Wflex-array-member-not-at-end warnings
Subsystems (4)
PATCH v4 1/1 integrity: Avoid -Wflex-array-member-not-at-end warnings
-Wflex-array-member-not-at-end is coming in GCC-14, and we are getting ready to enable it globally.
There is currently an object (hdr) in struct ima_max_digest_data that contains a flexible structure (struct ima_digest_data):
struct ima_max_digest_data {
struct ima_digest_data hdr;
u8 digest[HASH_MAX_DIGESTSIZE]; } __packed;
So, in order to avoid ending up with a flexible-array member in the middle of a struct, we use the __struct_group() helper to separate the flexible array from the rest of the members in the flexible structure:
struct ima_digest_data {
__struct_group(ima_digest_data_hdr, hdr, __packed,
... the rest of the members
);
u8 digest[];
} __packed;
And similarly for struct evm_ima_xattr_data.
With the change described above, we can now declare an object of the type of the tagged struct ima_digest_data_hdr, without embedding the flexible array in the middle of another struct:
struct ima_max_digest_data {
struct ima_digest_data_hdr hdr;
u8 digest[HASH_MAX_DIGESTSIZE]; } __packed;
And similarly for struct evm_digest and struct evm_xattr.
We also use container_of() whenever we need to retrieve a pointer to the flexible structure.
So, with these changes, fix the following warnings:
security/integrity/evm/evm.h:64:32: warning: structure containing a flexible array member is not at the end of another structure [-Wflex-array-member-not-at-end] security/integrity/evm/../integrity.h:40:35: warning: structure containing a flexible array member is not at the end of another structure [-Wflex-array-member-not-at-end] security/integrity/evm/../integrity.h:68:32: warning: structure containing a flexible array member is not at the end of another structure [-Wflex-array-member-not-at-end] security/integrity/ima/../integrity.h:40:35: warning: structure containing a flexible array member is not at the end of another structure [-Wflex-array-member-not-at-end] security/integrity/ima/../integrity.h:68:32: warning: structure containing a flexible array member is not at the end of another structure [-Wflex-array-member-not-at-end] security/integrity/integrity.h:40:35: warning: structure containing a flexible array member is not at the end of another structure [-Wflex-array-member-not-at-end] security/integrity/integrity.h:68:32: warning: structure containing a flexible array member is not at the end of another structure [-Wflex-array-member-not-at-end] security/integrity/platform_certs/../integrity.h:40:35: warning: structure containing a flexible array member is not at the end of another structure [-Wflex-array-member-not-at-end] security/integrity/platform_certs/../integrity.h:68:32: warning: structure containing a flexible array member is not at the end of another structure [-Wflex-array-member-not-at-end]
---
Changes in v4:
- Update changelog text. (Mimi Zohar)
- Include changes for struct evm_ima_xattr_data and struct evm_xattr.
- Add a couple of code comments.
Changes in v3:
- struct ima_digest_data is a packed structure. So, to keep things consistent, use the attribute __packed on the tagged struct ima_digest_data_hdr. For this, we use __struct_group() instead of struct_group_tagged(). Update the changelog text, accordingly.
- Link: https://lore.kernel.org/linux-hardening/ZfuzWku+ip4fsZrb@neat/
Changes in v2:
- Include changes for struct evm_digest (Mimi Zohar)
- Link: https://lore.kernel.org/linux-hardening/ZfuvoIj+AJHjCdTs@neat/
v1:
- Link: https://lore.kernel.org/linux-hardening/ZeYKWrXvACBBrAP8@neat/
security/integrity/evm/evm.h | 2 +- security/integrity/ima/ima_api.c | 6 ++++-- security/integrity/ima/ima_appraise.c | 4 +++- security/integrity/ima/ima_init.c | 6 ++++-- security/integrity/ima/ima_main.c | 6 ++++-- security/integrity/ima/ima_template_lib.c | 10 ++++++---- security/integrity/integrity.h | 12 +++++++++--- 7 files changed, 31 insertions(+), 15 deletions(-)
security/integrity/evm/evm.h +1 -1
@@ -61,7 +61,7 @@ extern int evm_hmac_attrs;extern struct list_head evm_config_xattrnames;struct evm_digest { -struct ima_digest_data hdr; +struct ima_digest_data_hdr hdr;char digest[IMA_MAX_DIGEST_SIZE ]; } __packed;
security/integrity/ima/ima_api.c +4 -2
@@ -247,6 +247,8 @@ int ima_collect_measurement(struct ima_iint_cache *iint, struct file *file,struct inode *real_inode =d_real_inode (file_dentry (file));const char *filename = file->f_path.dentry->d_name.name;struct ima_max_digest_data hash; +struct ima_digest_data *hash_hdr =container_of (&hash.hdr, + struct ima_digest_data, hdr);struct kstat stat;int result =0 ;int length;
@@ -286,9 +288,9 @@ int ima_collect_measurement(struct ima_iint_cache *iint, struct file *file, result = -ENODATA ; } }else if (buf) { - result =ima_calc_buffer_hash (buf, size, &hash.hdr); + result =ima_calc_buffer_hash (buf, size, hash_hdr); }else { - result =ima_calc_file_hash (file, &hash.hdr); + result =ima_calc_file_hash (file, hash_hdr); }if (result && result != -EBADF && result != -EINVAL )
security/integrity/ima/ima_appraise.c +3 -1
@@ -378,7 +378,9 @@ static int xattr_verify(enum ima_hooks func, struct ima_iint_cache *iint, } rc =calc_file_id_hash (IMA_VERITY_DIGSIG , iint->ima_hash->algo, - iint->ima_hash->digest, &hash.hdr); + iint->ima_hash->digest, +container_of (&hash.hdr, + struct ima_digest_data, hdr));if (rc) { *cause ="sigv3-hashing-error" ; *status =INTEGRITY_FAIL ;
security/integrity/ima/ima_init.c +4 -2
@@ -48,12 +48,14 @@ static int __init ima_add_boot_aggregate(void)struct ima_event_data event_data = { .iint = iint, .filename = boot_aggregate_name };struct ima_max_digest_data hash; +struct ima_digest_data *hash_hdr =container_of (&hash.hdr, + struct ima_digest_data, hdr);int result = -ENOMEM ;int violation =0 ;memset (iint,0 ,sizeof (*iint));memset (&hash,0 ,sizeof (hash)); - iint->ima_hash = &hash.hdr; + iint->ima_hash = hash_hdr; iint->ima_hash->algo = ima_hash_algo; iint->ima_hash->length = hash_digest_size[ima_hash_algo];
@@ -70,7 +72,7 @@ static int __init ima_add_boot_aggregate(void)* is not found. */ if (ima_tpm_chip) { - result =ima_calc_boot_aggregate (&hash.hdr); + result =ima_calc_boot_aggregate (hash_hdr);if (result <0 ) { audit_cause ="hashing_error" ; goto err_out;
security/integrity/ima/ima_main.c +4 -2
@@ -941,6 +941,8 @@ int process_buffer_measurement(struct mnt_idmap *idmap, .buf_len = size};struct ima_template_desc *template;struct ima_max_digest_data hash; +struct ima_digest_data *hash_hdr =container_of (&hash.hdr, + struct ima_digest_data, hdr);char digest_hash[IMA_MAX_DIGEST_SIZE ];int digest_hash_len = hash_digest_size[ima_hash_algo];int violation =0 ;
@@ -979,7 +981,7 @@ int process_buffer_measurement(struct mnt_idmap *idmap,if (!pcr) pcr =CONFIG_IMA_MEASURE_PCR_IDX ; - iint.ima_hash = &hash.hdr; + iint.ima_hash = hash_hdr; iint.ima_hash->algo = ima_hash_algo; iint.ima_hash->length = hash_digest_size[ima_hash_algo];
@@ -990,7 +992,7 @@ int process_buffer_measurement(struct mnt_idmap *idmap, }if (buf_hash) { -memcpy (digest_hash, hash.hdr.digest, digest_hash_len); +memcpy (digest_hash, hash_hdr->digest, digest_hash_len); ret =ima_calc_buffer_hash (digest_hash, digest_hash_len, iint.ima_hash);
security/integrity/ima/ima_template_lib.c +6 -4
@@ -339,6 +339,8 @@ int ima_eventdigest_init(struct ima_event_data *event_data, struct ima_field_data *field_data) {struct ima_max_digest_data hash; +struct ima_digest_data *hash_hdr =container_of (&hash.hdr, + struct ima_digest_data, hdr);u8 *cur_digest =NULL ;u32 cur_digestsize =0 ;struct inode *inode;
@@ -358,7 +360,7 @@ int ima_eventdigest_init(struct ima_event_data *event_data,if ((const char *)event_data->filename == boot_aggregate_name) {if (ima_tpm_chip) { hash.hdr.algo =HASH_ALGO_SHA1 ; - result =ima_calc_boot_aggregate (&hash.hdr); + result =ima_calc_boot_aggregate (hash_hdr);/* algo can change depending on available PCR banks */ if (!result && hash.hdr.algo !=HASH_ALGO_SHA1 )
@@ -368,7 +370,7 @@ int ima_eventdigest_init(struct ima_event_data *event_data,memset (&hash,0 ,sizeof (hash)); } - cur_digest = hash.hdr.digest; + cur_digest = hash_hdr->digest; cur_digestsize = hash_digest_size[HASH_ALGO_SHA1 ]; goto out; }
@@ -379,14 +381,14 @@ int ima_eventdigest_init(struct ima_event_data *event_data, inode =file_inode (event_data->file); hash.hdr.algo =ima_template_hash_algo_allowed (ima_hash_algo) ? ima_hash_algo :HASH_ALGO_SHA1 ; - result =ima_calc_file_hash (event_data->file, &hash.hdr); + result =ima_calc_file_hash (event_data->file, hash_hdr);if (result) {integrity_audit_msg (AUDIT_INTEGRITY_DATA , inode, event_data->filename,"collect_data" ,"failed" , result,0 );return result; } - cur_digest = hash.hdr.digest; + cur_digest = hash_hdr->digest; cur_digestsize = hash.hdr.length; out: return ima_eventdigest_init_common(cur_digest, cur_digestsize,
security/integrity/integrity.h +9 -3
@@ -31,19 +31,24 @@ enum evm_ima_xattr_type { };struct evm_ima_xattr_data { -u8 type; +/* New members must be added within the __struct_group() macro below. */ + __struct_group(evm_ima_xattr_data_hdr, hdr, __packed, + u8 type; + );u8 data[]; } __packed;/* Only used in the EVM HMAC code. */ struct evm_xattr { -struct evm_ima_xattr_data data; +struct evm_ima_xattr_data_hdr data;u8 digest[SHA1_DIGEST_SIZE ]; } __packed;#define IMA_MAX_DIGEST_SIZE HASH_MAX_DIGESTSIZEstruct ima_digest_data { +/* New members must be added within the __struct_group() macro below. */ + __struct_group(ima_digest_data_hdr, hdr, __packed, u8 algo;u8 length;union {
@@ -57,6 +62,7 @@ struct ima_digest_data { } ng;u8 data[2 ]; } xattr; + );u8 digest[]; } __packed;
@@ -65,7 +71,7 @@ struct ima_digest_data {* with the maximum hash size, define ima_max_digest_data struct. */ struct ima_max_digest_data { -struct ima_digest_data hdr; +struct ima_digest_data_hdr hdr;u8 digest[HASH_MAX_DIGESTSIZE ]; } __packed;
Signature · 1 line
2.34.1