Branch data Line data Source code
1 : : // SPDX-License-Identifier: GPL-2.0-only
2 : : /*
3 : : * AppArmor security module
4 : : *
5 : : * This file contains AppArmor /proc/<pid>/attr/ interface functions
6 : : *
7 : : * Copyright (C) 1998-2008 Novell/SUSE
8 : : * Copyright 2009-2010 Canonical Ltd.
9 : : */
10 : :
11 : : #include "include/apparmor.h"
12 : : #include "include/cred.h"
13 : : #include "include/policy.h"
14 : : #include "include/policy_ns.h"
15 : : #include "include/domain.h"
16 : : #include "include/procattr.h"
17 : :
18 : :
19 : : /**
20 : : * aa_getprocattr - Return the profile information for @profile
21 : : * @profile: the profile to print profile info about (NOT NULL)
22 : : * @string: Returns - string containing the profile info (NOT NULL)
23 : : *
24 : : * Returns: length of @string on success else error on failure
25 : : *
26 : : * Requires: profile != NULL
27 : : *
28 : : * Creates a string containing the namespace_name://profile_name for
29 : : * @profile.
30 : : *
31 : : * Returns: size of string placed in @string else error code on failure
32 : : */
33 : 0 : int aa_getprocattr(struct aa_label *label, char **string)
34 : : {
35 : 0 : struct aa_ns *ns = labels_ns(label);
36 : 0 : struct aa_ns *current_ns = aa_get_current_ns();
37 : : int len;
38 : :
39 [ # # ]: 0 : if (!aa_ns_visible(current_ns, ns, true)) {
40 : 0 : aa_put_ns(current_ns);
41 : 0 : return -EACCES;
42 : : }
43 : :
44 : 0 : len = aa_label_snxprint(NULL, 0, current_ns, label,
45 : : FLAG_SHOW_MODE | FLAG_VIEW_SUBNS |
46 : : FLAG_HIDDEN_UNCONFINED);
47 : : AA_BUG(len < 0);
48 : :
49 : 0 : *string = kmalloc(len + 2, GFP_KERNEL);
50 [ # # ]: 0 : if (!*string) {
51 : 0 : aa_put_ns(current_ns);
52 : 0 : return -ENOMEM;
53 : : }
54 : :
55 : 0 : len = aa_label_snxprint(*string, len + 2, current_ns, label,
56 : : FLAG_SHOW_MODE | FLAG_VIEW_SUBNS |
57 : : FLAG_HIDDEN_UNCONFINED);
58 [ # # ]: 0 : if (len < 0) {
59 : 0 : aa_put_ns(current_ns);
60 : 0 : return len;
61 : : }
62 : :
63 : 0 : (*string)[len] = '\n';
64 : 0 : (*string)[len + 1] = 0;
65 : :
66 : 0 : aa_put_ns(current_ns);
67 : 0 : return len + 1;
68 : : }
69 : :
70 : : /**
71 : : * split_token_from_name - separate a string of form <token>^<name>
72 : : * @op: operation being checked
73 : : * @args: string to parse (NOT NULL)
74 : : * @token: stores returned parsed token value (NOT NULL)
75 : : *
76 : : * Returns: start position of name after token else NULL on failure
77 : : */
78 : 0 : static char *split_token_from_name(const char *op, char *args, u64 *token)
79 : : {
80 : : char *name;
81 : :
82 : 0 : *token = simple_strtoull(args, &name, 16);
83 [ # # # # ]: 0 : if ((name == args) || *name != '^') {
84 [ # # ]: 0 : AA_ERROR("%s: Invalid input '%s'", op, args);
85 : : return ERR_PTR(-EINVAL);
86 : : }
87 : :
88 : 0 : name++; /* skip ^ */
89 [ # # ]: 0 : if (!*name)
90 : 0 : name = NULL;
91 : 0 : return name;
92 : : }
93 : :
94 : : /**
95 : : * aa_setprocattr_chagnehat - handle procattr interface to change_hat
96 : : * @args: args received from writing to /proc/<pid>/attr/current (NOT NULL)
97 : : * @size: size of the args
98 : : * @flags: set of flags governing behavior
99 : : *
100 : : * Returns: %0 or error code if change_hat fails
101 : : */
102 : 0 : int aa_setprocattr_changehat(char *args, size_t size, int flags)
103 : : {
104 : : char *hat;
105 : : u64 token;
106 : : const char *hats[16]; /* current hard limit on # of names */
107 : : int count = 0;
108 : :
109 : 0 : hat = split_token_from_name(OP_CHANGE_HAT, args, &token);
110 [ # # ]: 0 : if (IS_ERR(hat))
111 : 0 : return PTR_ERR(hat);
112 : :
113 [ # # # # ]: 0 : if (!hat && !token) {
114 [ # # ]: 0 : AA_ERROR("change_hat: Invalid input, NULL hat and NULL magic");
115 : : return -EINVAL;
116 : : }
117 : :
118 [ # # ]: 0 : if (hat) {
119 : : /* set up hat name vector, args guaranteed null terminated
120 : : * at args[size] by setprocattr.
121 : : *
122 : : * If there are multiple hat names in the buffer each is
123 : : * separated by a \0. Ie. userspace writes them pre tokenized
124 : : */
125 : 0 : char *end = args + size;
126 [ # # ]: 0 : for (count = 0; (hat < end) && count < 16; ++count) {
127 : 0 : char *next = hat + strlen(hat) + 1;
128 : 0 : hats[count] = hat;
129 : : AA_DEBUG("%s: (pid %d) Magic 0x%llx count %d hat '%s'\n"
130 : : , __func__, current->pid, token, count, hat);
131 : : hat = next;
132 : : }
133 : : } else
134 : : AA_DEBUG("%s: (pid %d) Magic 0x%llx count %d Hat '%s'\n",
135 : : __func__, current->pid, token, count, "<NULL>");
136 : :
137 : 0 : return aa_change_hat(hats, count, token, flags);
138 : : }
|