diff options
-rw-r--r-- | sys/compat/linux/linux_file.c | 24 | ||||
-rw-r--r-- | sys/compat/linux/linux_misc.c | 203 | ||||
-rw-r--r-- | sys/compat/linux/syscalls.master | 38 |
3 files changed, 261 insertions, 4 deletions
diff --git a/sys/compat/linux/linux_file.c b/sys/compat/linux/linux_file.c index 355e1265e89..3761ad27c97 100644 --- a/sys/compat/linux/linux_file.c +++ b/sys/compat/linux/linux_file.c @@ -1,4 +1,4 @@ -/* $OpenBSD: linux_file.c,v 1.9 1997/11/13 06:37:48 deraadt Exp $ */ +/* $OpenBSD: linux_file.c,v 1.10 2000/02/28 13:29:29 jasoni Exp $ */ /* $NetBSD: linux_file.c,v 1.15 1996/05/20 01:59:09 fvdl Exp $ */ /* @@ -710,6 +710,28 @@ linux_sys_fchown(p, v, retval) } int +linux_sys_lchown(p, v, retval) + struct proc *p; + void *v; + register_t *retval; +{ + struct linux_sys_lchown_args /* { + syscallarg(char *) path; + syscallarg(int) uid; + syscallarg(int) gid; + } */ *uap = v; + struct sys_lchown_args bla; + + SCARG(&bla, path) = SCARG(uap, path); + SCARG(&bla, uid) = ((linux_uid_t)SCARG(uap, uid) == (linux_uid_t)-1) ? + (uid_t)-1 : SCARG(uap, uid); + SCARG(&bla, gid) = ((linux_gid_t)SCARG(uap, gid) == (linux_gid_t)-1) ? + (gid_t)-1 : SCARG(uap, gid); + + return sys_lchown(p, &bla, retval); +} + +int linux_sys_rename(p, v, retval) struct proc *p; void *v; diff --git a/sys/compat/linux/linux_misc.c b/sys/compat/linux/linux_misc.c index 599be904272..3f1653cd7b8 100644 --- a/sys/compat/linux/linux_misc.c +++ b/sys/compat/linux/linux_misc.c @@ -1,4 +1,4 @@ -/* $OpenBSD: linux_misc.c,v 1.25 1999/12/06 19:36:41 aaron Exp $ */ +/* $OpenBSD: linux_misc.c,v 1.26 2000/02/28 13:29:30 jasoni Exp $ */ /* $NetBSD: linux_misc.c,v 1.27 1996/05/20 01:59:21 fvdl Exp $ */ /* @@ -194,6 +194,105 @@ linux_sys_wait4(p, v, retval) return 0; } +int +linux_sys_setresgid(p, v, retval) + struct proc *p; + void *v; + register_t *retval; +{ + struct linux_sys_setresgid_args /* { + syscallarg(gid_t) rgid; + syscallarg(gid_t) egid; + syscallarg(gid_t) sgid; + } */ *uap = v; + struct pcred *pc = p->p_cred; + gid_t rgid, egid, sgid; + int error; + + rgid = SCARG(uap, rgid); + egid = SCARG(uap, egid); + sgid = SCARG(uap, sgid); + + /* + * Note: These checks are a little different than the NetBSD + * setregid(2) call performs. This precisely follows the + * behavior of the Linux kernel. + */ + if (rgid != (gid_t)-1 && + rgid != pc->p_rgid && + rgid != pc->pc_ucred->cr_gid && + rgid != pc->p_svgid && + (error = suser(pc->pc_ucred, &p->p_acflag))) + return (error); + + if (egid != (gid_t)-1 && + egid != pc->p_rgid && + egid != pc->pc_ucred->cr_gid && + egid != pc->p_svgid && + (error = suser(pc->pc_ucred, &p->p_acflag))) + return (error); + + if (sgid != (gid_t)-1 && + sgid != pc->p_rgid && + sgid != pc->pc_ucred->cr_gid && + sgid != pc->p_svgid && + (error = suser(pc->pc_ucred, &p->p_acflag))) + return (error); + + /* + * Now assign the real, effective, and saved GIDs. + * Note that Linux, unlike NetBSD in setregid(2), does not + * set the saved UID in this call unless the user specifies + * it. + */ + if (rgid != (gid_t)-1) + pc->p_rgid = rgid; + + if (egid != (gid_t)-1) { + pc->pc_ucred = crcopy(pc->pc_ucred); + pc->pc_ucred->cr_gid = egid; + } + + if (sgid != (gid_t)-1) + pc->p_svgid = sgid; + + if (rgid != (gid_t)-1 && egid != (gid_t)-1 && sgid != (gid_t)-1) + p->p_flag |= P_SUGID; + return (0); +} + +int +linux_sys_getresgid(p, v, retval) + struct proc *p; + void *v; + register_t *retval; +{ + struct linux_sys_getresgid_args /* { + syscallarg(gid_t *) rgid; + syscallarg(gid_t *) egid; + syscallarg(gid_t *) sgid; + } */ *uap = v; + struct pcred *pc = p->p_cred; + int error; + + /* + * Linux copies these values out to userspace like so: + * + * 1. Copy out rgid. + * 2. If that succeeds, copy out egid. + * 3. If both of those succeed, copy out sgid. + */ + if ((error = copyout(&pc->p_rgid, SCARG(uap, rgid), + sizeof(gid_t))) != 0) + return (error); + + if ((error = copyout(&pc->pc_ucred->cr_uid, SCARG(uap, egid), + sizeof(gid_t))) != 0) + return (error); + + return (copyout(&pc->p_svgid, SCARG(uap, sgid), sizeof(gid_t))); +} + /* * This is the old brk(2) call. I don't think anything in the Linux * world uses this anymore @@ -1240,6 +1339,108 @@ linux_sys___sysctl(p, v, retval) } int +linux_sys_setresuid(p, v, retval) + struct proc *p; + void *v; + register_t *retval; +{ + struct linux_sys_setresuid_args /* { + syscallarg(uid_t) ruid; + syscallarg(uid_t) euid; + syscallarg(uid_t) suid; + } */ *uap = v; + struct pcred *pc = p->p_cred; + uid_t ruid, euid, suid; + int error; + + ruid = SCARG(uap, ruid); + euid = SCARG(uap, euid); + suid = SCARG(uap, suid); + + /* + * Note: These checks are a little different than the NetBSD + * setreuid(2) call performs. This precisely follows the + * behavior of the Linux kernel. + */ + if (ruid != (uid_t)-1 && + ruid != pc->p_ruid && + ruid != pc->pc_ucred->cr_uid && + ruid != pc->p_svuid && + (error = suser(pc->pc_ucred, &p->p_acflag))) + return (error); + + if (euid != (uid_t)-1 && + euid != pc->p_ruid && + euid != pc->pc_ucred->cr_uid && + euid != pc->p_svuid && + (error = suser(pc->pc_ucred, &p->p_acflag))) + return (error); + + if (suid != (uid_t)-1 && + suid != pc->p_ruid && + suid != pc->pc_ucred->cr_uid && + suid != pc->p_svuid && + (error = suser(pc->pc_ucred, &p->p_acflag))) + return (error); + + /* + * Now assign the new real, effective, and saved UIDs. + * Note that Linux, unlike NetBSD in setreuid(2), does not + * set the saved UID in this call unless the user specifies + * it. + */ + if (ruid != (uid_t)-1) { + (void)chgproccnt(pc->p_ruid, -1); + (void)chgproccnt(ruid, 1); + pc->p_ruid = ruid; + } + + if (euid != (uid_t)-1) { + pc->pc_ucred = crcopy(pc->pc_ucred); + pc->pc_ucred->cr_uid = euid; + } + + if (suid != (uid_t)-1) + pc->p_svuid = suid; + + if (ruid != (uid_t)-1 && euid != (uid_t)-1 && suid != (uid_t)-1) + p->p_flag |= P_SUGID; + return (0); +} + +int +linux_sys_getresuid(p, v, retval) + struct proc *p; + void *v; + register_t *retval; +{ + struct linux_sys_getresuid_args /* { + syscallarg(uid_t *) ruid; + syscallarg(uid_t *) euid; + syscallarg(uid_t *) suid; + } */ *uap = v; + struct pcred *pc = p->p_cred; + int error; + + /* + * Linux copies these values out to userspace like so: + * + * 1. Copy out ruid. + * 2. If that succeeds, copy out euid. + * 3. If both of those succeed, copy out suid. + */ + if ((error = copyout(&pc->p_ruid, SCARG(uap, ruid), + sizeof(uid_t))) != 0) + return (error); + + if ((error = copyout(&pc->pc_ucred->cr_uid, SCARG(uap, euid), + sizeof(uid_t))) != 0) + return (error); + + return (copyout(&pc->p_svuid, SCARG(uap, suid), sizeof(uid_t))); +} + +int linux_sys_nice(p, v, retval) struct proc *p; void *v; diff --git a/sys/compat/linux/syscalls.master b/sys/compat/linux/syscalls.master index a39816ed466..6a13b6dfe19 100644 --- a/sys/compat/linux/syscalls.master +++ b/sys/compat/linux/syscalls.master @@ -1,4 +1,4 @@ - $OpenBSD: syscalls.master,v 1.14 1999/12/06 19:36:42 aaron Exp $ + $OpenBSD: syscalls.master,v 1.15 2000/02/28 13:29:30 jasoni Exp $ ; $NetBSD: syscalls.master,v 1.15 1995/12/18 14:35:10 fvdl Exp $ ; @(#)syscalls.master 8.1 (Berkeley) 7/19/93 @@ -62,7 +62,7 @@ 13 STD { int linux_sys_time(linux_time_t *t); } 14 STD { int linux_sys_mknod(char *path, int mode, int dev); } 15 STD { int linux_sys_chmod(char *path, int mode); } -16 STD { int linux_sys_chown(char *path, int uid, int gid); } +16 STD { int linux_sys_lchown(char *path, int uid, int gid); } 17 STD { int linux_sys_break(char *nsize); } 18 OBSOL ostat 19 NOARGS { long compat_43_sys_lseek(int fd, long offset, \ @@ -259,3 +259,37 @@ struct timespec *rmtp); } 163 STD { int linux_sys_mremap(void *old_address, size_t old_size, \ size_t new_size, long flags); } +164 STD { int linux_sys_setresuid(uid_t ruid, uid_t euid, \ + uid_t suid); } +165 STD { int linux_sys_getresuid(uid_t *ruid, uid_t *euid, \ + uid_t *suid); } +166 UNIMPL vm86 +167 UNIMPL query_module +168 NOARGS { int sys_poll(struct pollfd *fds, u_int nfds, \ + int timeout); } +169 UNIMPL nfsservctl +;170 UNIMPL setresgid +;171 UNIMPL getresgid +170 STD { int linux_sys_setresgid(gid_t rgid, gid_t egid, \ + gid_t sgid); } +171 STD { int linux_sys_getresgid(gid_t *rgid, gid_t *egid, \ + gid_t *sgid); } +172 UNIMPL prctl +173 UNIMPL rt_sigreturn +174 UNIMPL rt_sigaction +175 UNIMPL rt_sigprocmask +176 UNIMPL rt_sigpending +177 UNIMPL rt_sigtimedwait +178 UNIMPL rt_queueinfo +179 UNIMPL rt_sigsuspend +180 UNIMPL pread +181 UNIMPL pwrite +182 STD { int linux_sys_chown(char *path, int uid, int gid); } +183 UNIMPL getcwd +184 UNIMPL capget +185 UNIMPL capset +186 UNIMPL sigaltstack +187 UNIMPL sendfile +188 UNIMPL getpmsg +189 UNIMPL putpmsg +190 UNIMPL vfork |