aboutsummaryrefslogtreecommitdiffstats
path: root/security/selinux/ss/mls.c
diff options
context:
space:
mode:
Diffstat (limited to 'security/selinux/ss/mls.c')
-rw-r--r--security/selinux/ss/mls.c178
1 files changed, 77 insertions, 101 deletions
diff --git a/security/selinux/ss/mls.c b/security/selinux/ss/mls.c
index 39475fb455bc..2fe459df3c85 100644
--- a/security/selinux/ss/mls.c
+++ b/security/selinux/ss/mls.c
@@ -218,9 +218,7 @@ int mls_context_isvalid(struct policydb *p, struct context *c)
218/* 218/*
219 * Set the MLS fields in the security context structure 219 * Set the MLS fields in the security context structure
220 * `context' based on the string representation in 220 * `context' based on the string representation in
221 * the string `*scontext'. Update `*scontext' to 221 * the string `scontext'.
222 * point to the end of the string representation of
223 * the MLS fields.
224 * 222 *
225 * This function modifies the string in place, inserting 223 * This function modifies the string in place, inserting
226 * NULL characters to terminate the MLS fields. 224 * NULL characters to terminate the MLS fields.
@@ -235,22 +233,21 @@ int mls_context_isvalid(struct policydb *p, struct context *c)
235 */ 233 */
236int mls_context_to_sid(struct policydb *pol, 234int mls_context_to_sid(struct policydb *pol,
237 char oldc, 235 char oldc,
238 char **scontext, 236 char *scontext,
239 struct context *context, 237 struct context *context,
240 struct sidtab *s, 238 struct sidtab *s,
241 u32 def_sid) 239 u32 def_sid)
242{ 240{
243 241 char *sensitivity, *cur_cat, *next_cat, *rngptr;
244 char delim;
245 char *scontextp, *p, *rngptr;
246 struct level_datum *levdatum; 242 struct level_datum *levdatum;
247 struct cat_datum *catdatum, *rngdatum; 243 struct cat_datum *catdatum, *rngdatum;
248 int l, rc = -EINVAL; 244 int l, rc, i;
245 char *rangep[2];
249 246
250 if (!pol->mls_enabled) { 247 if (!pol->mls_enabled) {
251 if (def_sid != SECSID_NULL && oldc) 248 if ((def_sid != SECSID_NULL && oldc) || (*scontext) == '\0')
252 *scontext += strlen(*scontext) + 1; 249 return 0;
253 return 0; 250 return -EINVAL;
254 } 251 }
255 252
256 /* 253 /*
@@ -261,113 +258,94 @@ int mls_context_to_sid(struct policydb *pol,
261 struct context *defcon; 258 struct context *defcon;
262 259
263 if (def_sid == SECSID_NULL) 260 if (def_sid == SECSID_NULL)
264 goto out; 261 return -EINVAL;
265 262
266 defcon = sidtab_search(s, def_sid); 263 defcon = sidtab_search(s, def_sid);
267 if (!defcon) 264 if (!defcon)
268 goto out; 265 return -EINVAL;
269 266
270 rc = mls_context_cpy(context, defcon); 267 return mls_context_cpy(context, defcon);
271 goto out;
272 } 268 }
273 269
274 /* Extract low sensitivity. */ 270 /*
275 scontextp = p = *scontext; 271 * If we're dealing with a range, figure out where the two parts
276 while (*p && *p != ':' && *p != '-') 272 * of the range begin.
277 p++; 273 */
278 274 rangep[0] = scontext;
279 delim = *p; 275 rangep[1] = strchr(scontext, '-');
280 if (delim != '\0') 276 if (rangep[1]) {
281 *p++ = '\0'; 277 rangep[1][0] = '\0';
278 rangep[1]++;
279 }
282 280
281 /* For each part of the range: */
283 for (l = 0; l < 2; l++) { 282 for (l = 0; l < 2; l++) {
284 levdatum = hashtab_search(pol->p_levels.table, scontextp); 283 /* Split sensitivity and category set. */
285 if (!levdatum) { 284 sensitivity = rangep[l];
286 rc = -EINVAL; 285 if (sensitivity == NULL)
287 goto out; 286 break;
288 } 287 next_cat = strchr(sensitivity, ':');
288 if (next_cat)
289 *(next_cat++) = '\0';
289 290
291 /* Parse sensitivity. */
292 levdatum = hashtab_search(pol->p_levels.table, sensitivity);
293 if (!levdatum)
294 return -EINVAL;
290 context->range.level[l].sens = levdatum->level->sens; 295 context->range.level[l].sens = levdatum->level->sens;
291 296
292 if (delim == ':') { 297 /* Extract category set. */
293 /* Extract category set. */ 298 while (next_cat != NULL) {
294 while (1) { 299 cur_cat = next_cat;
295 scontextp = p; 300 next_cat = strchr(next_cat, ',');
296 while (*p && *p != ',' && *p != '-') 301 if (next_cat != NULL)
297 p++; 302 *(next_cat++) = '\0';
298 delim = *p; 303
299 if (delim != '\0') 304 /* Separate into range if exists */
300 *p++ = '\0'; 305 rngptr = strchr(cur_cat, '.');
301 306 if (rngptr != NULL) {
302 /* Separate into range if exists */ 307 /* Remove '.' */
303 rngptr = strchr(scontextp, '.'); 308 *rngptr++ = '\0';
304 if (rngptr != NULL) { 309 }
305 /* Remove '.' */
306 *rngptr++ = '\0';
307 }
308 310
309 catdatum = hashtab_search(pol->p_cats.table, 311 catdatum = hashtab_search(pol->p_cats.table, cur_cat);
310 scontextp); 312 if (!catdatum)
311 if (!catdatum) { 313 return -EINVAL;
312 rc = -EINVAL;
313 goto out;
314 }
315 314
316 rc = ebitmap_set_bit(&context->range.level[l].cat, 315 rc = ebitmap_set_bit(&context->range.level[l].cat,
317 catdatum->value - 1, 1); 316 catdatum->value - 1, 1);
318 if (rc) 317 if (rc)
319 goto out; 318 return rc;
320 319
321 /* If range, set all categories in range */ 320 /* If range, set all categories in range */
322 if (rngptr) { 321 if (rngptr == NULL)
323 int i; 322 continue;
324 323
325 rngdatum = hashtab_search(pol->p_cats.table, rngptr); 324 rngdatum = hashtab_search(pol->p_cats.table, rngptr);
326 if (!rngdatum) { 325 if (!rngdatum)
327 rc = -EINVAL; 326 return -EINVAL;
328 goto out; 327
329 } 328 if (catdatum->value >= rngdatum->value)
330 329 return -EINVAL;
331 if (catdatum->value >= rngdatum->value) {
332 rc = -EINVAL;
333 goto out;
334 }
335
336 for (i = catdatum->value; i < rngdatum->value; i++) {
337 rc = ebitmap_set_bit(&context->range.level[l].cat, i, 1);
338 if (rc)
339 goto out;
340 }
341 }
342 330
343 if (delim != ',') 331 for (i = catdatum->value; i < rngdatum->value; i++) {
344 break; 332 rc = ebitmap_set_bit(&context->range.level[l].cat, i, 1);
333 if (rc)
334 return rc;
345 } 335 }
346 } 336 }
347 if (delim == '-') {
348 /* Extract high sensitivity. */
349 scontextp = p;
350 while (*p && *p != ':')
351 p++;
352
353 delim = *p;
354 if (delim != '\0')
355 *p++ = '\0';
356 } else
357 break;
358 } 337 }
359 338
360 if (l == 0) { 339 /* If we didn't see a '-', the range start is also the range end. */
340 if (rangep[1] == NULL) {
361 context->range.level[1].sens = context->range.level[0].sens; 341 context->range.level[1].sens = context->range.level[0].sens;
362 rc = ebitmap_cpy(&context->range.level[1].cat, 342 rc = ebitmap_cpy(&context->range.level[1].cat,
363 &context->range.level[0].cat); 343 &context->range.level[0].cat);
364 if (rc) 344 if (rc)
365 goto out; 345 return rc;
366 } 346 }
367 *scontext = ++p; 347
368 rc = 0; 348 return 0;
369out:
370 return rc;
371} 349}
372 350
373/* 351/*
@@ -379,21 +357,19 @@ out:
379int mls_from_string(struct policydb *p, char *str, struct context *context, 357int mls_from_string(struct policydb *p, char *str, struct context *context,
380 gfp_t gfp_mask) 358 gfp_t gfp_mask)
381{ 359{
382 char *tmpstr, *freestr; 360 char *tmpstr;
383 int rc; 361 int rc;
384 362
385 if (!p->mls_enabled) 363 if (!p->mls_enabled)
386 return -EINVAL; 364 return -EINVAL;
387 365
388 /* we need freestr because mls_context_to_sid will change 366 tmpstr = kstrdup(str, gfp_mask);
389 the value of tmpstr */
390 tmpstr = freestr = kstrdup(str, gfp_mask);
391 if (!tmpstr) { 367 if (!tmpstr) {
392 rc = -ENOMEM; 368 rc = -ENOMEM;
393 } else { 369 } else {
394 rc = mls_context_to_sid(p, ':', &tmpstr, context, 370 rc = mls_context_to_sid(p, ':', tmpstr, context,
395 NULL, SECSID_NULL); 371 NULL, SECSID_NULL);
396 kfree(freestr); 372 kfree(tmpstr);
397 } 373 }
398 374
399 return rc; 375 return rc;