Home | History | Annotate | Line # | Download | only in common
linux32_misc.c revision 1.23.4.1.6.1
      1  1.23.4.1.6.1    martin /*	$NetBSD: linux32_misc.c,v 1.23.4.1.6.1 2020/01/21 19:23:37 martin Exp $	*/
      2           1.1      manu 
      3           1.1      manu /*-
      4           1.5     njoly  * Copyright (c) 1995, 1998, 1999 The NetBSD Foundation, Inc.
      5           1.5     njoly  * All rights reserved.
      6           1.5     njoly  *
      7           1.5     njoly  * This code is derived from software contributed to The NetBSD Foundation
      8           1.5     njoly  * by Frank van der Linden and Eric Haszlakiewicz; by Jason R. Thorpe
      9           1.5     njoly  * of the Numerical Aerospace Simulation Facility, NASA Ames Research Center;
     10           1.5     njoly  * by Edgar Fu\ss, Mathematisches Institut der Uni Bonn.
     11           1.1      manu  *
     12           1.1      manu  * Redistribution and use in source and binary forms, with or without
     13           1.1      manu  * modification, are permitted provided that the following conditions
     14           1.1      manu  * are met:
     15           1.1      manu  * 1. Redistributions of source code must retain the above copyright
     16           1.1      manu  *    notice, this list of conditions and the following disclaimer.
     17           1.1      manu  * 2. Redistributions in binary form must reproduce the above copyright
     18           1.1      manu  *    notice, this list of conditions and the following disclaimer in the
     19           1.1      manu  *    documentation and/or other materials provided with the distribution.
     20           1.1      manu  *
     21           1.5     njoly  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
     22           1.5     njoly  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
     23           1.5     njoly  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
     24           1.5     njoly  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
     25           1.1      manu  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
     26           1.1      manu  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
     27           1.1      manu  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
     28           1.1      manu  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
     29           1.1      manu  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
     30           1.1      manu  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
     31           1.1      manu  * POSSIBILITY OF SUCH DAMAGE.
     32           1.1      manu  */
     33           1.1      manu 
     34           1.1      manu #include <sys/cdefs.h>
     35  1.23.4.1.6.1    martin __KERNEL_RCSID(0, "$NetBSD: linux32_misc.c,v 1.23.4.1.6.1 2020/01/21 19:23:37 martin Exp $");
     36           1.1      manu 
     37           1.1      manu #include <sys/param.h>
     38           1.1      manu #include <sys/proc.h>
     39           1.5     njoly #include <sys/time.h>
     40           1.5     njoly #include <sys/types.h>
     41           1.7       dsl #include <sys/fstypes.h>
     42           1.7       dsl #include <sys/vfs_syscalls.h>
     43          1.11  christos #include <sys/ptrace.h>
     44          1.14     njoly #include <sys/syscall.h>
     45           1.1      manu 
     46           1.1      manu #include <compat/netbsd32/netbsd32.h>
     47           1.1      manu #include <compat/netbsd32/netbsd32_syscallargs.h>
     48           1.1      manu 
     49          1.23       chs #include <compat/linux/common/linux_types.h>
     50          1.23       chs 
     51           1.5     njoly #include <compat/linux32/common/linux32_types.h>
     52           1.5     njoly #include <compat/linux32/common/linux32_signal.h>
     53          1.22  christos #include <compat/linux32/common/linux32_sched.h>
     54           1.5     njoly #include <compat/linux32/linux32_syscallargs.h>
     55           1.5     njoly 
     56          1.11  christos #include <compat/linux/common/linux_ptrace.h>
     57          1.19       chs #include <compat/linux/common/linux_emuldata.h>
     58           1.1      manu #include <compat/linux/common/linux_signal.h>
     59           1.1      manu #include <compat/linux/common/linux_misc.h>
     60           1.5     njoly #include <compat/linux/common/linux_statfs.h>
     61          1.15        ad #include <compat/linux/common/linux_ipc.h>
     62          1.15        ad #include <compat/linux/common/linux_sem.h>
     63          1.19       chs #include <compat/linux/common/linux_futex.h>
     64           1.1      manu #include <compat/linux/linux_syscallargs.h>
     65           1.1      manu 
     66           1.5     njoly extern const struct linux_mnttypes linux_fstypes[];
     67           1.5     njoly extern const int linux_fstypes_cnt;
     68           1.1      manu 
     69          1.19       chs void linux32_to_native_timespec(struct timespec *, struct linux32_timespec *);
     70           1.1      manu 
     71           1.5     njoly /*
     72           1.5     njoly  * Implement the fs stat functions. Straightforward.
     73           1.5     njoly  */
     74           1.1      manu int
     75           1.9       dsl linux32_sys_statfs(struct lwp *l, const struct linux32_sys_statfs_args *uap, register_t *retval)
     76           1.1      manu {
     77           1.9       dsl 	/* {
     78           1.5     njoly 		syscallarg(const netbsd32_charp char) path;
     79           1.5     njoly 		syscallarg(linux32_statfsp) sp;
     80           1.9       dsl 	} */
     81           1.7       dsl 	struct statvfs *sb;
     82           1.5     njoly 	struct linux_statfs ltmp;
     83           1.1      manu 	int error;
     84           1.1      manu 
     85           1.7       dsl 	sb = STATVFSBUF_GET();
     86           1.7       dsl 	error = do_sys_pstatvfs(l, SCARG_P32(uap, path), ST_WAIT, sb);
     87           1.7       dsl 	if (error == 0) {
     88           1.7       dsl 		bsd_to_linux_statfs(sb, &ltmp);
     89           1.7       dsl 		error = copyout(&ltmp, SCARG_P32(uap, sp), sizeof ltmp);
     90           1.7       dsl 	}
     91           1.1      manu 
     92           1.7       dsl 	STATVFSBUF_PUT(sb);
     93           1.5     njoly 	return error;
     94           1.1      manu }
     95          1.12     njoly 
     96          1.17     njoly int
     97          1.17     njoly linux32_sys_fstatfs(struct lwp *l, const struct linux32_sys_fstatfs_args *uap, register_t *retval)
     98          1.17     njoly {
     99          1.17     njoly 	/* {
    100          1.17     njoly 		syscallarg(int) fd;
    101          1.17     njoly 		syscallarg(linux32_statfsp) sp;
    102          1.17     njoly 	} */
    103          1.17     njoly 	struct statvfs *sb;
    104          1.17     njoly 	struct linux_statfs ltmp;
    105          1.17     njoly 	int error;
    106          1.17     njoly 
    107          1.17     njoly 	sb = STATVFSBUF_GET();
    108          1.17     njoly 	error = do_sys_fstatvfs(l, SCARG(uap, fd), ST_WAIT, sb);
    109          1.17     njoly 	if (error == 0) {
    110          1.17     njoly 		bsd_to_linux_statfs(sb, &ltmp);
    111          1.17     njoly 		error = copyout(&ltmp, SCARG_P32(uap, sp), sizeof ltmp);
    112          1.17     njoly 	}
    113          1.17     njoly 	STATVFSBUF_PUT(sb);
    114          1.17     njoly 
    115          1.17     njoly 	return error;
    116          1.17     njoly }
    117          1.17     njoly 
    118          1.20       chs int
    119          1.20       chs linux32_sys_statfs64(struct lwp *l, const struct linux32_sys_statfs64_args *uap, register_t *retval)
    120          1.20       chs {
    121          1.20       chs 	/* {
    122          1.20       chs 		syscallarg(const netbsd32_charp char) path;
    123          1.20       chs 		syscallarg(linux32_statfs64p) sp;
    124          1.20       chs 	} */
    125          1.20       chs 	struct statvfs *sb;
    126          1.20       chs 	struct linux_statfs64 ltmp;
    127          1.20       chs 	int error;
    128          1.20       chs 
    129          1.20       chs 	sb = STATVFSBUF_GET();
    130          1.20       chs 	error = do_sys_pstatvfs(l, SCARG_P32(uap, path), ST_WAIT, sb);
    131          1.20       chs 	if (error == 0) {
    132          1.20       chs 		bsd_to_linux_statfs64(sb, &ltmp);
    133          1.20       chs 		error = copyout(&ltmp, SCARG_P32(uap, sp), sizeof ltmp);
    134          1.20       chs 	}
    135          1.20       chs 
    136          1.20       chs 	STATVFSBUF_PUT(sb);
    137          1.20       chs 	return error;
    138          1.20       chs }
    139          1.20       chs 
    140          1.20       chs int
    141          1.20       chs linux32_sys_fstatfs64(struct lwp *l, const struct linux32_sys_fstatfs64_args *uap, register_t *retval)
    142          1.20       chs {
    143          1.20       chs 	/* {
    144          1.20       chs 		syscallarg(int) fd;
    145          1.20       chs 		syscallarg(linux32_statfs64p) sp;
    146          1.20       chs 	} */
    147          1.20       chs 	struct statvfs *sb;
    148          1.20       chs 	struct linux_statfs64 ltmp;
    149          1.20       chs 	int error;
    150          1.20       chs 
    151          1.20       chs 	sb = STATVFSBUF_GET();
    152          1.20       chs 	error = do_sys_fstatvfs(l, SCARG(uap, fd), ST_WAIT, sb);
    153          1.20       chs 	if (error == 0) {
    154          1.20       chs 		bsd_to_linux_statfs64(sb, &ltmp);
    155          1.20       chs 		error = copyout(&ltmp, SCARG_P32(uap, sp), sizeof ltmp);
    156          1.20       chs 	}
    157          1.20       chs 	STATVFSBUF_PUT(sb);
    158          1.20       chs 
    159          1.20       chs 	return error;
    160          1.20       chs }
    161          1.20       chs 
    162          1.11  christos extern const int linux_ptrace_request_map[];
    163          1.12     njoly 
    164          1.11  christos int
    165          1.11  christos linux32_sys_ptrace(struct lwp *l, const struct linux32_sys_ptrace_args *uap, register_t *retval)
    166          1.11  christos {
    167          1.11  christos 	/* {
    168          1.11  christos 		i386, m68k, powerpc: T=int
    169          1.11  christos 		alpha, amd64: T=long
    170          1.11  christos 		syscallarg(T) request;
    171          1.11  christos 		syscallarg(T) pid;
    172          1.11  christos 		syscallarg(T) addr;
    173          1.11  christos 		syscallarg(T) data;
    174          1.11  christos 	} */
    175          1.11  christos 	const int *ptr;
    176          1.11  christos 	int request;
    177          1.11  christos 	int error;
    178          1.11  christos 
    179          1.11  christos 	ptr = linux_ptrace_request_map;
    180          1.11  christos 	request = SCARG(uap, request);
    181          1.11  christos 	while (*ptr != -1)
    182          1.11  christos 		if (*ptr++ == request) {
    183          1.12     njoly 			struct sys_ptrace_args pta;
    184          1.11  christos 
    185          1.11  christos 			SCARG(&pta, req) = *ptr;
    186          1.11  christos 			SCARG(&pta, pid) = SCARG(uap, pid);
    187          1.12     njoly 			SCARG(&pta, addr) = NETBSD32IPTR64(SCARG(uap, addr));
    188          1.11  christos 			SCARG(&pta, data) = SCARG(uap, data);
    189          1.11  christos 
    190          1.11  christos 			/*
    191          1.11  christos 			 * Linux ptrace(PTRACE_CONT, pid, 0, 0) means actually
    192          1.11  christos 			 * to continue where the process left off previously.
    193          1.11  christos 			 * The same thing is achieved by addr == (void *) 1
    194          1.11  christos 			 * on NetBSD, so rewrite 'addr' appropriately.
    195          1.11  christos 			 */
    196          1.11  christos 			if (request == LINUX_PTRACE_CONT && SCARG(uap, addr)==0)
    197          1.11  christos 				SCARG(&pta, addr) = (void *) 1;
    198          1.11  christos 
    199          1.13        ad 			error = sysent[SYS_ptrace].sy_call(l, &pta, retval);
    200          1.11  christos 			if (error)
    201          1.11  christos 				return error;
    202          1.11  christos 			switch (request) {
    203          1.11  christos 			case LINUX_PTRACE_PEEKTEXT:
    204          1.11  christos 			case LINUX_PTRACE_PEEKDATA:
    205          1.11  christos 				error = copyout (retval,
    206          1.12     njoly 				    NETBSD32IPTR64(SCARG(uap, data)),
    207          1.11  christos 				    sizeof *retval);
    208          1.11  christos 				*retval = SCARG(uap, data);
    209          1.11  christos 				break;
    210          1.11  christos 			default:
    211          1.11  christos 				break;
    212          1.11  christos 			}
    213          1.11  christos 			return error;
    214          1.11  christos 		}
    215          1.11  christos 		else
    216          1.11  christos 			ptr++;
    217          1.11  christos 
    218          1.12     njoly 	return EIO;
    219          1.11  christos }
    220          1.16     njoly 
    221          1.16     njoly int
    222          1.16     njoly linux32_sys_personality(struct lwp *l, const struct linux32_sys_personality_args *uap, register_t *retval)
    223          1.16     njoly {
    224          1.16     njoly 	/* {
    225          1.18     njoly 		syscallarg(netbsd32_u_long) per;
    226          1.16     njoly 	} */
    227          1.21       chs 	struct linux_sys_personality_args ua;
    228          1.16     njoly 
    229          1.21       chs 	NETBSD32TOX_UAP(per, long);
    230          1.21       chs 	return linux_sys_personality(l, &ua, retval);
    231          1.16     njoly }
    232          1.19       chs 
    233          1.19       chs int
    234          1.19       chs linux32_sys_futex(struct lwp *l,
    235          1.19       chs     const struct linux32_sys_futex_args *uap, register_t *retval)
    236          1.19       chs {
    237          1.19       chs 	/* {
    238          1.19       chs 		syscallarg(linux32_intp_t) uaddr;
    239          1.19       chs 		syscallarg(int) op;
    240          1.19       chs 		syscallarg(int) val;
    241          1.19       chs 		syscallarg(linux32_timespecp_t) timeout;
    242          1.19       chs 		syscallarg(linux32_intp_t) uaddr2;
    243          1.19       chs 		syscallarg(int) val3;
    244          1.19       chs 	} */
    245          1.19       chs 	struct linux_sys_futex_args ua;
    246          1.19       chs 	struct linux32_timespec lts;
    247          1.19       chs 	struct timespec ts = { 0, 0 };
    248          1.19       chs 	int error;
    249          1.19       chs 
    250          1.19       chs 	NETBSD32TOP_UAP(uaddr, int);
    251          1.19       chs 	NETBSD32TO64_UAP(op);
    252          1.19       chs 	NETBSD32TO64_UAP(val);
    253          1.19       chs 	NETBSD32TOP_UAP(timeout, struct linux_timespec);
    254          1.19       chs 	NETBSD32TOP_UAP(uaddr2, int);
    255          1.19       chs 	NETBSD32TO64_UAP(val3);
    256          1.19       chs 	if ((SCARG(uap, op) & ~LINUX_FUTEX_PRIVATE_FLAG) == LINUX_FUTEX_WAIT &&
    257          1.19       chs 	    SCARG_P32(uap, timeout) != NULL) {
    258          1.19       chs 		if ((error = copyin((void *)SCARG_P32(uap, timeout),
    259          1.19       chs 		    &lts, sizeof(lts))) != 0) {
    260          1.19       chs 			return error;
    261          1.19       chs 		}
    262          1.19       chs 		linux32_to_native_timespec(&ts, &lts);
    263          1.19       chs 	}
    264          1.19       chs 	return linux_do_futex(l, &ua, retval, &ts);
    265          1.19       chs }
    266          1.19       chs 
    267          1.19       chs int
    268          1.19       chs linux32_sys_set_robust_list(struct lwp *l,
    269          1.19       chs     const struct linux32_sys_set_robust_list_args *uap, register_t *retval)
    270          1.19       chs {
    271          1.19       chs 	/* {
    272          1.19       chs 		syscallarg(linux32_robust_list_headp_t) head;
    273          1.19       chs 		syscallarg(linux32_size_t) len;
    274          1.19       chs 	} */
    275          1.19       chs 	struct linux_sys_set_robust_list_args ua;
    276          1.19       chs 	struct linux_emuldata *led;
    277          1.19       chs 
    278          1.19       chs 	if (SCARG(uap, len) != 12)
    279          1.19       chs 		return EINVAL;
    280          1.19       chs 
    281          1.19       chs 	NETBSD32TOP_UAP(head, struct robust_list_head);
    282          1.19       chs 	NETBSD32TOX64_UAP(len, size_t);
    283          1.19       chs 
    284          1.19       chs 	led = l->l_emuldata;
    285          1.19       chs 	led->led_robust_head = SCARG(&ua, head);
    286          1.19       chs 	*retval = 0;
    287          1.19       chs 	return 0;
    288          1.19       chs }
    289          1.19       chs 
    290          1.19       chs int
    291          1.19       chs linux32_sys_get_robust_list(struct lwp *l,
    292          1.19       chs     const struct linux32_sys_get_robust_list_args *uap, register_t *retval)
    293          1.19       chs {
    294          1.19       chs 	/* {
    295  1.23.4.1.6.1    martin 		syscallarg(linux32_pid_t) pid;
    296          1.19       chs 		syscallarg(linux32_robust_list_headpp_t) head;
    297          1.19       chs 		syscallarg(linux32_sizep_t) len;
    298          1.19       chs 	} */
    299          1.19       chs 	struct linux_sys_get_robust_list_args ua;
    300          1.19       chs 
    301  1.23.4.1.6.1    martin 	NETBSD32TOX_UAP(pid, int);
    302          1.19       chs 	NETBSD32TOP_UAP(head, struct robust_list_head *);
    303          1.20       chs 	NETBSD32TOP_UAP(len, size_t *);
    304          1.19       chs 	return linux_sys_get_robust_list(l, &ua, retval);
    305          1.19       chs }
    306          1.20       chs 
    307          1.20       chs int
    308          1.20       chs linux32_sys_truncate64(struct lwp *l, const struct linux32_sys_truncate64_args *uap, register_t *retval)
    309          1.20       chs {
    310          1.20       chs 	/* {
    311          1.20       chs 		syscallarg(netbsd32_charp) path;
    312          1.20       chs 		syscallarg(off_t) length;
    313          1.20       chs 	} */
    314          1.20       chs 	struct sys_truncate_args ua;
    315          1.20       chs 
    316          1.20       chs 	/* Linux doesn't have the 'pad' pseudo-parameter */
    317          1.20       chs 	NETBSD32TOP_UAP(path, const char *);
    318          1.20       chs 	SCARG(&ua, PAD) = 0;
    319          1.20       chs 	SCARG(&ua, length) = ((off_t)SCARG(uap, lenhi) << 32) + SCARG(uap, lenlo);
    320          1.20       chs 	return sys_truncate(l, &ua, retval);
    321          1.20       chs }
    322          1.20       chs 
    323          1.20       chs int
    324          1.20       chs linux32_sys_ftruncate64(struct lwp *l, const struct linux32_sys_ftruncate64_args *uap, register_t *retval)
    325          1.20       chs {
    326          1.20       chs 	/* {
    327          1.20       chs 		syscallarg(unsigned int) fd;
    328          1.20       chs 		syscallarg(off_t) length;
    329          1.20       chs 	} */
    330          1.20       chs 	struct sys_ftruncate_args ua;
    331          1.20       chs 
    332          1.20       chs 	/* Linux doesn't have the 'pad' pseudo-parameter */
    333          1.20       chs 	NETBSD32TO64_UAP(fd);
    334          1.20       chs 	SCARG(&ua, PAD) = 0;
    335          1.20       chs 	SCARG(&ua, length) = ((off_t)SCARG(uap, lenhi) << 32) + SCARG(uap, lenlo);
    336          1.20       chs 	return sys_ftruncate(l, &ua, retval);
    337          1.20       chs }
    338          1.20       chs 
    339          1.20       chs int
    340          1.20       chs linux32_sys_setdomainname(struct lwp *l, const struct linux32_sys_setdomainname_args *uap, register_t *retval)
    341          1.20       chs {
    342          1.20       chs 	/* {
    343          1.20       chs 		syscallarg(netbsd32_charp) domainname;
    344          1.20       chs 		syscallarg(int) len;
    345          1.20       chs 	} */
    346          1.20       chs 	struct linux_sys_setdomainname_args ua;
    347          1.20       chs 
    348          1.20       chs 	NETBSD32TOP_UAP(domainname, char);
    349          1.20       chs 	NETBSD32TO64_UAP(len);
    350          1.20       chs 	return linux_sys_setdomainname(l, &ua, retval);
    351          1.20       chs }
    352