Skip to content

Commit 223981d

Browse files
cschauflerpcmoore
authored andcommitted
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 <[email protected]> Acked-by: John Johansen <[email protected]> [PM: forward ported beyond v6.6 due merge window changes] Signed-off-by: Paul Moore <[email protected]>
1 parent 38b323e commit 223981d

File tree

3 files changed

+92
-11
lines changed

3 files changed

+92
-11
lines changed

security/apparmor/include/procattr.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111
#ifndef __AA_PROCATTR_H
1212
#define __AA_PROCATTR_H
1313

14-
int aa_getprocattr(struct aa_label *label, char **string);
14+
int aa_getprocattr(struct aa_label *label, char **string, bool newline);
1515
int aa_setprocattr_changehat(char *args, size_t size, int flags);
1616

1717
#endif /* __AA_PROCATTR_H */

security/apparmor/lsm.c

Lines changed: 85 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -776,6 +776,55 @@ static int apparmor_sb_pivotroot(const struct path *old_path,
776776
return error;
777777
}
778778

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+
779828
static int apparmor_getprocattr(struct task_struct *task, const char *name,
780829
char **value)
781830
{
@@ -795,16 +844,15 @@ static int apparmor_getprocattr(struct task_struct *task, const char *name,
795844
error = -EINVAL;
796845

797846
if (label)
798-
error = aa_getprocattr(label, value);
847+
error = aa_getprocattr(label, value, true);
799848

800849
aa_put_label(label);
801850
put_cred(cred);
802851

803852
return error;
804853
}
805854

806-
static int apparmor_setprocattr(const char *name, void *value,
807-
size_t size)
855+
static int do_setattr(u64 attr, void *value, size_t size)
808856
{
809857
char *command, *largs = NULL, *args = value;
810858
size_t arg_size;
@@ -835,7 +883,7 @@ static int apparmor_setprocattr(const char *name, void *value,
835883
goto out;
836884

837885
arg_size = size - (args - (largs ? largs : (char *) value));
838-
if (strcmp(name, "current") == 0) {
886+
if (attr == LSM_ATTR_CURRENT) {
839887
if (strcmp(command, "changehat") == 0) {
840888
error = aa_setprocattr_changehat(args, arg_size,
841889
AA_CHANGE_NOFLAGS);
@@ -850,7 +898,7 @@ static int apparmor_setprocattr(const char *name, void *value,
850898
error = aa_change_profile(args, AA_CHANGE_STACK);
851899
} else
852900
goto fail;
853-
} else if (strcmp(name, "exec") == 0) {
901+
} else if (attr == LSM_ATTR_EXEC) {
854902
if (strcmp(command, "exec") == 0)
855903
error = aa_change_profile(args, AA_CHANGE_ONEXEC);
856904
else if (strcmp(command, "stack") == 0)
@@ -870,13 +918,42 @@ static int apparmor_setprocattr(const char *name, void *value,
870918

871919
fail:
872920
ad.subj_label = begin_current_label_crit_section();
873-
ad.info = name;
921+
if (attr == LSM_ATTR_CURRENT)
922+
ad.info = "current";
923+
else if (attr == LSM_ATTR_EXEC)
924+
ad.info = "exec";
925+
else
926+
ad.info = "invalid";
874927
ad.error = error = -EINVAL;
875928
aa_audit_msg(AUDIT_APPARMOR_DENIED, &ad, NULL);
876929
end_current_label_crit_section(ad.subj_label);
877930
goto out;
878931
}
879932

933+
static int apparmor_setselfattr(unsigned int attr, struct lsm_ctx *ctx,
934+
size_t size, u32 flags)
935+
{
936+
int rc;
937+
938+
if (attr != LSM_ATTR_CURRENT && attr != LSM_ATTR_EXEC)
939+
return -EOPNOTSUPP;
940+
941+
rc = do_setattr(attr, ctx->ctx, ctx->ctx_len);
942+
if (rc > 0)
943+
return 0;
944+
return rc;
945+
}
946+
947+
static int apparmor_setprocattr(const char *name, void *value,
948+
size_t size)
949+
{
950+
int attr = lsm_name_to_attr(name);
951+
952+
if (attr)
953+
return do_setattr(attr, value, size);
954+
return -EINVAL;
955+
}
956+
880957
/**
881958
* apparmor_bprm_committing_creds - do task cleanup on committing new creds
882959
* @bprm: binprm for the exec (NOT NULL)
@@ -1424,6 +1501,8 @@ static struct security_hook_list apparmor_hooks[] __ro_after_init = {
14241501
LSM_HOOK_INIT(file_lock, apparmor_file_lock),
14251502
LSM_HOOK_INIT(file_truncate, apparmor_file_truncate),
14261503

1504+
LSM_HOOK_INIT(getselfattr, apparmor_getselfattr),
1505+
LSM_HOOK_INIT(setselfattr, apparmor_setselfattr),
14271506
LSM_HOOK_INIT(getprocattr, apparmor_getprocattr),
14281507
LSM_HOOK_INIT(setprocattr, apparmor_setprocattr),
14291508

security/apparmor/procattr.c

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -20,14 +20,15 @@
2020
* aa_getprocattr - Return the label information for @label
2121
* @label: the label to print label info about (NOT NULL)
2222
* @string: Returns - string containing the label info (NOT NULL)
23+
* @newline: indicates that a newline should be added
2324
*
2425
* Requires: label != NULL && string != NULL
2526
*
2627
* Creates a string containing the label information for @label.
2728
*
2829
* Returns: size of string placed in @string else error code on failure
2930
*/
30-
int aa_getprocattr(struct aa_label *label, char **string)
31+
int aa_getprocattr(struct aa_label *label, char **string, bool newline)
3132
{
3233
struct aa_ns *ns = labels_ns(label);
3334
struct aa_ns *current_ns = aa_get_current_ns();
@@ -57,11 +58,12 @@ int aa_getprocattr(struct aa_label *label, char **string)
5758
return len;
5859
}
5960

60-
(*string)[len] = '\n';
61-
(*string)[len + 1] = 0;
61+
if (newline)
62+
(*string)[len++] = '\n';
63+
(*string)[len] = 0;
6264

6365
aa_put_ns(current_ns);
64-
return len + 1;
66+
return len;
6567
}
6668

6769
/**

0 commit comments

Comments
 (0)