diff --git a/Documentation/security/IMA-templates.rst b/Documentation/security/IMA-templates.rst index 9f3e86ab028a45cfd0faa81ec4299d483d288070..bf8ce4cf5878ac7585b0645a2d23a834dcc77650 100644 --- a/Documentation/security/IMA-templates.rst +++ b/Documentation/security/IMA-templates.rst @@ -75,6 +75,8 @@ descriptors by adding their identifier to the format string - 'modsig' the appended file signature; - 'buf': the buffer data that was used to generate the hash without size limitations; - 'evmsig': the EVM portable signature; + - 'iuid': the inode UID; + - 'igid': the inode GID; Below, there is the list of defined template descriptors: diff --git a/security/integrity/ima/ima_template.c b/security/integrity/ima/ima_template.c index dffaed44cc37f8b106817dacb6a20e6708a02e8a..fd99989afd2bc89bf49dd2e73da04f818a8c8c1a 100644 --- a/security/integrity/ima/ima_template.c +++ b/security/integrity/ima/ima_template.c @@ -50,6 +50,10 @@ static const struct ima_template_field supported_fields[] = { {.field_id = "evmsig", .field_init = ima_eventevmsig_init, .field_show = ima_show_template_sig}, #endif + {.field_id = "iuid", .field_init = ima_eventinodeuid_init, + .field_show = ima_show_template_uint}, + {.field_id = "igid", .field_init = ima_eventinodegid_init, + .field_show = ima_show_template_uint}, }; /* diff --git a/security/integrity/ima/ima_template_lib.c b/security/integrity/ima/ima_template_lib.c index 7308ee5873141665e254d97af8798695407593f1..cd6ec561cf8f2242e585bb1ef7dd46e95a4d8640 100644 --- a/security/integrity/ima/ima_template_lib.c +++ b/security/integrity/ima/ima_template_lib.c @@ -26,7 +26,8 @@ enum data_formats { DATA_FMT_DIGEST = 0, DATA_FMT_DIGEST_WITH_ALGO, DATA_FMT_STRING, - DATA_FMT_HEX + DATA_FMT_HEX, + DATA_FMT_UINT }; static int ima_write_template_field_data(const void *data, const u32 datalen, @@ -90,6 +91,35 @@ static void ima_show_template_data_ascii(struct seq_file *m, case DATA_FMT_STRING: seq_printf(m, "%s", buf_ptr); break; + case DATA_FMT_UINT: + switch (field_data->len) { + case sizeof(u8): + seq_printf(m, "%u", *(u8 *)buf_ptr); + break; + case sizeof(u16): + if (ima_canonical_fmt) + seq_printf(m, "%u", + le16_to_cpu(*(u16 *)buf_ptr)); + else + seq_printf(m, "%u", *(u16 *)buf_ptr); + break; + case sizeof(u32): + if (ima_canonical_fmt) + seq_printf(m, "%u", + le32_to_cpu(*(u32 *)buf_ptr)); + else + seq_printf(m, "%u", *(u32 *)buf_ptr); + break; + case sizeof(u64): + if (ima_canonical_fmt) + seq_printf(m, "%llu", + le64_to_cpu(*(u64 *)buf_ptr)); + else + seq_printf(m, "%llu", *(u64 *)buf_ptr); + break; + default: + break; + } default: break; } @@ -165,6 +195,12 @@ void ima_show_template_buf(struct seq_file *m, enum ima_show_type show, ima_show_template_field_data(m, show, DATA_FMT_HEX, field_data); } +void ima_show_template_uint(struct seq_file *m, enum ima_show_type show, + struct ima_field_data *field_data) +{ + ima_show_template_field_data(m, show, DATA_FMT_UINT, field_data); +} + /** * ima_parse_buf() - Parses lengths and data from an input buffer * @bufstartp: Buffer start address. @@ -522,3 +558,48 @@ int ima_eventevmsig_init(struct ima_event_data *event_data, return rc; } #endif + +static int ima_eventinodedac_init_common(struct ima_event_data *event_data, + struct ima_field_data *field_data, + bool get_uid) +{ + unsigned int id; + + if (!event_data->file) + return 0; + + if (get_uid) + id = i_uid_read(file_inode(event_data->file)); + else + id = i_gid_read(file_inode(event_data->file)); + + if (ima_canonical_fmt) { + if (sizeof(id) == sizeof(u16)) + id = cpu_to_le16(id); + else + id = cpu_to_le32(id); + } + + return ima_write_template_field_data((void *)&id, sizeof(id), + DATA_FMT_UINT, field_data); +} + +/* + * ima_eventinodeuid_init - include the inode UID as part of the template + * data + */ +int ima_eventinodeuid_init(struct ima_event_data *event_data, + struct ima_field_data *field_data) +{ + return ima_eventinodedac_init_common(event_data, field_data, true); +} + +/* + * ima_eventinodegid_init - include the inode GID as part of the template + * data + */ +int ima_eventinodegid_init(struct ima_event_data *event_data, + struct ima_field_data *field_data) +{ + return ima_eventinodedac_init_common(event_data, field_data, false); +} diff --git a/security/integrity/ima/ima_template_lib.h b/security/integrity/ima/ima_template_lib.h index 7d0d5be2890879e09257bd98516688ef46ecaa05..fbf80c0d7589cfc88b595a8b063a46687adc7138 100644 --- a/security/integrity/ima/ima_template_lib.h +++ b/security/integrity/ima/ima_template_lib.h @@ -27,6 +27,8 @@ void ima_show_template_sig(struct seq_file *m, enum ima_show_type show, struct ima_field_data *field_data); void ima_show_template_buf(struct seq_file *m, enum ima_show_type show, struct ima_field_data *field_data); +void ima_show_template_uint(struct seq_file *m, enum ima_show_type show, + struct ima_field_data *field_data); int ima_parse_buf(void *bufstartp, void *bufendp, void **bufcurp, int maxfields, struct ima_field_data *fields, int *curfields, unsigned long *len_mask, int enforce_mask, char *bufname); @@ -50,4 +52,8 @@ int ima_eventmodsig_init(struct ima_event_data *event_data, int ima_eventevmsig_init(struct ima_event_data *event_data, struct ima_field_data *field_data); #endif /* CONFIG_IMA_DIGEST_LIST */ +int ima_eventinodeuid_init(struct ima_event_data *event_data, + struct ima_field_data *field_data); +int ima_eventinodegid_init(struct ima_event_data *event_data, + struct ima_field_data *field_data); #endif /* __LINUX_IMA_TEMPLATE_LIB_H */