diff options
author | Tyler Hicks <tyhicks@canonical.com> | 2018-07-06 07:25:00 +0200 |
---|---|---|
committer | John Johansen <john.johansen@canonical.com> | 2018-07-20 01:24:43 +0200 |
commit | 7f3ebcf2b1395e0248e56146041e1e5625fd2f23 (patch) | |
tree | 51d693e57cc5734aee692b1cebab08acd1aab511 /security/apparmor/lib.c | |
parent | Merge tag 'pci-v4.18-fixes-3' of git://git.kernel.org/pub/scm/linux/kernel/gi... (diff) | |
download | linux-7f3ebcf2b1395e0248e56146041e1e5625fd2f23.tar.xz linux-7f3ebcf2b1395e0248e56146041e1e5625fd2f23.zip |
apparmor: Check buffer bounds when mapping permissions mask
Don't read past the end of the buffer containing permissions
characters or write past the end of the destination string.
Detected by CoverityScan CID#1415361, 1415376 ("Out-of-bounds access")
Fixes: e53cfe6c7caa ("apparmor: rework perm mapping to a slightly broader set")
Signed-off-by: Tyler Hicks <tyhicks@canonical.com>
Acked-by: Serge Hallyn <serge@hallyn.com>
Signed-off-by: John Johansen <john.johansen@canonical.com>
Diffstat (limited to 'security/apparmor/lib.c')
-rw-r--r-- | security/apparmor/lib.c | 17 |
1 files changed, 13 insertions, 4 deletions
diff --git a/security/apparmor/lib.c b/security/apparmor/lib.c index a7b3f681b80e..974affe50531 100644 --- a/security/apparmor/lib.c +++ b/security/apparmor/lib.c @@ -198,15 +198,24 @@ const char *aa_file_perm_names[] = { /** * aa_perm_mask_to_str - convert a perm mask to its short string * @str: character buffer to store string in (at least 10 characters) + * @str_size: size of the @str buffer + * @chrs: NUL-terminated character buffer of permission characters * @mask: permission mask to convert */ -void aa_perm_mask_to_str(char *str, const char *chrs, u32 mask) +void aa_perm_mask_to_str(char *str, size_t str_size, const char *chrs, u32 mask) { unsigned int i, perm = 1; + size_t num_chrs = strlen(chrs); + + for (i = 0; i < num_chrs; perm <<= 1, i++) { + if (mask & perm) { + /* Ensure that one byte is left for NUL-termination */ + if (WARN_ON_ONCE(str_size <= 1)) + break; - for (i = 0; i < 32; perm <<= 1, i++) { - if (mask & perm) *str++ = chrs[i]; + str_size--; + } } *str = '\0'; } @@ -236,7 +245,7 @@ void aa_audit_perm_mask(struct audit_buffer *ab, u32 mask, const char *chrs, audit_log_format(ab, "\""); if ((mask & chrsmask) && chrs) { - aa_perm_mask_to_str(str, chrs, mask & chrsmask); + aa_perm_mask_to_str(str, sizeof(str), chrs, mask & chrsmask); mask &= ~chrsmask; audit_log_format(ab, "%s", str); if (mask & namesmask) |