Message ID | m1aax1uoa3.fsf_-_@fess.ebiederm.org |
---|---|
State | Not Applicable, archived |
Delegated to: | David Miller |
Headers | show |
On Tue, Dec 29, 2009 at 10:35 PM, Eric W. Biederman <ebiederm@xmission.com> wrote: > > If we can know that a process will never raise it's priveleges we can > enable a lot of features that otherwise would be unsafe, because they > could break assumptions of existing suid executables. > > To allow this to be used as a sand boxing feature also disable > ptracing other executables without this new restriction. > > For the moment I have used a per thread flag because we are out of per > process flags. > > To ensure all descendants get this flag I rely on the default copying > of procss structures. > > The disabling of suid executables is exactly the same as MNT_NOSUID. > > This should be what we have been talking about in for disabling of > suid exec. I choose not to use securebits as that interface requires > privilege and assumes capabilities. This implementation is more basic > than capabilities and only adds additional sanity checks when > linux capabilities are not present. > > I attempt to ensure there are no mixed priveleges present, when we > perform the disable so I don't need to handle or think about > interactions with setreuid or capabilities in this code. Is this sufficient for other security models such as selinux or TOMOYO? Can processes in these models gain privileges through means not restricted here? Also, perhaps there should be a corresponding GET prctl? -- To unsubscribe from this list: send the line "unsubscribe netdev" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Bryan Donlan <bdonlan@gmail.com> writes: > Is this sufficient for other security models such as selinux or > TOMOYO? Can processes in these models gain privileges through means > not restricted here? The LSM is primarily about returning -EPERM more often. Except for the prctl and the capability hooks I am not aware of anywhere a LSM can increase a processes capabilities. > Also, perhaps there should be a corresponding GET prctl? Probably for the final version. Eric -- To unsubscribe from this list: send the line "unsubscribe netdev" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
On Tue, Dec 29, 2009 at 11:33 PM, Eric W. Biederman <ebiederm@xmission.com> wrote: > Bryan Donlan <bdonlan@gmail.com> writes: > >> Is this sufficient for other security models such as selinux or >> TOMOYO? Can processes in these models gain privileges through means >> not restricted here? > > The LSM is primarily about returning -EPERM more often. > Except for the prctl and the capability hooks I am not aware > of anywhere a LSM can increase a processes capabilities. I'm more concerned about a case where a privilege that the LSM currently denies is lifted by execing some executable - this is still an increase in privilege, even though the LSM only adds additional restrictions. That is: 1) Initial state: LSM denies access to /somefile (although normal POSIX permissions would permit access) 2) Disable capability-gaining 3) Disable network access with proposed API 4) Exec some application, which is labeled in a way that permits access to /somefile 5) Application fails to access the network, then does something to /somefile I'm not entirely sure if step 4) can happen in any of the currently existing LSMs - if it's not possible to gain privileges in them via a suid-like mechanism, this isn't a problem, but it's something that needs to be checked for. -- To unsubscribe from this list: send the line "unsubscribe netdev" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Bryan Donlan <bdonlan@gmail.com> writes: > On Tue, Dec 29, 2009 at 11:33 PM, Eric W. Biederman > <ebiederm@xmission.com> wrote: >> Bryan Donlan <bdonlan@gmail.com> writes: >> >>> Is this sufficient for other security models such as selinux or >>> TOMOYO? Can processes in these models gain privileges through means >>> not restricted here? >> >> The LSM is primarily about returning -EPERM more often. >> Except for the prctl and the capability hooks I am not aware >> of anywhere a LSM can increase a processes capabilities. > > I'm more concerned about a case where a privilege that the LSM > currently denies is lifted by execing some executable - this is still > an increase in privilege, even though the LSM only adds additional > restrictions. That is: > > 1) Initial state: LSM denies access to /somefile (although normal > POSIX permissions would permit access) > 2) Disable capability-gaining > 3) Disable network access with proposed API > 4) Exec some application, which is labeled in a way that permits > access to /somefile > 5) Application fails to access the network, then does something to /somefile > > I'm not entirely sure if step 4) can happen in any of the currently > existing LSMs - if it's not possible to gain privileges in them via a > suid-like mechanism, this isn't a problem, but it's something that > needs to be checked for. A reasonable concern. When the glitches get worked out of this patch I intend to allow much more dangerous things like unprivileged unsharing of all of the namespaces, and unprivileged mounts. It appears I missed a place where MNT_NOSUID was handled in selinux. So I will be adding a bprm->nosuid field so I don't have to duplicate the MNT_NOSUID check everywhere it is used. I don't understand TOMOYO I think it is file based access control, which suggests there is not a suid like mechanism. Smack and selinux are label based. Selinux at least can switch labels on exec, but it handles NOSUID already. Looking a little farther if I assume that lsm implementations that implement the set_creds hook need attention. Only selinux has an interesting set_creds implementation and it handles nosuid already. So I think we are ok. Eric -- To unsubscribe from this list: send the line "unsubscribe netdev" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
diff --git a/arch/x86/include/asm/thread_info.h b/arch/x86/include/asm/thread_info.h index 375c917..e716203 100644 --- a/arch/x86/include/asm/thread_info.h +++ b/arch/x86/include/asm/thread_info.h @@ -82,6 +82,7 @@ struct thread_info { #define TIF_SYSCALL_EMU 6 /* syscall emulation active */ #define TIF_SYSCALL_AUDIT 7 /* syscall auditing active */ #define TIF_SECCOMP 8 /* secure computing */ +#define TIF_NOSUID 9 /* suid exec permanently disabled */ #define TIF_MCE_NOTIFY 10 /* notify userspace of an MCE */ #define TIF_USER_RETURN_NOTIFY 11 /* notify kernel of userspace return */ #define TIF_NOTSC 16 /* TSC is not accessible in userland */ @@ -107,6 +108,7 @@ struct thread_info { #define _TIF_SYSCALL_EMU (1 << TIF_SYSCALL_EMU) #define _TIF_SYSCALL_AUDIT (1 << TIF_SYSCALL_AUDIT) #define _TIF_SECCOMP (1 << TIF_SECCOMP) +#define _TIF_NOSUID (1 << TIF_NOSUID) #define _TIF_MCE_NOTIFY (1 << TIF_MCE_NOTIFY) #define _TIF_USER_RETURN_NOTIFY (1 << TIF_USER_RETURN_NOTIFY) #define _TIF_NOTSC (1 << TIF_NOTSC) diff --git a/fs/exec.c b/fs/exec.c index 632b02e..e6c9bc5 100644 --- a/fs/exec.c +++ b/fs/exec.c @@ -1132,7 +1132,8 @@ int prepare_binprm(struct linux_binprm *bprm) bprm->cred->euid = current_euid(); bprm->cred->egid = current_egid(); - if (!(bprm->file->f_path.mnt->mnt_flags & MNT_NOSUID)) { + if (!(bprm->file->f_path.mnt->mnt_flags & MNT_NOSUID) && + !test_tsk_thread_flag(current, TIF_NOSUID)) { /* Set-uid? */ if (mode & S_ISUID) { bprm->per_clear |= PER_CLEAR_ON_SETID; diff --git a/include/linux/prctl.h b/include/linux/prctl.h index a3baeb2..acb3516 100644 --- a/include/linux/prctl.h +++ b/include/linux/prctl.h @@ -102,4 +102,6 @@ #define PR_MCE_KILL_GET 34 +#define PR_SET_NOSUID 35 + #endif /* _LINUX_PRCTL_H */ diff --git a/kernel/ptrace.c b/kernel/ptrace.c index 23bd09c..4b2643c 100644 --- a/kernel/ptrace.c +++ b/kernel/ptrace.c @@ -152,6 +152,10 @@ int __ptrace_may_access(struct task_struct *task, unsigned int mode) if (!dumpable && !capable(CAP_SYS_PTRACE)) return -EPERM; + if (test_tsk_thread_flag(current, TIF_NOSUID) && + !test_tsk_thread_flag(current, TIF_NOSUID)) + return -EPERM; + return security_ptrace_access_check(task, mode); } diff --git a/kernel/sys.c b/kernel/sys.c index 26a6b73..1d1902a 100644 --- a/kernel/sys.c +++ b/kernel/sys.c @@ -1578,6 +1578,22 @@ SYSCALL_DEFINE5(prctl, int, option, unsigned long, arg2, unsigned long, arg3, else error = PR_MCE_KILL_DEFAULT; break; + case PR_SET_NOSUID: + { + const struct cred *cred = current->cred; + error = -EINVAL; + if ( (cred->uid != cred->suid) || + (cred->uid != cred->euid) || + (cred->uid != cred->fsuid) || + (cred->gid != cred->sgid) || + (cred->gid != cred->egid) || + (cred->gid != cred->fsgid) || + (atomic_read(¤t->signal->count) != 1)) + break; + error = 0; + set_tsk_thread_flag(current, TIF_NOSUID); + break; + } default: error = -EINVAL; break; diff --git a/security/commoncap.c b/security/commoncap.c index f800fdb..8abd3dc 100644 --- a/security/commoncap.c +++ b/security/commoncap.c @@ -392,6 +392,9 @@ static int get_file_caps(struct linux_binprm *bprm, bool *effective) if (bprm->file->f_vfsmnt->mnt_flags & MNT_NOSUID) return 0; + if (test_tsk_thread_flag(current, TIF_NOSUID)) + return 0; + dentry = dget(bprm->file->f_dentry); rc = get_vfs_caps_from_disk(dentry, &vcaps); @@ -869,6 +872,18 @@ int cap_task_prctl(int option, unsigned long arg2, unsigned long arg3, new->securebits &= ~issecure_mask(SECURE_KEEP_CAPS); goto changed; + case PR_SET_NOSUID: + { + const struct cred *cred = current->cred; + error = -EINVAL; + // Perform the capabilities checks + if (!cap_isclear(cred->cap_permitted) || + !cap_isclear(cred->cap_effective)) + goto error; + // Have the default perform the rest of the work. + error = -ENOSYS; + goto error; + } default: /* No functionality available - continue with default */ error = -ENOSYS;
If we can know that a process will never raise it's priveleges we can enable a lot of features that otherwise would be unsafe, because they could break assumptions of existing suid executables. To allow this to be used as a sand boxing feature also disable ptracing other executables without this new restriction. For the moment I have used a per thread flag because we are out of per process flags. To ensure all descendants get this flag I rely on the default copying of procss structures. The disabling of suid executables is exactly the same as MNT_NOSUID. This should be what we have been talking about in for disabling of suid exec. I choose not to use securebits as that interface requires privilege and assumes capabilities. This implementation is more basic than capabilities and only adds additional sanity checks when linux capabilities are not present. I attempt to ensure there are no mixed priveleges present, when we perform the disable so I don't need to handle or think about interactions with setreuid or capabilities in this code. Signed-off-by: Eric W. Biederman <ebiederm@xmission.com> --- arch/x86/include/asm/thread_info.h | 2 ++ fs/exec.c | 3 ++- include/linux/prctl.h | 2 ++ kernel/ptrace.c | 4 ++++ kernel/sys.c | 16 ++++++++++++++++ security/commoncap.c | 15 +++++++++++++++ 6 files changed, 41 insertions(+), 1 deletions(-)