version 1.183, 2007/07/17 17:42:08 |
version 1.183.8.4, 2008/03/23 02:04:32 |
|
|
/* $NetBSD$ */ |
/* linux_misc.c,v 1.183.8.3 2008/01/09 01:51:12 matt Exp */ |
|
|
/*- |
/*- |
* Copyright (c) 1995, 1998, 1999 The NetBSD Foundation, Inc. |
* Copyright (c) 1995, 1998, 1999 The NetBSD Foundation, Inc. |
|
|
*/ |
*/ |
|
|
#include <sys/cdefs.h> |
#include <sys/cdefs.h> |
__KERNEL_RCSID(0, "$NetBSD$"); |
__KERNEL_RCSID(0, "linux_misc.c,v 1.183.8.3 2008/01/09 01:51:12 matt Exp"); |
|
|
#if defined(_KERNEL_OPT) |
#if defined(_KERNEL_OPT) |
#include "opt_ptrace.h" |
#include "opt_ptrace.h" |
Line 113 __KERNEL_RCSID(0, "$NetBSD$"); |
|
Line 113 __KERNEL_RCSID(0, "$NetBSD$"); |
|
#include <compat/linux/common/linux_machdep.h> |
#include <compat/linux/common/linux_machdep.h> |
#include <compat/linux/common/linux_types.h> |
#include <compat/linux/common/linux_types.h> |
#include <compat/linux/common/linux_signal.h> |
#include <compat/linux/common/linux_signal.h> |
|
#include <compat/linux/common/linux_ipc.h> |
|
#include <compat/linux/common/linux_sem.h> |
|
|
#include <compat/linux/linux_syscallargs.h> |
#include <compat/linux/linux_syscallargs.h> |
|
|
Line 182 const int linux_fstypes_cnt = sizeof(lin |
|
Line 184 const int linux_fstypes_cnt = sizeof(lin |
|
# endif |
# endif |
|
|
/* Local linux_misc.c functions: */ |
/* Local linux_misc.c functions: */ |
static void linux_to_bsd_mmap_args __P((struct sys_mmap_args *, |
static void linux_to_bsd_mmap_args(struct sys_mmap_args *, |
const struct linux_sys_mmap_args *)); |
const struct linux_sys_mmap_args *); |
static int linux_mmap __P((struct lwp *, struct linux_sys_mmap_args *, |
static int linux_mmap(struct lwp *, const struct linux_sys_mmap_args *, |
register_t *, off_t)); |
register_t *, off_t); |
|
|
|
|
/* |
/* |
Line 218 bsd_to_linux_wstat(int st) |
|
Line 220 bsd_to_linux_wstat(int st) |
|
* it to what Linux wants. |
* it to what Linux wants. |
*/ |
*/ |
int |
int |
linux_sys_wait4(l, v, retval) |
linux_sys_wait4(struct lwp *l, const struct linux_sys_wait4_args *uap, register_t *retval) |
struct lwp *l; |
|
void *v; |
|
register_t *retval; |
|
{ |
{ |
struct linux_sys_wait4_args /* { |
/* { |
syscallarg(int) pid; |
syscallarg(int) pid; |
syscallarg(int *) status; |
syscallarg(int *) status; |
syscallarg(int) options; |
syscallarg(int) options; |
syscallarg(struct rusage *) rusage; |
syscallarg(struct rusage *) rusage; |
} */ *uap = v; |
} */ |
int error, status, options, linux_options, was_zombie; |
int error, status, options, linux_options, was_zombie; |
struct rusage ru; |
struct rusage ru; |
|
int pid = SCARG(uap, pid); |
|
|
linux_options = SCARG(uap, options); |
linux_options = SCARG(uap, options); |
options = WOPTSCHECKED; |
options = WOPTSCHECKED; |
Line 253 linux_sys_wait4(l, v, retval) |
|
Line 253 linux_sys_wait4(l, v, retval) |
|
|
|
# endif |
# endif |
|
|
error = do_sys_wait(l, &SCARG(uap, pid), &status, options, |
error = do_sys_wait(l, &pid, &status, options, |
SCARG(uap, rusage) != NULL ? &ru : NULL, &was_zombie); |
SCARG(uap, rusage) != NULL ? &ru : NULL, &was_zombie); |
|
|
retval[0] = SCARG(uap, pid); |
retval[0] = pid; |
if (SCARG(uap, pid) == 0) |
if (pid == 0) |
return error; |
return error; |
|
|
sigdelset(&l->l_proc->p_sigpend.sp_set, SIGCHLD); /* XXXAD ksiginfo leak */ |
sigdelset(&l->l_proc->p_sigpend.sp_set, SIGCHLD); /* XXXAD ksiginfo leak */ |
Line 278 linux_sys_wait4(l, v, retval) |
|
Line 278 linux_sys_wait4(l, v, retval) |
|
* done in the kernel in Linux. NetBSD does it in the library. |
* done in the kernel in Linux. NetBSD does it in the library. |
*/ |
*/ |
int |
int |
linux_sys_brk(l, v, retval) |
linux_sys_brk(struct lwp *l, const struct linux_sys_brk_args *uap, register_t *retval) |
struct lwp *l; |
|
void *v; |
|
register_t *retval; |
|
{ |
{ |
struct linux_sys_brk_args /* { |
/* { |
syscallarg(char *) nsize; |
syscallarg(char *) nsize; |
} */ *uap = v; |
} */ |
struct proc *p = l->l_proc; |
struct proc *p = l->l_proc; |
char *nbrk = SCARG(uap, nsize); |
char *nbrk = SCARG(uap, nsize); |
struct sys_obreak_args oba; |
struct sys_obreak_args oba; |
Line 308 linux_sys_brk(l, v, retval) |
|
Line 305 linux_sys_brk(l, v, retval) |
|
* Implement the fs stat functions. Straightforward. |
* Implement the fs stat functions. Straightforward. |
*/ |
*/ |
int |
int |
linux_sys_statfs(l, v, retval) |
linux_sys_statfs(struct lwp *l, const struct linux_sys_statfs_args *uap, register_t *retval) |
struct lwp *l; |
|
void *v; |
|
register_t *retval; |
|
{ |
{ |
struct linux_sys_statfs_args /* { |
/* { |
syscallarg(const char *) path; |
syscallarg(const char *) path; |
syscallarg(struct linux_statfs *) sp; |
syscallarg(struct linux_statfs *) sp; |
} */ *uap = v; |
} */ |
struct statvfs *sb; |
struct statvfs *sb; |
struct linux_statfs ltmp; |
struct linux_statfs ltmp; |
int error; |
int error; |
Line 333 linux_sys_statfs(l, v, retval) |
|
Line 327 linux_sys_statfs(l, v, retval) |
|
} |
} |
|
|
int |
int |
linux_sys_fstatfs(l, v, retval) |
linux_sys_fstatfs(struct lwp *l, const struct linux_sys_fstatfs_args *uap, register_t *retval) |
struct lwp *l; |
|
void *v; |
|
register_t *retval; |
|
{ |
{ |
struct linux_sys_fstatfs_args /* { |
/* { |
syscallarg(int) fd; |
syscallarg(int) fd; |
syscallarg(struct linux_statfs *) sp; |
syscallarg(struct linux_statfs *) sp; |
} */ *uap = v; |
} */ |
struct statvfs *sb; |
struct statvfs *sb; |
struct linux_statfs ltmp; |
struct linux_statfs ltmp; |
int error; |
int error; |
Line 364 linux_sys_fstatfs(l, v, retval) |
|
Line 355 linux_sys_fstatfs(l, v, retval) |
|
* long, and an extra domainname field. |
* long, and an extra domainname field. |
*/ |
*/ |
int |
int |
linux_sys_uname(struct lwp *l, void *v, register_t *retval) |
linux_sys_uname(struct lwp *l, const struct linux_sys_uname_args *uap, register_t *retval) |
{ |
{ |
struct linux_sys_uname_args /* { |
/* { |
syscallarg(struct linux_utsname *) up; |
syscallarg(struct linux_utsname *) up; |
} */ *uap = v; |
} */ |
struct linux_utsname luts; |
struct linux_utsname luts; |
|
|
strncpy(luts.l_sysname, linux_sysname, sizeof(luts.l_sysname)); |
strlcpy(luts.l_sysname, linux_sysname, sizeof(luts.l_sysname)); |
strncpy(luts.l_nodename, hostname, sizeof(luts.l_nodename)); |
strlcpy(luts.l_nodename, hostname, sizeof(luts.l_nodename)); |
strncpy(luts.l_release, linux_release, sizeof(luts.l_release)); |
strlcpy(luts.l_release, linux_release, sizeof(luts.l_release)); |
strncpy(luts.l_version, linux_version, sizeof(luts.l_version)); |
strlcpy(luts.l_version, linux_version, sizeof(luts.l_version)); |
strncpy(luts.l_machine, LINUX_UNAME_ARCH, sizeof(luts.l_machine)); |
strlcpy(luts.l_machine, LINUX_UNAME_ARCH, sizeof(luts.l_machine)); |
strncpy(luts.l_domainname, domainname, sizeof(luts.l_domainname)); |
strlcpy(luts.l_domainname, domainname, sizeof(luts.l_domainname)); |
|
|
return copyout(&luts, SCARG(uap, up), sizeof(luts)); |
return copyout(&luts, SCARG(uap, up), sizeof(luts)); |
} |
} |
Line 389 linux_sys_uname(struct lwp *l, void *v, |
|
Line 380 linux_sys_uname(struct lwp *l, void *v, |
|
* Only called directly on machines with >= 6 free regs. |
* Only called directly on machines with >= 6 free regs. |
*/ |
*/ |
int |
int |
linux_sys_mmap(l, v, retval) |
linux_sys_mmap(struct lwp *l, const struct linux_sys_mmap_args *uap, register_t *retval) |
struct lwp *l; |
|
void *v; |
|
register_t *retval; |
|
{ |
{ |
struct linux_sys_mmap_args /* { |
/* { |
syscallarg(unsigned long) addr; |
syscallarg(unsigned long) addr; |
syscallarg(size_t) len; |
syscallarg(size_t) len; |
syscallarg(int) prot; |
syscallarg(int) prot; |
syscallarg(int) flags; |
syscallarg(int) flags; |
syscallarg(int) fd; |
syscallarg(int) fd; |
syscallarg(linux_off_t) offset; |
syscallarg(linux_off_t) offset; |
} */ *uap = v; |
} */ |
|
|
if (SCARG(uap, offset) & PAGE_MASK) |
if (SCARG(uap, offset) & PAGE_MASK) |
return EINVAL; |
return EINVAL; |
Line 419 linux_sys_mmap(l, v, retval) |
|
Line 407 linux_sys_mmap(l, v, retval) |
|
* point, and the actual syscall. |
* point, and the actual syscall. |
*/ |
*/ |
int |
int |
linux_sys_mmap2(l, v, retval) |
linux_sys_mmap2(struct lwp *l, const struct linux_sys_mmap2_args *uap, register_t *retval) |
struct lwp *l; |
|
void *v; |
|
register_t *retval; |
|
{ |
{ |
struct linux_sys_mmap2_args /* { |
/* { |
syscallarg(unsigned long) addr; |
syscallarg(unsigned long) addr; |
syscallarg(size_t) len; |
syscallarg(size_t) len; |
syscallarg(int) prot; |
syscallarg(int) prot; |
syscallarg(int) flags; |
syscallarg(int) flags; |
syscallarg(int) fd; |
syscallarg(int) fd; |
syscallarg(linux_off_t) offset; |
syscallarg(linux_off_t) offset; |
} */ *uap = v; |
} */ |
|
|
return linux_mmap(l, uap, retval, |
return linux_mmap(l, uap, retval, |
((off_t)SCARG(uap, offset)) << PAGE_SHIFT); |
((off_t)SCARG(uap, offset)) << PAGE_SHIFT); |
Line 441 linux_sys_mmap2(l, v, retval) |
|
Line 426 linux_sys_mmap2(l, v, retval) |
|
* Massage arguments and call system mmap(2). |
* Massage arguments and call system mmap(2). |
*/ |
*/ |
static int |
static int |
linux_mmap(l, uap, retval, offset) |
linux_mmap(struct lwp *l, const struct linux_sys_mmap_args *uap, register_t *retval, off_t offset) |
struct lwp *l; |
|
struct linux_sys_mmap_args *uap; |
|
register_t *retval; |
|
off_t offset; |
|
{ |
{ |
struct sys_mmap_args cma; |
struct sys_mmap_args cma; |
int error; |
int error; |
size_t mmoff=0; |
size_t mmoff=0; |
|
|
|
linux_to_bsd_mmap_args(&cma, uap); |
|
SCARG(&cma, pos) = offset; |
|
|
if (SCARG(uap, flags) & LINUX_MAP_GROWSDOWN) { |
if (SCARG(uap, flags) & LINUX_MAP_GROWSDOWN) { |
/* |
/* |
* Request for stack-like memory segment. On linux, this |
* Request for stack-like memory segment. On linux, this |
Line 464 linux_mmap(l, uap, retval, offset) |
|
Line 448 linux_mmap(l, uap, retval, offset) |
|
*/ |
*/ |
rlim_t ssl = l->l_proc->p_rlimit[RLIMIT_STACK].rlim_cur; |
rlim_t ssl = l->l_proc->p_rlimit[RLIMIT_STACK].rlim_cur; |
|
|
if (SCARG(uap, len) < ssl) { |
if (SCARG(&cma, len) < ssl) { |
/* Compute the address offset */ |
/* Compute the address offset */ |
mmoff = round_page(ssl) - SCARG(uap, len); |
mmoff = round_page(ssl) - SCARG(uap, len); |
|
|
if (SCARG(uap, addr)) |
if (SCARG(&cma, addr)) |
SCARG(uap, addr) -= mmoff; |
SCARG(&cma, addr) = (char *)SCARG(&cma, addr) - mmoff; |
|
|
SCARG(uap, len) = (size_t) ssl; |
SCARG(&cma, len) = (size_t) ssl; |
} |
} |
} |
} |
|
|
linux_to_bsd_mmap_args(&cma, uap); |
|
SCARG(&cma, pos) = offset; |
|
|
|
error = sys_mmap(l, &cma, retval); |
error = sys_mmap(l, &cma, retval); |
if (error) |
if (error) |
return (error); |
return (error); |
|
|
/* Shift the returned address for stack-like segment if necessary */ |
/* Shift the returned address for stack-like segment if necessary */ |
if (SCARG(uap, flags) & LINUX_MAP_GROWSDOWN && mmoff) |
retval[0] += mmoff; |
retval[0] += mmoff; |
|
|
|
return (0); |
return (0); |
} |
} |
|
|
static void |
static void |
linux_to_bsd_mmap_args(cma, uap) |
linux_to_bsd_mmap_args(struct sys_mmap_args *cma, const struct linux_sys_mmap_args *uap) |
struct sys_mmap_args *cma; |
|
const struct linux_sys_mmap_args *uap; |
|
{ |
{ |
int flags = MAP_TRYFIXED, fl = SCARG(uap, flags); |
int flags = MAP_TRYFIXED, fl = SCARG(uap, flags); |
|
|
Line 516 linux_to_bsd_mmap_args(cma, uap) |
|
Line 494 linux_to_bsd_mmap_args(cma, uap) |
|
#define LINUX_MREMAP_FIXED 2 |
#define LINUX_MREMAP_FIXED 2 |
|
|
int |
int |
linux_sys_mremap(l, v, retval) |
linux_sys_mremap(struct lwp *l, const struct linux_sys_mremap_args *uap, register_t *retval) |
struct lwp *l; |
|
void *v; |
|
register_t *retval; |
|
{ |
{ |
struct linux_sys_mremap_args /* { |
/* { |
syscallarg(void *) old_address; |
syscallarg(void *) old_address; |
syscallarg(size_t) old_size; |
syscallarg(size_t) old_size; |
syscallarg(size_t) new_size; |
syscallarg(size_t) new_size; |
syscallarg(u_long) flags; |
syscallarg(u_long) flags; |
} */ *uap = v; |
} */ |
|
|
struct proc *p; |
struct proc *p; |
struct vm_map *map; |
struct vm_map *map; |
|
|
} |
} |
|
|
int |
int |
linux_sys_msync(l, v, retval) |
linux_sys_msync(struct lwp *l, const struct linux_sys_msync_args *uap, register_t *retval) |
struct lwp *l; |
|
void *v; |
|
register_t *retval; |
|
{ |
{ |
struct linux_sys_msync_args /* { |
/* { |
syscallarg(void *) addr; |
syscallarg(void *) addr; |
syscallarg(int) len; |
syscallarg(int) len; |
syscallarg(int) fl; |
syscallarg(int) fl; |
} */ *uap = v; |
} */ |
|
|
struct sys___msync13_args bma; |
struct sys___msync13_args bma; |
|
|
Line 597 linux_sys_msync(l, v, retval) |
|
Line 569 linux_sys_msync(l, v, retval) |
|
} |
} |
|
|
int |
int |
linux_sys_mprotect(struct lwp *l, void *v, register_t *retval) |
linux_sys_mprotect(struct lwp *l, const struct linux_sys_mprotect_args *uap, register_t *retval) |
{ |
{ |
struct linux_sys_mprotect_args /* { |
/* { |
syscallarg(const void *) start; |
syscallarg(const void *) start; |
syscallarg(unsigned long) len; |
syscallarg(unsigned long) len; |
syscallarg(int) prot; |
syscallarg(int) prot; |
} */ *uap = v; |
} */ |
struct vm_map_entry *entry; |
struct vm_map_entry *entry; |
struct vm_map *map; |
struct vm_map *map; |
struct proc *p; |
struct proc *p; |
Line 669 linux_sys_mprotect(struct lwp *l, void * |
|
Line 641 linux_sys_mprotect(struct lwp *l, void * |
|
#define CONVTCK(r) (r.tv_sec * hz + r.tv_usec / (1000000 / hz)) |
#define CONVTCK(r) (r.tv_sec * hz + r.tv_usec / (1000000 / hz)) |
|
|
int |
int |
linux_sys_times(l, v, retval) |
linux_sys_times(struct lwp *l, const struct linux_sys_times_args *uap, register_t *retval) |
struct lwp *l; |
|
void *v; |
|
register_t *retval; |
|
{ |
{ |
struct linux_sys_times_args /* { |
/* { |
syscallarg(struct times *) tms; |
syscallarg(struct times *) tms; |
} */ *uap = v; |
} */ |
struct proc *p = l->l_proc; |
struct proc *p = l->l_proc; |
struct timeval t; |
struct timeval t; |
int error; |
int error; |
Line 720 linux_sys_times(l, v, retval) |
|
Line 689 linux_sys_times(l, v, retval) |
|
* Note that this doesn't handle union-mounted filesystems. |
* Note that this doesn't handle union-mounted filesystems. |
*/ |
*/ |
int |
int |
linux_sys_getdents(l, v, retval) |
linux_sys_getdents(struct lwp *l, const struct linux_sys_getdents_args *uap, register_t *retval) |
struct lwp *l; |
|
void *v; |
|
register_t *retval; |
|
{ |
{ |
struct linux_sys_getdents_args /* { |
/* { |
syscallarg(int) fd; |
syscallarg(int) fd; |
syscallarg(struct linux_dirent *) dent; |
syscallarg(struct linux_dirent *) dent; |
syscallarg(unsigned int) count; |
syscallarg(unsigned int) count; |
} */ *uap = v; |
} */ |
struct dirent *bdp; |
struct dirent *bdp; |
struct vnode *vp; |
struct vnode *vp; |
char *inp, *tbuf; /* BSD-format */ |
char *inp, *tbuf; /* BSD-format */ |
Line 761 linux_sys_getdents(l, v, retval) |
|
Line 727 linux_sys_getdents(l, v, retval) |
|
goto out1; |
goto out1; |
} |
} |
|
|
if ((error = VOP_GETATTR(vp, &va, l->l_cred, l))) |
if ((error = VOP_GETATTR(vp, &va, l->l_cred))) |
goto out1; |
goto out1; |
|
|
nbytes = SCARG(uap, count); |
nbytes = SCARG(uap, count); |
|
|
* this. |
* this. |
*/ |
*/ |
int |
int |
linux_sys_select(l, v, retval) |
linux_sys_select(struct lwp *l, const struct linux_sys_select_args *uap, register_t *retval) |
struct lwp *l; |
|
void *v; |
|
register_t *retval; |
|
{ |
{ |
struct linux_sys_select_args /* { |
/* { |
syscallarg(int) nfds; |
syscallarg(int) nfds; |
syscallarg(fd_set *) readfds; |
syscallarg(fd_set *) readfds; |
syscallarg(fd_set *) writefds; |
syscallarg(fd_set *) writefds; |
syscallarg(fd_set *) exceptfds; |
syscallarg(fd_set *) exceptfds; |
syscallarg(struct timeval *) timeout; |
syscallarg(struct timeval *) timeout; |
} */ *uap = v; |
} */ |
|
|
return linux_select1(l, retval, SCARG(uap, nfds), SCARG(uap, readfds), |
return linux_select1(l, retval, SCARG(uap, nfds), SCARG(uap, readfds), |
SCARG(uap, writefds), SCARG(uap, exceptfds), SCARG(uap, timeout)); |
SCARG(uap, writefds), SCARG(uap, exceptfds), SCARG(uap, timeout)); |
Line 980 linux_select1(l, retval, nfds, readfds, |
|
Line 943 linux_select1(l, retval, nfds, readfds, |
|
} |
} |
|
|
/* |
/* |
* Get the process group of a certain process. Look it up |
|
* and return the value. |
|
*/ |
|
int |
|
linux_sys_getpgid(l, v, retval) |
|
struct lwp *l; |
|
void *v; |
|
register_t *retval; |
|
{ |
|
struct linux_sys_getpgid_args /* { |
|
syscallarg(int) pid; |
|
} */ *uap = v; |
|
struct proc *p = l->l_proc; |
|
struct proc *targp; |
|
|
|
if (SCARG(uap, pid) != 0 && SCARG(uap, pid) != p->p_pid) { |
|
if ((targp = pfind(SCARG(uap, pid))) == 0) |
|
return ESRCH; |
|
} |
|
else |
|
targp = p; |
|
|
|
retval[0] = targp->p_pgid; |
|
return 0; |
|
} |
|
|
|
/* |
|
* Set the 'personality' (emulation mode) for the current process. Only |
* Set the 'personality' (emulation mode) for the current process. Only |
* accept the Linux personality here (0). This call is needed because |
* accept the Linux personality here (0). This call is needed because |
* the Linux ELF crt0 issues it in an ugly kludge to make sure that |
* the Linux ELF crt0 issues it in an ugly kludge to make sure that |
* ELF binaries run in Linux mode, not SVR4 mode. |
* ELF binaries run in Linux mode, not SVR4 mode. |
*/ |
*/ |
int |
int |
linux_sys_personality(struct lwp *l, void *v, register_t *retval) |
linux_sys_personality(struct lwp *l, const struct linux_sys_personality_args *uap, register_t *retval) |
{ |
{ |
struct linux_sys_personality_args /* { |
/* { |
syscallarg(int) per; |
syscallarg(int) per; |
} */ *uap = v; |
} */ |
|
|
if (SCARG(uap, per) != 0) |
if (SCARG(uap, per) != 0) |
return EINVAL; |
return EINVAL; |
retval[0] = 0; |
retval[0] = 0; |
return 0; |
return 0; |
} |
} |
#endif /* !COMPAT_LINUX32 */ |
|
|
|
#if defined(__i386__) || defined(__m68k__) || defined(COMPAT_LINUX32) |
|
/* |
|
* The calls are here because of type conversions. |
|
*/ |
|
int |
|
linux_sys_setreuid16(l, v, retval) |
|
struct lwp *l; |
|
void *v; |
|
register_t *retval; |
|
{ |
|
struct linux_sys_setreuid16_args /* { |
|
syscallarg(int) ruid; |
|
syscallarg(int) euid; |
|
} */ *uap = v; |
|
struct sys_setreuid_args bsa; |
|
|
|
SCARG(&bsa, ruid) = ((linux_uid_t)SCARG(uap, ruid) == (linux_uid_t)-1) ? |
|
(uid_t)-1 : SCARG(uap, ruid); |
|
SCARG(&bsa, euid) = ((linux_uid_t)SCARG(uap, euid) == (linux_uid_t)-1) ? |
|
(uid_t)-1 : SCARG(uap, euid); |
|
|
|
return sys_setreuid(l, &bsa, retval); |
|
} |
|
|
|
int |
|
linux_sys_setregid16(l, v, retval) |
|
struct lwp *l; |
|
void *v; |
|
register_t *retval; |
|
{ |
|
struct linux_sys_setregid16_args /* { |
|
syscallarg(int) rgid; |
|
syscallarg(int) egid; |
|
} */ *uap = v; |
|
struct sys_setregid_args bsa; |
|
|
|
SCARG(&bsa, rgid) = ((linux_gid_t)SCARG(uap, rgid) == (linux_gid_t)-1) ? |
|
(uid_t)-1 : SCARG(uap, rgid); |
|
SCARG(&bsa, egid) = ((linux_gid_t)SCARG(uap, egid) == (linux_gid_t)-1) ? |
|
(uid_t)-1 : SCARG(uap, egid); |
|
|
|
return sys_setregid(l, &bsa, retval); |
|
} |
|
|
|
int |
|
linux_sys_setresuid16(l, v, retval) |
|
struct lwp *l; |
|
void *v; |
|
register_t *retval; |
|
{ |
|
struct linux_sys_setresuid16_args /* { |
|
syscallarg(uid_t) ruid; |
|
syscallarg(uid_t) euid; |
|
syscallarg(uid_t) suid; |
|
} */ *uap = v; |
|
struct linux_sys_setresuid16_args lsa; |
|
|
|
SCARG(&lsa, ruid) = ((linux_uid_t)SCARG(uap, ruid) == (linux_uid_t)-1) ? |
|
(uid_t)-1 : SCARG(uap, ruid); |
|
SCARG(&lsa, euid) = ((linux_uid_t)SCARG(uap, euid) == (linux_uid_t)-1) ? |
|
(uid_t)-1 : SCARG(uap, euid); |
|
SCARG(&lsa, suid) = ((linux_uid_t)SCARG(uap, suid) == (linux_uid_t)-1) ? |
|
(uid_t)-1 : SCARG(uap, suid); |
|
|
|
return linux_sys_setresuid(l, &lsa, retval); |
|
} |
|
|
|
int |
|
linux_sys_setresgid16(l, v, retval) |
|
struct lwp *l; |
|
void *v; |
|
register_t *retval; |
|
{ |
|
struct linux_sys_setresgid16_args /* { |
|
syscallarg(gid_t) rgid; |
|
syscallarg(gid_t) egid; |
|
syscallarg(gid_t) sgid; |
|
} */ *uap = v; |
|
struct linux_sys_setresgid16_args lsa; |
|
|
|
SCARG(&lsa, rgid) = ((linux_gid_t)SCARG(uap, rgid) == (linux_gid_t)-1) ? |
|
(gid_t)-1 : SCARG(uap, rgid); |
|
SCARG(&lsa, egid) = ((linux_gid_t)SCARG(uap, egid) == (linux_gid_t)-1) ? |
|
(gid_t)-1 : SCARG(uap, egid); |
|
SCARG(&lsa, sgid) = ((linux_gid_t)SCARG(uap, sgid) == (linux_gid_t)-1) ? |
|
(gid_t)-1 : SCARG(uap, sgid); |
|
|
|
return linux_sys_setresgid(l, &lsa, retval); |
|
} |
|
|
|
int |
|
linux_sys_getgroups16(l, v, retval) |
|
struct lwp *l; |
|
void *v; |
|
register_t *retval; |
|
{ |
|
struct linux_sys_getgroups16_args /* { |
|
syscallarg(int) gidsetsize; |
|
syscallarg(linux_gid_t *) gidset; |
|
} */ *uap = v; |
|
linux_gid_t lset[16]; |
|
linux_gid_t *gidset; |
|
unsigned int ngrps; |
|
int i, n, j; |
|
int error; |
|
|
|
ngrps = kauth_cred_ngroups(l->l_cred); |
|
*retval = ngrps; |
|
if (SCARG(uap, gidsetsize) == 0) |
|
return 0; |
|
if (SCARG(uap, gidsetsize) < ngrps) |
|
return EINVAL; |
|
|
|
gidset = SCARG(uap, gidset); |
|
for (i = 0; i < (n = ngrps); i += n, gidset += n) { |
|
n -= i; |
|
if (n > __arraycount(lset)) |
|
n = __arraycount(lset); |
|
for (j = 0; j < n; j++) |
|
lset[j] = kauth_cred_group(l->l_cred, i + j); |
|
error = copyout(lset, gidset, n * sizeof(lset[0])); |
|
if (error != 0) |
|
return error; |
|
} |
|
|
|
return 0; |
|
} |
|
|
|
/* |
|
* It is very unlikly that any problem using 16bit groups is written |
|
* to allow for more than 16 of them, so don't bother trying to |
|
* support that. |
|
*/ |
|
#define COMPAT_NGROUPS16 16 |
|
|
|
int |
|
linux_sys_setgroups16(l, v, retval) |
|
struct lwp *l; |
|
void *v; |
|
register_t *retval; |
|
{ |
|
struct linux_sys_setgroups16_args /* { |
|
syscallarg(int) gidsetsize; |
|
syscallarg(linux_gid_t *) gidset; |
|
} */ *uap = v; |
|
linux_gid_t lset[COMPAT_NGROUPS16]; |
|
kauth_cred_t ncred; |
|
int error; |
|
gid_t grbuf[COMPAT_NGROUPS16]; |
|
unsigned int i, ngroups = SCARG(uap, gidsetsize); |
|
|
|
if (ngroups > COMPAT_NGROUPS16) |
|
return EINVAL; |
|
error = copyin(SCARG(uap, gidset), lset, ngroups); |
|
if (error != 0) |
|
return error; |
|
|
|
for (i = 0; i < ngroups; i++) |
|
grbuf[i] = lset[i]; |
|
|
|
ncred = kauth_cred_alloc(); |
|
error = kauth_cred_setgroups(ncred, grbuf, SCARG(uap, gidsetsize), |
|
-1, UIO_SYSSPACE); |
|
if (error != 0) { |
|
kauth_cred_free(ncred); |
|
return error; |
|
} |
|
|
|
return kauth_proc_setgroups(l, ncred); |
|
} |
|
|
|
#endif /* __i386__ || __m68k__ || COMPAT_LINUX32 */ |
|
|
|
#ifndef COMPAT_LINUX32 |
|
/* |
/* |
* We have nonexistent fsuid equal to uid. |
* We have nonexistent fsuid equal to uid. |
* If modification is requested, refuse. |
* If modification is requested, refuse. |
*/ |
*/ |
int |
int |
linux_sys_setfsuid(l, v, retval) |
linux_sys_setfsuid(struct lwp *l, const struct linux_sys_setfsuid_args *uap, register_t *retval) |
struct lwp *l; |
|
void *v; |
|
register_t *retval; |
|
{ |
{ |
struct linux_sys_setfsuid_args /* { |
/* { |
syscallarg(uid_t) uid; |
syscallarg(uid_t) uid; |
} */ *uap = v; |
} */ |
uid_t uid; |
uid_t uid; |
|
|
uid = SCARG(uap, uid); |
uid = SCARG(uap, uid); |
if (kauth_cred_getuid(l->l_cred) != uid) |
if (kauth_cred_getuid(l->l_cred) != uid) |
return sys_nosys(l, v, retval); |
return sys_nosys(l, uap, retval); |
else |
|
return (0); |
*retval = uid; |
|
return 0; |
} |
} |
|
|
/* XXX XXX XXX */ |
|
# ifndef alpha |
|
int |
int |
linux_sys_getfsuid(l, v, retval) |
linux_sys_setfsgid(struct lwp *l, const struct linux_sys_setfsgid_args *uap, register_t *retval) |
struct lwp *l; |
|
void *v; |
|
register_t *retval; |
|
{ |
{ |
return sys_getuid(l, v, retval); |
/* { |
|
syscallarg(gid_t) gid; |
|
} */ |
|
gid_t gid; |
|
|
|
gid = SCARG(uap, gid); |
|
if (kauth_cred_getgid(l->l_cred) != gid) |
|
return sys_nosys(l, uap, retval); |
|
|
|
*retval = gid; |
|
return 0; |
} |
} |
# endif |
|
|
|
int |
int |
linux_sys_setresuid(struct lwp *l, void *v, register_t *retval) |
linux_sys_setresuid(struct lwp *l, const struct linux_sys_setresuid_args *uap, register_t *retval) |
{ |
{ |
struct linux_sys_setresuid_args /* { |
/* { |
syscallarg(uid_t) ruid; |
syscallarg(uid_t) ruid; |
syscallarg(uid_t) euid; |
syscallarg(uid_t) euid; |
syscallarg(uid_t) suid; |
syscallarg(uid_t) suid; |
} */ *uap = v; |
} */ |
|
|
/* |
/* |
* Note: These checks are a little different than the NetBSD |
* Note: These checks are a little different than the NetBSD |
Line 1257 linux_sys_setresuid(struct lwp *l, void |
|
Line 1020 linux_sys_setresuid(struct lwp *l, void |
|
} |
} |
|
|
int |
int |
linux_sys_getresuid(struct lwp *l, void *v, register_t *retval) |
linux_sys_getresuid(struct lwp *l, const struct linux_sys_getresuid_args *uap, register_t *retval) |
{ |
{ |
struct linux_sys_getresuid_args /* { |
/* { |
syscallarg(uid_t *) ruid; |
syscallarg(uid_t *) ruid; |
syscallarg(uid_t *) euid; |
syscallarg(uid_t *) euid; |
syscallarg(uid_t *) suid; |
syscallarg(uid_t *) suid; |
} */ *uap = v; |
} */ |
kauth_cred_t pc = l->l_cred; |
kauth_cred_t pc = l->l_cred; |
int error; |
int error; |
uid_t uid; |
uid_t uid; |
Line 1289 linux_sys_getresuid(struct lwp *l, void |
|
Line 1052 linux_sys_getresuid(struct lwp *l, void |
|
} |
} |
|
|
int |
int |
linux_sys_ptrace(l, v, retval) |
linux_sys_ptrace(struct lwp *l, const struct linux_sys_ptrace_args *uap, register_t *retval) |
struct lwp *l; |
|
void *v; |
|
register_t *retval; |
|
{ |
{ |
#if defined(PTRACE) || defined(_LKM) |
/* { |
struct linux_sys_ptrace_args /* { |
|
i386, m68k, powerpc: T=int |
i386, m68k, powerpc: T=int |
alpha, amd64: T=long |
alpha, amd64: T=long |
syscallarg(T) request; |
syscallarg(T) request; |
syscallarg(T) pid; |
syscallarg(T) pid; |
syscallarg(T) addr; |
syscallarg(T) addr; |
syscallarg(T) data; |
syscallarg(T) data; |
} */ *uap = v; |
} */ |
|
#if defined(PTRACE) || defined(_LKM) |
const int *ptr; |
const int *ptr; |
int request; |
int request; |
int error; |
int error; |
Line 1356 linux_sys_ptrace(l, v, retval) |
|
Line 1116 linux_sys_ptrace(l, v, retval) |
|
} |
} |
|
|
int |
int |
linux_sys_reboot(struct lwp *l, void *v, register_t *retval) |
linux_sys_reboot(struct lwp *l, const struct linux_sys_reboot_args *uap, register_t *retval) |
{ |
{ |
struct linux_sys_reboot_args /* { |
/* { |
syscallarg(int) magic1; |
syscallarg(int) magic1; |
syscallarg(int) magic2; |
syscallarg(int) magic2; |
syscallarg(int) cmd; |
syscallarg(int) cmd; |
syscallarg(void *) arg; |
syscallarg(void *) arg; |
} */ *uap = v; |
} */ |
struct sys_reboot_args /* { |
struct sys_reboot_args /* { |
syscallarg(int) opt; |
syscallarg(int) opt; |
syscallarg(char *) bootstr; |
syscallarg(char *) bootstr; |
Line 1411 linux_sys_reboot(struct lwp *l, void *v, |
|
Line 1171 linux_sys_reboot(struct lwp *l, void *v, |
|
* Copy of compat_12_sys_swapon(). |
* Copy of compat_12_sys_swapon(). |
*/ |
*/ |
int |
int |
linux_sys_swapon(l, v, retval) |
linux_sys_swapon(struct lwp *l, const struct linux_sys_swapon_args *uap, register_t *retval) |
struct lwp *l; |
|
void *v; |
|
register_t *retval; |
|
{ |
{ |
struct sys_swapctl_args ua; |
/* { |
struct linux_sys_swapon_args /* { |
|
syscallarg(const char *) name; |
syscallarg(const char *) name; |
} */ *uap = v; |
} */ |
|
struct sys_swapctl_args ua; |
|
|
SCARG(&ua, cmd) = SWAP_ON; |
SCARG(&ua, cmd) = SWAP_ON; |
SCARG(&ua, arg) = (void *)__UNCONST(SCARG(uap, name)); |
SCARG(&ua, arg) = (void *)__UNCONST(SCARG(uap, name)); |
Line 1431 linux_sys_swapon(l, v, retval) |
|
Line 1188 linux_sys_swapon(l, v, retval) |
|
* Stop swapping to the file or block device specified by path. |
* Stop swapping to the file or block device specified by path. |
*/ |
*/ |
int |
int |
linux_sys_swapoff(l, v, retval) |
linux_sys_swapoff(struct lwp *l, const struct linux_sys_swapoff_args *uap, register_t *retval) |
struct lwp *l; |
|
void *v; |
|
register_t *retval; |
|
{ |
{ |
struct sys_swapctl_args ua; |
/* { |
struct linux_sys_swapoff_args /* { |
|
syscallarg(const char *) path; |
syscallarg(const char *) path; |
} */ *uap = v; |
} */ |
|
struct sys_swapctl_args ua; |
|
|
SCARG(&ua, cmd) = SWAP_OFF; |
SCARG(&ua, cmd) = SWAP_OFF; |
SCARG(&ua, arg) = __UNCONST(SCARG(uap, path)); /*XXXUNCONST*/ |
SCARG(&ua, arg) = __UNCONST(SCARG(uap, path)); /*XXXUNCONST*/ |
Line 1451 linux_sys_swapoff(l, v, retval) |
|
Line 1205 linux_sys_swapoff(l, v, retval) |
|
*/ |
*/ |
/* ARGSUSED */ |
/* ARGSUSED */ |
int |
int |
linux_sys_setdomainname(struct lwp *l, void *v, register_t *retval) |
linux_sys_setdomainname(struct lwp *l, const struct linux_sys_setdomainname_args *uap, register_t *retval) |
{ |
{ |
struct linux_sys_setdomainname_args /* { |
/* { |
syscallarg(char *) domainname; |
syscallarg(char *) domainname; |
syscallarg(int) len; |
syscallarg(int) len; |
} */ *uap = v; |
} */ |
int name[2]; |
int name[2]; |
|
|
name[0] = CTL_KERN; |
name[0] = CTL_KERN; |
Line 1470 linux_sys_setdomainname(struct lwp *l, v |
|
Line 1224 linux_sys_setdomainname(struct lwp *l, v |
|
*/ |
*/ |
/* ARGSUSED */ |
/* ARGSUSED */ |
int |
int |
linux_sys_sysinfo(struct lwp *l, void *v, register_t *retval) |
linux_sys_sysinfo(struct lwp *l, const struct linux_sys_sysinfo_args *uap, register_t *retval) |
{ |
{ |
struct linux_sys_sysinfo_args /* { |
/* { |
syscallarg(struct linux_sysinfo *) arg; |
syscallarg(struct linux_sysinfo *) arg; |
} */ *uap = v; |
} */ |
struct linux_sysinfo si; |
struct linux_sysinfo si; |
struct loadavg *la; |
struct loadavg *la; |
|
|
Line 1501 linux_sys_sysinfo(struct lwp *l, void *v |
|
Line 1255 linux_sys_sysinfo(struct lwp *l, void *v |
|
} |
} |
|
|
int |
int |
linux_sys_getrlimit(l, v, retval) |
linux_sys_getrlimit(struct lwp *l, const struct linux_sys_getrlimit_args *uap, register_t *retval) |
struct lwp *l; |
|
void *v; |
|
register_t *retval; |
|
{ |
{ |
struct linux_sys_getrlimit_args /* { |
/* { |
syscallarg(int) which; |
syscallarg(int) which; |
# ifdef LINUX_LARGEFILE64 |
# ifdef LINUX_LARGEFILE64 |
syscallarg(struct rlimit *) rlp; |
syscallarg(struct rlimit *) rlp; |
# else |
# else |
syscallarg(struct orlimit *) rlp; |
syscallarg(struct orlimit *) rlp; |
# endif |
# endif |
} */ *uap = v; |
} */ |
# ifdef LINUX_LARGEFILE64 |
# ifdef LINUX_LARGEFILE64 |
struct rlimit orl; |
struct rlimit orl; |
# else |
# else |
Line 1531 linux_sys_getrlimit(l, v, retval) |
|
Line 1282 linux_sys_getrlimit(l, v, retval) |
|
} |
} |
|
|
int |
int |
linux_sys_setrlimit(l, v, retval) |
linux_sys_setrlimit(struct lwp *l, const struct linux_sys_setrlimit_args *uap, register_t *retval) |
struct lwp *l; |
|
void *v; |
|
register_t *retval; |
|
{ |
{ |
struct linux_sys_setrlimit_args /* { |
/* { |
syscallarg(int) which; |
syscallarg(int) which; |
# ifdef LINUX_LARGEFILE64 |
# ifdef LINUX_LARGEFILE64 |
syscallarg(struct rlimit *) rlp; |
syscallarg(struct rlimit *) rlp; |
# else |
# else |
syscallarg(struct orlimit *) rlp; |
syscallarg(struct orlimit *) rlp; |
# endif |
# endif |
} */ *uap = v; |
} */ |
struct rlimit rl; |
struct rlimit rl; |
# ifdef LINUX_LARGEFILE64 |
# ifdef LINUX_LARGEFILE64 |
struct rlimit orl; |
struct rlimit orl; |
Line 1567 linux_sys_setrlimit(l, v, retval) |
|
Line 1315 linux_sys_setrlimit(l, v, retval) |
|
# if !defined(__mips__) && !defined(__amd64__) |
# if !defined(__mips__) && !defined(__amd64__) |
/* XXX: this doesn't look 100% common, at least mips doesn't have it */ |
/* XXX: this doesn't look 100% common, at least mips doesn't have it */ |
int |
int |
linux_sys_ugetrlimit(l, v, retval) |
linux_sys_ugetrlimit(struct lwp *l, const struct linux_sys_ugetrlimit_args *uap, register_t *retval) |
struct lwp *l; |
|
void *v; |
|
register_t *retval; |
|
{ |
{ |
return linux_sys_getrlimit(l, v, retval); |
return linux_sys_getrlimit(l, (const void *)uap, retval); |
} |
} |
# endif |
# endif |
|
|
Line 1582 linux_sys_ugetrlimit(l, v, retval) |
|
Line 1327 linux_sys_ugetrlimit(l, v, retval) |
|
* This is the way Linux does it and glibc depends on this behaviour. |
* This is the way Linux does it and glibc depends on this behaviour. |
*/ |
*/ |
int |
int |
linux_sys_nosys(struct lwp *l, void *v, |
linux_sys_nosys(struct lwp *l, const void *v, register_t *retval) |
register_t *retval) |
|
{ |
{ |
return (ENOSYS); |
return (ENOSYS); |
} |
} |
|
|
int |
int |
linux_sys_getpriority(l, v, retval) |
linux_sys_getpriority(struct lwp *l, const struct linux_sys_getpriority_args *uap, register_t *retval) |
struct lwp *l; |
|
void *v; |
|
register_t *retval; |
|
{ |
{ |
struct linux_sys_getpriority_args /* { |
/* { |
syscallarg(int) which; |
syscallarg(int) which; |
syscallarg(int) who; |
syscallarg(int) who; |
} */ *uap = v; |
} */ |
struct sys_getpriority_args bsa; |
struct sys_getpriority_args bsa; |
int error; |
int error; |
|
|