On Mon, Aug 4, 2014 at 10:36 AM, Stephen Smalley <sds@xxxxxxxxxxxxx> wrote: > If the callee SID is bounded by the caller SID, then allowing > the transition to occur poses no risk of privilege escalation and we can > therefore safely allow the transition to occur. Add this exemption > for both the case where a transition was explicitly requested by the > application and the case where an automatic transition is defined in > policy. This still wants something like security_bounded_transition_noaudit, right? (Or just a parameter about whether to audit -- there will only be two callers, I think.) --Andy > > Signed-off-by: Stephen Smalley <sds@xxxxxxxxxxxxx> > --- > security/selinux/hooks.c | 59 ++++++++++++++++++++++++++++++++++++++---------- > 1 file changed, 47 insertions(+), 12 deletions(-) > > diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c > index 83d06db..d96c91a 100644 > --- a/security/selinux/hooks.c > +++ b/security/selinux/hooks.c > @@ -2086,6 +2086,41 @@ static int selinux_vm_enough_memory(struct mm_struct *mm, long pages) > > /* binprm security operations */ > > +static int check_nnp_nosuid(const struct linux_binprm *bprm, > + const struct task_security_struct *old_tsec, > + const struct task_security_struct *new_tsec) > +{ > + int nnp = (bprm->unsafe & LSM_UNSAFE_NO_NEW_PRIVS); > + int nosuid = (bprm->file->f_path.mnt->mnt_flags & MNT_NOSUID); > + int rc; > + > + if (!nnp && !nosuid) > + return 0; /* neither NNP nor nosuid */ > + > + if (new_tsec->sid == old_tsec->sid) > + return 0; /* No change in credentials */ > + > + /* > + * The only transitions we permit under NNP or nosuid > + * are transitions to bounded SIDs, i.e. SIDs that are > + * guaranteed to only be allowed a subset of the permissions > + * of the current SID. > + */ > + rc = security_bounded_transition(old_tsec->sid, new_tsec->sid); > + if (rc) { > + /* > + * On failure, preserve the errno values for NNP vs nosuid. > + * NNP: Operation not permitted for caller. > + * nosuid: Permission denied to file. > + */ > + if (nnp) > + return -EPERM; > + else > + return -EACCES; > + } > + return 0; > +} > + > static int selinux_bprm_set_creds(struct linux_binprm *bprm) > { > const struct task_security_struct *old_tsec; > @@ -2122,14 +2157,10 @@ static int selinux_bprm_set_creds(struct linux_binprm *bprm) > /* Reset exec SID on execve. */ > new_tsec->exec_sid = 0; > > - /* > - * Minimize confusion: if no_new_privs or nosuid and a > - * transition is explicitly requested, then fail the exec. > - */ > - if (bprm->unsafe & LSM_UNSAFE_NO_NEW_PRIVS) > - return -EPERM; > - if (bprm->file->f_path.mnt->mnt_flags & MNT_NOSUID) > - return -EACCES; > + /* Fail on NNP or nosuid if not an allowed transition. */ > + rc = check_nnp_nosuid(bprm, old_tsec, new_tsec); > + if (rc) > + return rc; > } else { > /* Check for a default transition on this program. */ > rc = security_transition_sid(old_tsec->sid, isec->sid, > @@ -2137,15 +2168,19 @@ static int selinux_bprm_set_creds(struct linux_binprm *bprm) > &new_tsec->sid); > if (rc) > return rc; > + > + /* > + * Fallback to old SID on NNP or nosuid if not an allowed > + * transition. > + */ > + rc = check_nnp_nosuid(bprm, old_tsec, new_tsec); > + if (rc) > + new_tsec->sid = old_tsec->sid; > } > > ad.type = LSM_AUDIT_DATA_PATH; > ad.u.path = bprm->file->f_path; > > - if ((bprm->file->f_path.mnt->mnt_flags & MNT_NOSUID) || > - (bprm->unsafe & LSM_UNSAFE_NO_NEW_PRIVS)) > - new_tsec->sid = old_tsec->sid; > - > if (new_tsec->sid == old_tsec->sid) { > rc = avc_has_perm(old_tsec->sid, isec->sid, > SECCLASS_FILE, FILE__EXECUTE_NO_TRANS, &ad); > -- > 1.8.3.1 > -- Andy Lutomirski AMA Capital Management, LLC _______________________________________________ Selinux mailing list Selinux@xxxxxxxxxxxxx To unsubscribe, send email to Selinux-leave@xxxxxxxxxxxxx. To get help, send an email containing "help" to Selinux-request@xxxxxxxxxxxxx.