diff options
author | Tetsuo Handa <penguin-kernel@I-love.SAKURA.ne.jp> | 2010-05-16 21:06:58 -0400 |
---|---|---|
committer | James Morris <jmorris@namei.org> | 2010-08-02 01:33:35 -0400 |
commit | 4c3e9e2ded48bcf696a45945ea7d25bb15b873fd (patch) | |
tree | 0be326f0f90b0279ae83594e9244c3739d348df1 /security/tomoyo/common.c | |
parent | babcd37821fba57048b30151969d28303f2a8b6b (diff) |
TOMOYO: Add numeric values grouping support.
This patch adds numeric values grouping support, which is useful for grouping
numeric values such as file's UID, DAC's mode, ioctl()'s cmd number.
Signed-off-by: Tetsuo Handa <penguin-kernel@I-love.SAKURA.ne.jp>
Signed-off-by: James Morris <jmorris@namei.org>
Diffstat (limited to 'security/tomoyo/common.c')
-rw-r--r-- | security/tomoyo/common.c | 161 |
1 files changed, 161 insertions, 0 deletions
diff --git a/security/tomoyo/common.c b/security/tomoyo/common.c index b5dbdc9ff73c..d82c2978b1be 100644 --- a/security/tomoyo/common.c +++ b/security/tomoyo/common.c | |||
@@ -119,6 +119,159 @@ static bool tomoyo_print_name_union(struct tomoyo_io_buffer *head, | |||
119 | } | 119 | } |
120 | 120 | ||
121 | /** | 121 | /** |
122 | * tomoyo_parse_ulong - Parse an "unsigned long" value. | ||
123 | * | ||
124 | * @result: Pointer to "unsigned long". | ||
125 | * @str: Pointer to string to parse. | ||
126 | * | ||
127 | * Returns value type on success, 0 otherwise. | ||
128 | * | ||
129 | * The @src is updated to point the first character after the value | ||
130 | * on success. | ||
131 | */ | ||
132 | u8 tomoyo_parse_ulong(unsigned long *result, char **str) | ||
133 | { | ||
134 | const char *cp = *str; | ||
135 | char *ep; | ||
136 | int base = 10; | ||
137 | if (*cp == '0') { | ||
138 | char c = *(cp + 1); | ||
139 | if (c == 'x' || c == 'X') { | ||
140 | base = 16; | ||
141 | cp += 2; | ||
142 | } else if (c >= '0' && c <= '7') { | ||
143 | base = 8; | ||
144 | cp++; | ||
145 | } | ||
146 | } | ||
147 | *result = simple_strtoul(cp, &ep, base); | ||
148 | if (cp == ep) | ||
149 | return 0; | ||
150 | *str = ep; | ||
151 | switch (base) { | ||
152 | case 16: | ||
153 | return TOMOYO_VALUE_TYPE_HEXADECIMAL; | ||
154 | case 8: | ||
155 | return TOMOYO_VALUE_TYPE_OCTAL; | ||
156 | default: | ||
157 | return TOMOYO_VALUE_TYPE_DECIMAL; | ||
158 | } | ||
159 | } | ||
160 | |||
161 | /** | ||
162 | * tomoyo_print_ulong - Print an "unsigned long" value. | ||
163 | * | ||
164 | * @buffer: Pointer to buffer. | ||
165 | * @buffer_len: Size of @buffer. | ||
166 | * @value: An "unsigned long" value. | ||
167 | * @type: Type of @value. | ||
168 | * | ||
169 | * Returns nothing. | ||
170 | */ | ||
171 | void tomoyo_print_ulong(char *buffer, const int buffer_len, | ||
172 | const unsigned long value, const u8 type) | ||
173 | { | ||
174 | if (type == TOMOYO_VALUE_TYPE_DECIMAL) | ||
175 | snprintf(buffer, buffer_len, "%lu", value); | ||
176 | else if (type == TOMOYO_VALUE_TYPE_OCTAL) | ||
177 | snprintf(buffer, buffer_len, "0%lo", value); | ||
178 | else if (type == TOMOYO_VALUE_TYPE_HEXADECIMAL) | ||
179 | snprintf(buffer, buffer_len, "0x%lX", value); | ||
180 | else | ||
181 | snprintf(buffer, buffer_len, "type(%u)", type); | ||
182 | } | ||
183 | |||
184 | /** | ||
185 | * tomoyo_print_number_union - Print a tomoyo_number_union. | ||
186 | * | ||
187 | * @head: Pointer to "struct tomoyo_io_buffer". | ||
188 | * @ptr: Pointer to "struct tomoyo_number_union". | ||
189 | * | ||
190 | * Returns true on success, false otherwise. | ||
191 | */ | ||
192 | bool tomoyo_print_number_union(struct tomoyo_io_buffer *head, | ||
193 | const struct tomoyo_number_union *ptr) | ||
194 | { | ||
195 | unsigned long min; | ||
196 | unsigned long max; | ||
197 | u8 min_type; | ||
198 | u8 max_type; | ||
199 | if (!tomoyo_io_printf(head, " ")) | ||
200 | return false; | ||
201 | if (ptr->is_group) | ||
202 | return tomoyo_io_printf(head, "@%s", | ||
203 | ptr->group->group_name->name); | ||
204 | min_type = ptr->min_type; | ||
205 | max_type = ptr->max_type; | ||
206 | min = ptr->values[0]; | ||
207 | max = ptr->values[1]; | ||
208 | switch (min_type) { | ||
209 | case TOMOYO_VALUE_TYPE_HEXADECIMAL: | ||
210 | if (!tomoyo_io_printf(head, "0x%lX", min)) | ||
211 | return false; | ||
212 | break; | ||
213 | case TOMOYO_VALUE_TYPE_OCTAL: | ||
214 | if (!tomoyo_io_printf(head, "0%lo", min)) | ||
215 | return false; | ||
216 | break; | ||
217 | default: | ||
218 | if (!tomoyo_io_printf(head, "%lu", min)) | ||
219 | return false; | ||
220 | break; | ||
221 | } | ||
222 | if (min == max && min_type == max_type) | ||
223 | return true; | ||
224 | switch (max_type) { | ||
225 | case TOMOYO_VALUE_TYPE_HEXADECIMAL: | ||
226 | return tomoyo_io_printf(head, "-0x%lX", max); | ||
227 | case TOMOYO_VALUE_TYPE_OCTAL: | ||
228 | return tomoyo_io_printf(head, "-0%lo", max); | ||
229 | default: | ||
230 | return tomoyo_io_printf(head, "-%lu", max); | ||
231 | } | ||
232 | } | ||
233 | |||
234 | /** | ||
235 | * tomoyo_parse_number_union - Parse a tomoyo_number_union. | ||
236 | * | ||
237 | * @data: Number or number range or number group. | ||
238 | * @ptr: Pointer to "struct tomoyo_number_union". | ||
239 | * | ||
240 | * Returns true on success, false otherwise. | ||
241 | */ | ||
242 | bool tomoyo_parse_number_union(char *data, struct tomoyo_number_union *num) | ||
243 | { | ||
244 | u8 type; | ||
245 | unsigned long v; | ||
246 | memset(num, 0, sizeof(*num)); | ||
247 | if (data[0] == '@') { | ||
248 | if (!tomoyo_is_correct_path(data, 0, 0, 0)) | ||
249 | return false; | ||
250 | num->group = tomoyo_get_number_group(data + 1); | ||
251 | num->is_group = true; | ||
252 | return num->group != NULL; | ||
253 | } | ||
254 | type = tomoyo_parse_ulong(&v, &data); | ||
255 | if (!type) | ||
256 | return false; | ||
257 | num->values[0] = v; | ||
258 | num->min_type = type; | ||
259 | if (!*data) { | ||
260 | num->values[1] = v; | ||
261 | num->max_type = type; | ||
262 | return true; | ||
263 | } | ||
264 | if (*data++ != '-') | ||
265 | return false; | ||
266 | type = tomoyo_parse_ulong(&v, &data); | ||
267 | if (!type || *data) | ||
268 | return false; | ||
269 | num->values[1] = v; | ||
270 | num->max_type = type; | ||
271 | return true; | ||
272 | } | ||
273 | |||
274 | /** | ||
122 | * tomoyo_is_byte_range - Check whether the string isa \ooo style octal value. | 275 | * tomoyo_is_byte_range - Check whether the string isa \ooo style octal value. |
123 | * | 276 | * |
124 | * @str: Pointer to the string. | 277 | * @str: Pointer to the string. |
@@ -1750,6 +1903,8 @@ static int tomoyo_write_exception_policy(struct tomoyo_io_buffer *head) | |||
1750 | return tomoyo_write_no_rewrite_policy(data, is_delete); | 1903 | return tomoyo_write_no_rewrite_policy(data, is_delete); |
1751 | if (tomoyo_str_starts(&data, TOMOYO_KEYWORD_PATH_GROUP)) | 1904 | if (tomoyo_str_starts(&data, TOMOYO_KEYWORD_PATH_GROUP)) |
1752 | return tomoyo_write_path_group_policy(data, is_delete); | 1905 | return tomoyo_write_path_group_policy(data, is_delete); |
1906 | if (tomoyo_str_starts(&data, TOMOYO_KEYWORD_NUMBER_GROUP)) | ||
1907 | return tomoyo_write_number_group_policy(data, is_delete); | ||
1753 | return -EINVAL; | 1908 | return -EINVAL; |
1754 | } | 1909 | } |
1755 | 1910 | ||
@@ -1812,6 +1967,12 @@ static int tomoyo_read_exception_policy(struct tomoyo_io_buffer *head) | |||
1812 | head->read_var2 = NULL; | 1967 | head->read_var2 = NULL; |
1813 | head->read_step = 10; | 1968 | head->read_step = 10; |
1814 | case 10: | 1969 | case 10: |
1970 | if (!tomoyo_read_number_group_policy(head)) | ||
1971 | break; | ||
1972 | head->read_var1 = NULL; | ||
1973 | head->read_var2 = NULL; | ||
1974 | head->read_step = 11; | ||
1975 | case 11: | ||
1815 | head->read_eof = true; | 1976 | head->read_eof = true; |
1816 | break; | 1977 | break; |
1817 | default: | 1978 | default: |