diff options
Diffstat (limited to 'security/selinux/hooks.c')
-rw-r--r-- | security/selinux/hooks.c | 47 |
1 files changed, 32 insertions, 15 deletions
diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c index 00ad46e166f6..04b8e1082c9a 100644 --- a/security/selinux/hooks.c +++ b/security/selinux/hooks.c | |||
@@ -2318,6 +2318,7 @@ static int check_nnp_nosuid(const struct linux_binprm *bprm, | |||
2318 | int nnp = (bprm->unsafe & LSM_UNSAFE_NO_NEW_PRIVS); | 2318 | int nnp = (bprm->unsafe & LSM_UNSAFE_NO_NEW_PRIVS); |
2319 | int nosuid = !mnt_may_suid(bprm->file->f_path.mnt); | 2319 | int nosuid = !mnt_may_suid(bprm->file->f_path.mnt); |
2320 | int rc; | 2320 | int rc; |
2321 | u32 av; | ||
2321 | 2322 | ||
2322 | if (!nnp && !nosuid) | 2323 | if (!nnp && !nosuid) |
2323 | return 0; /* neither NNP nor nosuid */ | 2324 | return 0; /* neither NNP nor nosuid */ |
@@ -2326,24 +2327,40 @@ static int check_nnp_nosuid(const struct linux_binprm *bprm, | |||
2326 | return 0; /* No change in credentials */ | 2327 | return 0; /* No change in credentials */ |
2327 | 2328 | ||
2328 | /* | 2329 | /* |
2329 | * The only transitions we permit under NNP or nosuid | 2330 | * If the policy enables the nnp_nosuid_transition policy capability, |
2330 | * are transitions to bounded SIDs, i.e. SIDs that are | 2331 | * then we permit transitions under NNP or nosuid if the |
2331 | * guaranteed to only be allowed a subset of the permissions | 2332 | * policy allows the corresponding permission between |
2332 | * of the current SID. | 2333 | * the old and new contexts. |
2333 | */ | 2334 | */ |
2334 | rc = security_bounded_transition(old_tsec->sid, new_tsec->sid); | 2335 | if (selinux_policycap_nnp_nosuid_transition) { |
2335 | if (rc) { | 2336 | av = 0; |
2336 | /* | ||
2337 | * On failure, preserve the errno values for NNP vs nosuid. | ||
2338 | * NNP: Operation not permitted for caller. | ||
2339 | * nosuid: Permission denied to file. | ||
2340 | */ | ||
2341 | if (nnp) | 2337 | if (nnp) |
2342 | return -EPERM; | 2338 | av |= PROCESS2__NNP_TRANSITION; |
2343 | else | 2339 | if (nosuid) |
2344 | return -EACCES; | 2340 | av |= PROCESS2__NOSUID_TRANSITION; |
2341 | rc = avc_has_perm(old_tsec->sid, new_tsec->sid, | ||
2342 | SECCLASS_PROCESS2, av, NULL); | ||
2343 | if (!rc) | ||
2344 | return 0; | ||
2345 | } | 2345 | } |
2346 | return 0; | 2346 | |
2347 | /* | ||
2348 | * We also permit NNP or nosuid transitions to bounded SIDs, | ||
2349 | * i.e. SIDs that are guaranteed to only be allowed a subset | ||
2350 | * of the permissions of the current SID. | ||
2351 | */ | ||
2352 | rc = security_bounded_transition(old_tsec->sid, new_tsec->sid); | ||
2353 | if (!rc) | ||
2354 | return 0; | ||
2355 | |||
2356 | /* | ||
2357 | * On failure, preserve the errno values for NNP vs nosuid. | ||
2358 | * NNP: Operation not permitted for caller. | ||
2359 | * nosuid: Permission denied to file. | ||
2360 | */ | ||
2361 | if (nnp) | ||
2362 | return -EPERM; | ||
2363 | return -EACCES; | ||
2347 | } | 2364 | } |
2348 | 2365 | ||
2349 | static int selinux_bprm_set_creds(struct linux_binprm *bprm) | 2366 | static int selinux_bprm_set_creds(struct linux_binprm *bprm) |