]>
Commit | Line | Data |
---|---|---|
cdff2642 JJ |
1 | /* |
2 | * AppArmor security module | |
3 | * | |
4 | * This file contains basic common functions used in AppArmor | |
5 | * | |
6 | * Copyright (C) 1998-2008 Novell/SUSE | |
7 | * Copyright 2009-2010 Canonical Ltd. | |
8 | * | |
9 | * This program is free software; you can redistribute it and/or | |
10 | * modify it under the terms of the GNU General Public License as | |
11 | * published by the Free Software Foundation, version 2 of the | |
12 | * License. | |
13 | */ | |
14 | ||
3b0aaf58 | 15 | #include <linux/ctype.h> |
b7f080cf | 16 | #include <linux/mm.h> |
cdff2642 JJ |
17 | #include <linux/slab.h> |
18 | #include <linux/string.h> | |
19 | #include <linux/vmalloc.h> | |
20 | ||
21 | #include "include/audit.h" | |
32c3df63 | 22 | #include "include/apparmor.h" |
12557dcb | 23 | #include "include/lib.h" |
fe6bb31f | 24 | #include "include/policy.h" |
cdff2642 JJ |
25 | |
26 | /** | |
27 | * aa_split_fqname - split a fqname into a profile and namespace name | |
28 | * @fqname: a full qualified name in namespace profile format (NOT NULL) | |
29 | * @ns_name: pointer to portion of the string containing the ns name (NOT NULL) | |
30 | * | |
31 | * Returns: profile name or NULL if one is not specified | |
32 | * | |
33 | * Split a namespace name from a profile name (see policy.c for naming | |
34 | * description). If a portion of the name is missing it returns NULL for | |
35 | * that portion. | |
36 | * | |
37 | * NOTE: may modify the @fqname string. The pointers returned point | |
38 | * into the @fqname string. | |
39 | */ | |
40 | char *aa_split_fqname(char *fqname, char **ns_name) | |
41 | { | |
42 | char *name = strim(fqname); | |
43 | ||
44 | *ns_name = NULL; | |
45 | if (name[0] == ':') { | |
46 | char *split = strchr(&name[1], ':'); | |
04ccd53f | 47 | *ns_name = skip_spaces(&name[1]); |
cdff2642 JJ |
48 | if (split) { |
49 | /* overwrite ':' with \0 */ | |
2654bfbc JJ |
50 | *split++ = 0; |
51 | if (strncmp(split, "//", 2) == 0) | |
52 | split += 2; | |
53 | name = skip_spaces(split); | |
cdff2642 JJ |
54 | } else |
55 | /* a ns name without a following profile is allowed */ | |
56 | name = NULL; | |
cdff2642 JJ |
57 | } |
58 | if (name && *name == 0) | |
59 | name = NULL; | |
60 | ||
61 | return name; | |
62 | } | |
63 | ||
3b0aaf58 JJ |
64 | /** |
65 | * skipn_spaces - Removes leading whitespace from @str. | |
66 | * @str: The string to be stripped. | |
67 | * | |
68 | * Returns a pointer to the first non-whitespace character in @str. | |
69 | * if all whitespace will return NULL | |
70 | */ | |
71 | ||
72 | static const char *skipn_spaces(const char *str, size_t n) | |
73 | { | |
74 | for (; n && isspace(*str); --n) | |
75 | ++str; | |
76 | if (n) | |
77 | return (char *)str; | |
78 | return NULL; | |
79 | } | |
80 | ||
81 | const char *aa_splitn_fqname(const char *fqname, size_t n, const char **ns_name, | |
82 | size_t *ns_len) | |
83 | { | |
84 | const char *end = fqname + n; | |
85 | const char *name = skipn_spaces(fqname, n); | |
86 | ||
87 | if (!name) | |
88 | return NULL; | |
89 | *ns_name = NULL; | |
90 | *ns_len = 0; | |
91 | if (name[0] == ':') { | |
92 | char *split = strnchr(&name[1], end - &name[1], ':'); | |
93 | *ns_name = skipn_spaces(&name[1], end - &name[1]); | |
94 | if (!*ns_name) | |
95 | return NULL; | |
96 | if (split) { | |
97 | *ns_len = split - *ns_name; | |
98 | if (*ns_len == 0) | |
99 | *ns_name = NULL; | |
100 | split++; | |
101 | if (end - split > 1 && strncmp(split, "//", 2) == 0) | |
102 | split += 2; | |
103 | name = skipn_spaces(split, end - split); | |
104 | } else { | |
105 | /* a ns name without a following profile is allowed */ | |
106 | name = NULL; | |
107 | *ns_len = end - *ns_name; | |
108 | } | |
109 | } | |
110 | if (name && *name == 0) | |
111 | name = NULL; | |
112 | ||
113 | return name; | |
114 | } | |
115 | ||
cdff2642 JJ |
116 | /** |
117 | * aa_info_message - log a none profile related status message | |
118 | * @str: message to log | |
119 | */ | |
120 | void aa_info_message(const char *str) | |
121 | { | |
122 | if (audit_enabled) { | |
ef88a7ac JJ |
123 | DEFINE_AUDIT_DATA(sa, LSM_AUDIT_DATA_NONE, NULL); |
124 | ||
125 | aad(&sa)->info = str; | |
cdff2642 JJ |
126 | aa_audit_msg(AUDIT_APPARMOR_STATUS, &sa, NULL); |
127 | } | |
128 | printk(KERN_INFO "AppArmor: %s\n", str); | |
129 | } | |
130 | ||
fe6bb31f JJ |
131 | /** |
132 | * aa_policy_init - initialize a policy structure | |
133 | * @policy: policy to initialize (NOT NULL) | |
134 | * @prefix: prefix name if any is required. (MAYBE NULL) | |
135 | * @name: name of the policy, init will make a copy of it (NOT NULL) | |
136 | * | |
137 | * Note: this fn creates a copy of strings passed in | |
138 | * | |
139 | * Returns: true if policy init successful | |
140 | */ | |
141 | bool aa_policy_init(struct aa_policy *policy, const char *prefix, | |
d102d895 | 142 | const char *name, gfp_t gfp) |
fe6bb31f JJ |
143 | { |
144 | /* freed by policy_free */ | |
145 | if (prefix) { | |
146 | policy->hname = kmalloc(strlen(prefix) + strlen(name) + 3, | |
d102d895 | 147 | gfp); |
fe6bb31f | 148 | if (policy->hname) |
bbe4a7c8 | 149 | sprintf((char *)policy->hname, "%s//%s", prefix, name); |
fe6bb31f | 150 | } else |
d102d895 | 151 | policy->hname = kstrdup(name, gfp); |
fe6bb31f | 152 | if (!policy->hname) |
b9c42ac7 | 153 | return false; |
fe6bb31f | 154 | /* base.name is a substring of fqname */ |
d102d895 | 155 | policy->name = basename(policy->hname); |
fe6bb31f JJ |
156 | INIT_LIST_HEAD(&policy->list); |
157 | INIT_LIST_HEAD(&policy->profiles); | |
158 | ||
b9c42ac7 | 159 | return true; |
fe6bb31f JJ |
160 | } |
161 | ||
162 | /** | |
163 | * aa_policy_destroy - free the elements referenced by @policy | |
164 | * @policy: policy that is to have its elements freed (NOT NULL) | |
165 | */ | |
166 | void aa_policy_destroy(struct aa_policy *policy) | |
167 | { | |
5fd1b95f JJ |
168 | AA_BUG(on_list_rcu(&policy->profiles)); |
169 | AA_BUG(on_list_rcu(&policy->list)); | |
fe6bb31f JJ |
170 | |
171 | /* don't free name as its a subset of hname */ | |
172 | kzfree(policy->hname); | |
173 | } |