aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--security/selinux/hooks.c5
-rw-r--r--security/selinux/ss/mls.c178
-rw-r--r--security/selinux/ss/mls.h2
-rw-r--r--security/selinux/ss/policydb.c2
-rw-r--r--security/selinux/ss/services.c12
5 files changed, 88 insertions, 111 deletions
diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c
index 1b500b4c78a7..1b73a3f966c8 100644
--- a/security/selinux/hooks.c
+++ b/security/selinux/hooks.c
@@ -1508,6 +1508,11 @@ static int selinux_genfs_get_sid(struct dentry *dentry,
1508 } 1508 }
1509 rc = security_genfs_sid(&selinux_state, sb->s_type->name, 1509 rc = security_genfs_sid(&selinux_state, sb->s_type->name,
1510 path, tclass, sid); 1510 path, tclass, sid);
1511 if (rc == -ENOENT) {
1512 /* No match in policy, mark as unlabeled. */
1513 *sid = SECINITSID_UNLABELED;
1514 rc = 0;
1515 }
1511 } 1516 }
1512 free_page((unsigned long)buffer); 1517 free_page((unsigned long)buffer);
1513 return rc; 1518 return rc;
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;
diff --git a/security/selinux/ss/mls.h b/security/selinux/ss/mls.h
index 9a3ff7af70ad..67093647576d 100644
--- a/security/selinux/ss/mls.h
+++ b/security/selinux/ss/mls.h
@@ -34,7 +34,7 @@ int mls_level_isvalid(struct policydb *p, struct mls_level *l);
34 34
35int mls_context_to_sid(struct policydb *p, 35int mls_context_to_sid(struct policydb *p,
36 char oldc, 36 char oldc,
37 char **scontext, 37 char *scontext,
38 struct context *context, 38 struct context *context,
39 struct sidtab *s, 39 struct sidtab *s,
40 u32 def_sid); 40 u32 def_sid);
diff --git a/security/selinux/ss/policydb.c b/security/selinux/ss/policydb.c
index e9394e7adc84..f4eadd3f7350 100644
--- a/security/selinux/ss/policydb.c
+++ b/security/selinux/ss/policydb.c
@@ -1101,7 +1101,7 @@ static int str_read(char **strp, gfp_t flags, void *fp, u32 len)
1101 if ((len == 0) || (len == (u32)-1)) 1101 if ((len == 0) || (len == (u32)-1))
1102 return -EINVAL; 1102 return -EINVAL;
1103 1103
1104 str = kmalloc(len + 1, flags); 1104 str = kmalloc(len + 1, flags | __GFP_NOWARN);
1105 if (!str) 1105 if (!str)
1106 return -ENOMEM; 1106 return -ENOMEM;
1107 1107
diff --git a/security/selinux/ss/services.c b/security/selinux/ss/services.c
index f3def298a90e..12e414394530 100644
--- a/security/selinux/ss/services.c
+++ b/security/selinux/ss/services.c
@@ -1365,7 +1365,6 @@ int security_sid_to_context_force(struct selinux_state *state, u32 sid,
1365static int string_to_context_struct(struct policydb *pol, 1365static int string_to_context_struct(struct policydb *pol,
1366 struct sidtab *sidtabp, 1366 struct sidtab *sidtabp,
1367 char *scontext, 1367 char *scontext,
1368 u32 scontext_len,
1369 struct context *ctx, 1368 struct context *ctx,
1370 u32 def_sid) 1369 u32 def_sid)
1371{ 1370{
@@ -1426,15 +1425,12 @@ static int string_to_context_struct(struct policydb *pol,
1426 1425
1427 ctx->type = typdatum->value; 1426 ctx->type = typdatum->value;
1428 1427
1429 rc = mls_context_to_sid(pol, oldc, &p, ctx, sidtabp, def_sid); 1428 rc = mls_context_to_sid(pol, oldc, p, ctx, sidtabp, def_sid);
1430 if (rc) 1429 if (rc)
1431 goto out; 1430 goto out;
1432 1431
1433 rc = -EINVAL;
1434 if ((p - scontext) < scontext_len)
1435 goto out;
1436
1437 /* Check the validity of the new context. */ 1432 /* Check the validity of the new context. */
1433 rc = -EINVAL;
1438 if (!policydb_context_isvalid(pol, ctx)) 1434 if (!policydb_context_isvalid(pol, ctx))
1439 goto out; 1435 goto out;
1440 rc = 0; 1436 rc = 0;
@@ -1489,7 +1485,7 @@ static int security_context_to_sid_core(struct selinux_state *state,
1489 policydb = &state->ss->policydb; 1485 policydb = &state->ss->policydb;
1490 sidtab = &state->ss->sidtab; 1486 sidtab = &state->ss->sidtab;
1491 rc = string_to_context_struct(policydb, sidtab, scontext2, 1487 rc = string_to_context_struct(policydb, sidtab, scontext2,
1492 scontext_len, &context, def_sid); 1488 &context, def_sid);
1493 if (rc == -EINVAL && force) { 1489 if (rc == -EINVAL && force) {
1494 context.str = str; 1490 context.str = str;
1495 context.len = strlen(str) + 1; 1491 context.len = strlen(str) + 1;
@@ -1958,7 +1954,7 @@ static int convert_context(u32 key,
1958 goto out; 1954 goto out;
1959 1955
1960 rc = string_to_context_struct(args->newp, NULL, s, 1956 rc = string_to_context_struct(args->newp, NULL, s,
1961 c->len, &ctx, SECSID_NULL); 1957 &ctx, SECSID_NULL);
1962 kfree(s); 1958 kfree(s);
1963 if (!rc) { 1959 if (!rc) {
1964 pr_info("SELinux: Context %s became valid (mapped).\n", 1960 pr_info("SELinux: Context %s became valid (mapped).\n",