]> git.proxmox.com Git - mirror_ubuntu-focal-kernel.git/commitdiff
apparmor: Check buffer bounds when mapping permissions mask
authorTyler Hicks <tyhicks@canonical.com>
Fri, 6 Jul 2018 05:25:00 +0000 (05:25 +0000)
committerJohn Johansen <john.johansen@canonical.com>
Thu, 19 Jul 2018 23:24:43 +0000 (16:24 -0700)
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#14153611415376 ("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>
security/apparmor/file.c
security/apparmor/include/perms.h
security/apparmor/lib.c

index 224b2fef93cadff32cd3dbd213ad3e2498d2e009..4285943f7260f36f271b7d7ad773345fb84d97f0 100644 (file)
@@ -47,7 +47,8 @@ static void audit_file_mask(struct audit_buffer *ab, u32 mask)
 {
        char str[10];
 
-       aa_perm_mask_to_str(str, aa_file_perm_chrs, map_mask_to_chr_mask(mask));
+       aa_perm_mask_to_str(str, sizeof(str), aa_file_perm_chrs,
+                           map_mask_to_chr_mask(mask));
        audit_log_string(ab, str);
 }
 
index 38aa6247d00f9ce51320bbaf3c50016cbe81ea3b..b94ec114d1a4505f1abfc6d7058af559aa6ae201 100644 (file)
@@ -137,7 +137,8 @@ extern struct aa_perms allperms;
        xcheck(fn_for_each((L1), (P), (FN1)), fn_for_each((L2), (P), (FN2)))
 
 
-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);
 void aa_audit_perm_names(struct audit_buffer *ab, const char * const *names,
                         u32 mask);
 void aa_audit_perm_mask(struct audit_buffer *ab, u32 mask, const char *chrs,
index a7b3f681b80e19aed6b0733ad0edf863b20c0c9b..974affe505314bcd5ecef87966ba698de1dd853e 100644 (file)
@@ -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)