Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

apparmor: Improve debug print infrastructure

Make it so apparmor debug output can be controlled by class flags
as well as the debug flag on labels. This provides much finer
control at what is being output so apparmor doesn't flood the
logs with information that is not needed, making it hard to find
what is important.

Signed-off-by: John Johansen <john.johansen@canonical.com>

+177 -34
+11 -8
security/apparmor/domain.c
··· 652 652 if (error) { 653 653 if (profile_unconfined(profile) || 654 654 (profile->label.flags & FLAG_IX_ON_NAME_ERROR)) { 655 - AA_DEBUG("name lookup ix on error"); 655 + AA_DEBUG(DEBUG_DOMAIN, "name lookup ix on error"); 656 656 error = 0; 657 657 new = aa_get_newest_label(&profile->label); 658 658 } ··· 664 664 new = find_attach(bprm, profile->ns, 665 665 &profile->ns->base.profiles, name, &info); 666 666 if (new) { 667 - AA_DEBUG("unconfined attached to new label"); 667 + AA_DEBUG(DEBUG_DOMAIN, "unconfined attached to new label"); 668 668 return new; 669 669 } 670 - AA_DEBUG("unconfined exec no attachment"); 670 + AA_DEBUG(DEBUG_DOMAIN, "unconfined exec no attachment"); 671 671 return aa_get_newest_label(&profile->label); 672 672 } 673 673 ··· 766 766 if (error) { 767 767 if (profile_unconfined(profile) || 768 768 (profile->label.flags & FLAG_IX_ON_NAME_ERROR)) { 769 - AA_DEBUG("name lookup ix on error"); 769 + AA_DEBUG(DEBUG_DOMAIN, "name lookup ix on error"); 770 770 error = 0; 771 771 } 772 772 xname = bprm->filename; ··· 1216 1216 if (task_no_new_privs(current) && !unconfined(label) && 1217 1217 !aa_label_is_unconfined_subset(new, ctx->nnp)) { 1218 1218 /* not an apparmor denial per se, so don't log it */ 1219 - AA_DEBUG("no_new_privs - change_hat denied"); 1219 + AA_DEBUG(DEBUG_DOMAIN, 1220 + "no_new_privs - change_hat denied"); 1220 1221 error = -EPERM; 1221 1222 goto out; 1222 1223 } ··· 1238 1237 if (task_no_new_privs(current) && !unconfined(label) && 1239 1238 !aa_label_is_unconfined_subset(previous, ctx->nnp)) { 1240 1239 /* not an apparmor denial per se, so don't log it */ 1241 - AA_DEBUG("no_new_privs - change_hat denied"); 1240 + AA_DEBUG(DEBUG_DOMAIN, 1241 + "no_new_privs - change_hat denied"); 1242 1242 error = -EPERM; 1243 1243 goto out; 1244 1244 } ··· 1345 1343 1346 1344 if (!fqname || !*fqname) { 1347 1345 aa_put_label(label); 1348 - AA_DEBUG("no profile name"); 1346 + AA_DEBUG(DEBUG_DOMAIN, "no profile name"); 1349 1347 return -EINVAL; 1350 1348 } 1351 1349 ··· 1464 1462 if (task_no_new_privs(current) && !unconfined(label) && 1465 1463 !aa_label_is_unconfined_subset(new, ctx->nnp)) { 1466 1464 /* not an apparmor denial per se, so don't log it */ 1467 - AA_DEBUG("no_new_privs - change_hat denied"); 1465 + AA_DEBUG(DEBUG_DOMAIN, 1466 + "no_new_privs - change_hat denied"); 1468 1467 error = -EPERM; 1469 1468 goto out; 1470 1469 }
+1 -1
security/apparmor/include/apparmor.h
··· 43 43 /* Control parameters settable through module/boot flags */ 44 44 extern enum audit_mode aa_g_audit; 45 45 extern bool aa_g_audit_header; 46 - extern bool aa_g_debug; 46 + extern int aa_g_debug; 47 47 extern bool aa_g_hash_policy; 48 48 extern bool aa_g_export_binary; 49 49 extern int aa_g_rawdata_compression_level;
+26 -11
security/apparmor/include/lib.h
··· 19 19 extern struct aa_dfa *stacksplitdfa; 20 20 21 21 /* 22 - * DEBUG remains global (no per profile flag) since it is mostly used in sysctl 23 - * which is not related to profile accesses. 24 - */ 25 - 26 - #define DEBUG_ON (aa_g_debug) 27 - /* 28 22 * split individual debug cases out in preparation for finer grained 29 23 * debug controls in the future. 30 24 */ 31 - #define AA_DEBUG_LABEL DEBUG_ON 32 25 #define dbg_printk(__fmt, __args...) pr_debug(__fmt, ##__args) 33 - #define AA_DEBUG(fmt, args...) \ 26 + 27 + #define DEBUG_NONE 0 28 + #define DEBUG_LABEL_ABS_ROOT 1 29 + #define DEBUG_LABEL 2 30 + #define DEBUG_DOMAIN 4 31 + #define DEBUG_POLICY 8 32 + #define DEBUG_INTERFACE 0x10 33 + 34 + #define DEBUG_ALL 0x1f /* update if new DEBUG_X added */ 35 + #define DEBUG_PARSE_ERROR (-1) 36 + 37 + #define DEBUG_ON (aa_g_debug != DEBUG_NONE) 38 + #define DEBUG_ABS_ROOT (aa_g_debug & DEBUG_LABEL_ABS_ROOT) 39 + 40 + #define AA_DEBUG(opt, fmt, args...) \ 34 41 do { \ 35 - if (DEBUG_ON) \ 36 - pr_debug_ratelimited("AppArmor: " fmt, ##args); \ 42 + if (aa_g_debug & opt) \ 43 + pr_warn_ratelimited("%s: " fmt, __func__, ##args); \ 37 44 } while (0) 45 + #define AA_DEBUG_LABEL(LAB, X, fmt, args) \ 46 + do { \ 47 + if ((LAB)->flags & FLAG_DEBUG1) \ 48 + AA_DEBUG(X, fmt, args); \ 49 + } while (0) 38 50 39 51 #define AA_WARN(X) WARN((X), "APPARMOR WARN %s: %s\n", __func__, #X) 40 52 ··· 62 50 #else 63 51 #define AA_BUG_FMT(X, fmt, args...) no_printk(fmt, ##args) 64 52 #endif 53 + 54 + int aa_parse_debug_params(const char *str); 55 + int aa_print_debug_params(char *buffer); 65 56 66 57 #define AA_ERROR(fmt, args...) \ 67 58 pr_err_ratelimited("AppArmor: " fmt, ##args) ··· 296 281 } \ 297 282 __done: \ 298 283 if (!__new_) \ 299 - AA_DEBUG("label build failed\n"); \ 284 + AA_DEBUG(DEBUG_LABEL, "label build failed\n"); \ 300 285 (__new_); \ 301 286 }) 302 287
+6 -6
security/apparmor/label.c
··· 431 431 432 432 /* + 1 for null terminator entry on vec */ 433 433 new = kzalloc(struct_size(new, vec, size + 1), gfp); 434 - AA_DEBUG("%s (%p)\n", __func__, new); 434 + AA_DEBUG(DEBUG_LABEL, "%s (%p)\n", __func__, new); 435 435 if (!new) 436 436 goto fail; 437 437 ··· 1617 1617 AA_BUG(!str && size != 0); 1618 1618 AA_BUG(!label); 1619 1619 1620 - if (AA_DEBUG_LABEL && (flags & FLAG_ABS_ROOT)) { 1620 + if (DEBUG_ABS_ROOT && (flags & FLAG_ABS_ROOT)) { 1621 1621 ns = root_ns; 1622 1622 len = snprintf(str, size, "_"); 1623 1623 update_for_len(total, len, size, str); ··· 1731 1731 display_mode(ns, label, flags)) { 1732 1732 len = aa_label_asxprint(&name, ns, label, flags, gfp); 1733 1733 if (len < 0) { 1734 - AA_DEBUG("label print error"); 1734 + AA_DEBUG(DEBUG_LABEL, "label print error"); 1735 1735 return; 1736 1736 } 1737 1737 str = name; ··· 1759 1759 1760 1760 len = aa_label_asxprint(&str, ns, label, flags, gfp); 1761 1761 if (len < 0) { 1762 - AA_DEBUG("label print error"); 1762 + AA_DEBUG(DEBUG_LABEL, "label print error"); 1763 1763 return; 1764 1764 } 1765 1765 seq_puts(f, str); ··· 1782 1782 1783 1783 len = aa_label_asxprint(&str, ns, label, flags, gfp); 1784 1784 if (len < 0) { 1785 - AA_DEBUG("label print error"); 1785 + AA_DEBUG(DEBUG_LABEL, "label print error"); 1786 1786 return; 1787 1787 } 1788 1788 pr_info("%s", str); ··· 1865 1865 AA_BUG(!str); 1866 1866 1867 1867 str = skipn_spaces(str, n); 1868 - if (str == NULL || (AA_DEBUG_LABEL && *str == '_' && 1868 + if (str == NULL || (DEBUG_ABS_ROOT && *str == '_' && 1869 1869 base != &root_ns->unconfined->label)) 1870 1870 return ERR_PTR(-EINVAL); 1871 1871
+91
security/apparmor/lib.c
··· 25 25 .quiet = ALL_PERMS_MASK, 26 26 .hide = ALL_PERMS_MASK }; 27 27 28 + struct val_table_ent { 29 + const char *str; 30 + int value; 31 + }; 32 + 33 + struct val_table_ent debug_values_table[] = { 34 + { "N", DEBUG_NONE }, 35 + { "none", DEBUG_NONE }, 36 + { "n", DEBUG_NONE }, 37 + { "0", DEBUG_NONE }, 38 + { "all", DEBUG_ALL }, 39 + { "Y", DEBUG_ALL }, 40 + { "y", DEBUG_ALL }, 41 + { "1", DEBUG_ALL }, 42 + { "abs_root", DEBUG_LABEL_ABS_ROOT }, 43 + { "label", DEBUG_LABEL }, 44 + { "domain", DEBUG_DOMAIN }, 45 + { "policy", DEBUG_POLICY }, 46 + { "interface", DEBUG_INTERFACE }, 47 + { NULL, 0 } 48 + }; 49 + 50 + static struct val_table_ent *val_table_find_ent(struct val_table_ent *table, 51 + const char *name, size_t len) 52 + { 53 + struct val_table_ent *entry; 54 + 55 + for (entry = table; entry->str != NULL; entry++) { 56 + if (strncmp(entry->str, name, len) == 0 && 57 + strlen(entry->str) == len) 58 + return entry; 59 + } 60 + return NULL; 61 + } 62 + 63 + int aa_parse_debug_params(const char *str) 64 + { 65 + struct val_table_ent *ent; 66 + const char *next; 67 + int val = 0; 68 + 69 + do { 70 + size_t n = strcspn(str, "\r\n,"); 71 + 72 + next = str + n; 73 + ent = val_table_find_ent(debug_values_table, str, next - str); 74 + if (ent) 75 + val |= ent->value; 76 + else 77 + AA_DEBUG(DEBUG_INTERFACE, "unknown debug type '%.*s'", 78 + (int)(next - str), str); 79 + str = next + 1; 80 + } while (*next != 0); 81 + return val; 82 + } 83 + 84 + /** 85 + * aa_mask_to_str - convert a perm mask to its short string 86 + * @str: character buffer to store string in (at least 10 characters) 87 + * @str_size: size of the @str buffer 88 + * @chrs: NUL-terminated character buffer of permission characters 89 + * @mask: permission mask to convert 90 + */ 91 + static int val_mask_to_str(char *str, size_t size, 92 + const struct val_table_ent *table, u32 mask) 93 + { 94 + const struct val_table_ent *ent; 95 + int total = 0; 96 + 97 + for (ent = table; ent->str; ent++) { 98 + if (ent->value && (ent->value & mask) == ent->value) { 99 + int len = scnprintf(str, size, "%s%s", total ? "," : "", 100 + ent->str); 101 + size -= len; 102 + str += len; 103 + total += len; 104 + mask &= ~ent->value; 105 + } 106 + } 107 + 108 + return total; 109 + } 110 + 111 + int aa_print_debug_params(char *buffer) 112 + { 113 + if (!aa_g_debug) 114 + return sprintf(buffer, "N"); 115 + return val_mask_to_str(buffer, PAGE_SIZE, debug_values_table, 116 + aa_g_debug); 117 + } 118 + 28 119 /** 29 120 * aa_free_str_table - free entries str table 30 121 * @t: the string table to free (MAYBE NULL)
+34 -2
security/apparmor/lsm.c
··· 1571 1571 .get = param_get_aalockpolicy 1572 1572 }; 1573 1573 1574 + static int param_set_debug(const char *val, const struct kernel_param *kp); 1575 + static int param_get_debug(char *buffer, const struct kernel_param *kp); 1576 + 1574 1577 static int param_set_audit(const char *val, const struct kernel_param *kp); 1575 1578 static int param_get_audit(char *buffer, const struct kernel_param *kp); 1576 1579 ··· 1607 1604 aacompressionlevel, 0400); 1608 1605 1609 1606 /* Debug mode */ 1610 - bool aa_g_debug = IS_ENABLED(CONFIG_SECURITY_APPARMOR_DEBUG_MESSAGES); 1611 - module_param_named(debug, aa_g_debug, aabool, S_IRUSR | S_IWUSR); 1607 + int aa_g_debug; 1608 + module_param_call(debug, param_set_debug, param_get_debug, 1609 + &aa_g_debug, 0600); 1612 1610 1613 1611 /* Audit mode */ 1614 1612 enum audit_mode aa_g_audit; ··· 1800 1796 if (apparmor_initialized && !aa_current_policy_view_capable(NULL)) 1801 1797 return -EPERM; 1802 1798 return param_get_int(buffer, kp); 1799 + } 1800 + 1801 + static int param_get_debug(char *buffer, const struct kernel_param *kp) 1802 + { 1803 + if (!apparmor_enabled) 1804 + return -EINVAL; 1805 + if (apparmor_initialized && !aa_current_policy_view_capable(NULL)) 1806 + return -EPERM; 1807 + return aa_print_debug_params(buffer); 1808 + } 1809 + 1810 + static int param_set_debug(const char *val, const struct kernel_param *kp) 1811 + { 1812 + int i; 1813 + 1814 + if (!apparmor_enabled) 1815 + return -EINVAL; 1816 + if (!val) 1817 + return -EINVAL; 1818 + if (apparmor_initialized && !aa_current_policy_admin_capable(NULL)) 1819 + return -EPERM; 1820 + 1821 + i = aa_parse_debug_params(val); 1822 + if (i == DEBUG_PARSE_ERROR) 1823 + return -EINVAL; 1824 + 1825 + aa_g_debug = i; 1826 + return 0; 1803 1827 } 1804 1828 1805 1829 static int param_get_audit(char *buffer, const struct kernel_param *kp)
+3 -3
security/apparmor/policy.c
··· 280 280 struct aa_ruleset *rule, *tmp; 281 281 struct rhashtable *rht; 282 282 283 - AA_DEBUG("%s(%p)\n", __func__, profile); 283 + AA_DEBUG(DEBUG_POLICY, "%s(%p)\n", __func__, profile); 284 284 285 285 if (!profile) 286 286 return; ··· 833 833 bool capable = policy_ns_capable(subj_cred, label, user_ns, 834 834 CAP_MAC_ADMIN) == 0; 835 835 836 - AA_DEBUG("cap_mac_admin? %d\n", capable); 837 - AA_DEBUG("policy locked? %d\n", aa_g_lock_policy); 836 + AA_DEBUG(DEBUG_POLICY, "cap_mac_admin? %d\n", capable); 837 + AA_DEBUG(DEBUG_POLICY, "policy locked? %d\n", aa_g_lock_policy); 838 838 839 839 return aa_policy_view_capable(subj_cred, label, ns) && capable && 840 840 !aa_g_lock_policy;
+1 -1
security/apparmor/policy_ns.c
··· 107 107 struct aa_ns *ns; 108 108 109 109 ns = kzalloc(sizeof(*ns), GFP_KERNEL); 110 - AA_DEBUG("%s(%p)\n", __func__, ns); 110 + AA_DEBUG(DEBUG_POLICY, "%s(%p)\n", __func__, ns); 111 111 if (!ns) 112 112 return NULL; 113 113 if (!aa_policy_init(&ns->base, prefix, name, GFP_KERNEL))
+4 -2
security/apparmor/procattr.c
··· 125 125 for (count = 0; (hat < end) && count < 16; ++count) { 126 126 char *next = hat + strlen(hat) + 1; 127 127 hats[count] = hat; 128 - AA_DEBUG("%s: (pid %d) Magic 0x%llx count %d hat '%s'\n" 128 + AA_DEBUG(DEBUG_DOMAIN, 129 + "%s: (pid %d) Magic 0x%llx count %d hat '%s'\n" 129 130 , __func__, current->pid, token, count, hat); 130 131 hat = next; 131 132 } 132 133 } else 133 - AA_DEBUG("%s: (pid %d) Magic 0x%llx count %d Hat '%s'\n", 134 + AA_DEBUG(DEBUG_DOMAIN, 135 + "%s: (pid %d) Magic 0x%llx count %d Hat '%s'\n", 134 136 __func__, current->pid, token, count, "<NULL>"); 135 137 136 138 return aa_change_hat(hats, count, token, flags);