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

AppArmor: Add selfattr hooks

Add hooks for setselfattr and getselfattr. These hooks are not very
different from their setprocattr and getprocattr equivalents, and
much of the code is shared.

Signed-off-by: Casey Schaufler <casey@schaufler-ca.com>
Acked-by: John Johansen <john.johansen@canonical.com>
[PM: forward ported beyond v6.6 due merge window changes]
Signed-off-by: Paul Moore <paul@paul-moore.com>

authored by

Casey Schaufler and committed by
Paul Moore
223981db 38b323e5

+92 -11
+1 -1
security/apparmor/include/procattr.h
··· 11 11 #ifndef __AA_PROCATTR_H 12 12 #define __AA_PROCATTR_H 13 13 14 - int aa_getprocattr(struct aa_label *label, char **string); 14 + int aa_getprocattr(struct aa_label *label, char **string, bool newline); 15 15 int aa_setprocattr_changehat(char *args, size_t size, int flags); 16 16 17 17 #endif /* __AA_PROCATTR_H */
+85 -6
security/apparmor/lsm.c
··· 776 776 return error; 777 777 } 778 778 779 + static int apparmor_getselfattr(unsigned int attr, struct lsm_ctx __user *lx, 780 + size_t *size, u32 flags) 781 + { 782 + int error = -ENOENT; 783 + struct aa_task_ctx *ctx = task_ctx(current); 784 + struct aa_label *label = NULL; 785 + size_t total_len = 0; 786 + char *value; 787 + 788 + switch (attr) { 789 + case LSM_ATTR_CURRENT: 790 + label = aa_get_newest_label(cred_label(current_cred())); 791 + break; 792 + case LSM_ATTR_PREV: 793 + if (ctx->previous) 794 + label = aa_get_newest_label(ctx->previous); 795 + break; 796 + case LSM_ATTR_EXEC: 797 + if (ctx->onexec) 798 + label = aa_get_newest_label(ctx->onexec); 799 + break; 800 + default: 801 + error = -EOPNOTSUPP; 802 + break; 803 + } 804 + 805 + if (label) { 806 + error = aa_getprocattr(label, &value, false); 807 + if (error > 0) { 808 + total_len = ALIGN(struct_size(lx, ctx, error), 8); 809 + if (total_len > *size) 810 + error = -E2BIG; 811 + else if (lx) 812 + error = lsm_fill_user_ctx(lx, value, error, 813 + LSM_ID_APPARMOR, 0); 814 + else 815 + error = 1; 816 + } 817 + kfree(value); 818 + } 819 + 820 + aa_put_label(label); 821 + 822 + *size = total_len; 823 + if (error < 0) 824 + return error; 825 + return 1; 826 + } 827 + 779 828 static int apparmor_getprocattr(struct task_struct *task, const char *name, 780 829 char **value) 781 830 { ··· 844 795 error = -EINVAL; 845 796 846 797 if (label) 847 - error = aa_getprocattr(label, value); 798 + error = aa_getprocattr(label, value, true); 848 799 849 800 aa_put_label(label); 850 801 put_cred(cred); ··· 852 803 return error; 853 804 } 854 805 855 - static int apparmor_setprocattr(const char *name, void *value, 856 - size_t size) 806 + static int do_setattr(u64 attr, void *value, size_t size) 857 807 { 858 808 char *command, *largs = NULL, *args = value; 859 809 size_t arg_size; ··· 883 835 goto out; 884 836 885 837 arg_size = size - (args - (largs ? largs : (char *) value)); 886 - if (strcmp(name, "current") == 0) { 838 + if (attr == LSM_ATTR_CURRENT) { 887 839 if (strcmp(command, "changehat") == 0) { 888 840 error = aa_setprocattr_changehat(args, arg_size, 889 841 AA_CHANGE_NOFLAGS); ··· 898 850 error = aa_change_profile(args, AA_CHANGE_STACK); 899 851 } else 900 852 goto fail; 901 - } else if (strcmp(name, "exec") == 0) { 853 + } else if (attr == LSM_ATTR_EXEC) { 902 854 if (strcmp(command, "exec") == 0) 903 855 error = aa_change_profile(args, AA_CHANGE_ONEXEC); 904 856 else if (strcmp(command, "stack") == 0) ··· 918 870 919 871 fail: 920 872 ad.subj_label = begin_current_label_crit_section(); 921 - ad.info = name; 873 + if (attr == LSM_ATTR_CURRENT) 874 + ad.info = "current"; 875 + else if (attr == LSM_ATTR_EXEC) 876 + ad.info = "exec"; 877 + else 878 + ad.info = "invalid"; 922 879 ad.error = error = -EINVAL; 923 880 aa_audit_msg(AUDIT_APPARMOR_DENIED, &ad, NULL); 924 881 end_current_label_crit_section(ad.subj_label); 925 882 goto out; 883 + } 884 + 885 + static int apparmor_setselfattr(unsigned int attr, struct lsm_ctx *ctx, 886 + size_t size, u32 flags) 887 + { 888 + int rc; 889 + 890 + if (attr != LSM_ATTR_CURRENT && attr != LSM_ATTR_EXEC) 891 + return -EOPNOTSUPP; 892 + 893 + rc = do_setattr(attr, ctx->ctx, ctx->ctx_len); 894 + if (rc > 0) 895 + return 0; 896 + return rc; 897 + } 898 + 899 + static int apparmor_setprocattr(const char *name, void *value, 900 + size_t size) 901 + { 902 + int attr = lsm_name_to_attr(name); 903 + 904 + if (attr) 905 + return do_setattr(attr, value, size); 906 + return -EINVAL; 926 907 } 927 908 928 909 /** ··· 1501 1424 LSM_HOOK_INIT(file_lock, apparmor_file_lock), 1502 1425 LSM_HOOK_INIT(file_truncate, apparmor_file_truncate), 1503 1426 1427 + LSM_HOOK_INIT(getselfattr, apparmor_getselfattr), 1428 + LSM_HOOK_INIT(setselfattr, apparmor_setselfattr), 1504 1429 LSM_HOOK_INIT(getprocattr, apparmor_getprocattr), 1505 1430 LSM_HOOK_INIT(setprocattr, apparmor_setprocattr), 1506 1431
+6 -4
security/apparmor/procattr.c
··· 20 20 * aa_getprocattr - Return the label information for @label 21 21 * @label: the label to print label info about (NOT NULL) 22 22 * @string: Returns - string containing the label info (NOT NULL) 23 + * @newline: indicates that a newline should be added 23 24 * 24 25 * Requires: label != NULL && string != NULL 25 26 * ··· 28 27 * 29 28 * Returns: size of string placed in @string else error code on failure 30 29 */ 31 - int aa_getprocattr(struct aa_label *label, char **string) 30 + int aa_getprocattr(struct aa_label *label, char **string, bool newline) 32 31 { 33 32 struct aa_ns *ns = labels_ns(label); 34 33 struct aa_ns *current_ns = aa_get_current_ns(); ··· 58 57 return len; 59 58 } 60 59 61 - (*string)[len] = '\n'; 62 - (*string)[len + 1] = 0; 60 + if (newline) 61 + (*string)[len++] = '\n'; 62 + (*string)[len] = 0; 63 63 64 64 aa_put_ns(current_ns); 65 - return len + 1; 65 + return len; 66 66 } 67 67 68 68 /**