Index: head/sys/amd64/linux/syscalls.master =================================================================== --- head/sys/amd64/linux/syscalls.master (revision 367772) +++ head/sys/amd64/linux/syscalls.master (revision 367773) @@ -1,2055 +1,2065 @@ $FreeBSD$ ; @(#)syscalls.master 8.1 (Berkeley) 7/19/93 ; System call name/number master file (or rather, slave, from LINUX). ; Processed to create linux_sysent.c, linux_proto.h and linux_syscall.h. ; Columns: number audit type nargs name alt{name,tag,rtyp}/comments ; number system call number, must be in order ; audit the audit event associated with the system call ; A value of AUE_NULL means no auditing, but it also means that ; there is no audit event for the call at this time. For the ; case where the event exists, but we don't want auditing, the ; event should be #defined to AUE_NULL in audit_kevents.h. ; type one of STD, NOPROTO, UNIMPL ; name pseudo-prototype of syscall routine ; If one of the following alts is different, then all appear: ; altname name of system call if different ; alttag name of args struct tag if different from [o]`name'"_args" ; altrtyp return type if not int (bogus - syscalls always return int) ; for UNIMPL, name continues with comments ; types: ; STD always included ; UNIMPL not implemented, placeholder only ; NOPROTO same as STD except do not create structure or ; function prototype in sys/sysproto.h. Does add a ; definition to syscall.h besides adding a sysent. #include #include #include #include #include #include ; Isn't pretty, but there seems to be no other way to trap nosys #define nosys linux_nosys ; #ifdef's, etc. may be included, and are copied to the output files. 0 AUE_NULL NOPROTO { int read( int fd, char *buf, l_size_t nbyte ); } 1 AUE_NULL NOPROTO { int write( int fd, char *buf, l_size_t nbyte ); } 2 AUE_OPEN_RWTC STD { int linux_open( char *path, l_int flags, l_mode_t mode ); } 3 AUE_CLOSE NOPROTO { int close( int fd ); } 4 AUE_STAT STD { int linux_newstat( char *path, struct l_newstat *buf ); } 5 AUE_FSTAT STD { int linux_newfstat( l_uint fd, struct l_newstat *buf ); } 6 AUE_LSTAT STD { int linux_newlstat( char *path, struct l_newstat *buf ); } 7 AUE_POLL NOPROTO { int poll( struct pollfd *fds, u_int nfds, int timeout ); } 8 AUE_LSEEK STD { int linux_lseek( l_uint fdes, l_off_t off, l_int whence ); } 9 AUE_MMAP STD { int linux_mmap2( l_ulong addr, l_ulong len, l_ulong prot, l_ulong flags, l_ulong fd, l_ulong pgoff ); } 10 AUE_MPROTECT STD { int linux_mprotect( l_ulong addr, l_size_t len, l_ulong prot ); } 11 AUE_MUNMAP NOPROTO { int munmap( void *addr, l_size_t len ); } 12 AUE_NULL STD { int linux_brk( l_ulong dsend ); } 13 AUE_NULL STD { int linux_rt_sigaction( l_int sig, l_sigaction_t *act, l_sigaction_t *oact, l_size_t sigsetsize ); } 14 AUE_NULL STD { int linux_rt_sigprocmask( l_int how, l_sigset_t *mask, l_sigset_t *omask, l_size_t sigsetsize ); } 15 AUE_NULL STD { int linux_rt_sigreturn( struct l_ucontext *ucp ); } 16 AUE_IOCTL STD { int linux_ioctl( l_uint fd, l_uint cmd, l_ulong arg ); } 17 AUE_PREAD STD { int linux_pread( l_uint fd, char *buf, l_size_t nbyte, l_loff_t offset ); } 18 AUE_PWRITE STD { int linux_pwrite( l_uint fd, char *buf, l_size_t nbyte, l_loff_t offset ); } 19 AUE_READV NOPROTO { int readv( int fd, struct iovec *iovp, u_int iovcnt ); } 20 AUE_WRITEV NOPROTO { int writev( int fd, struct iovec *iovp, u_int iovcnt ); } 21 AUE_ACCESS STD { int linux_access( char *path, l_int amode ); } 22 AUE_PIPE STD { int linux_pipe( l_int *pipefds ); } 23 AUE_SELECT STD { int linux_select( l_int nfds, l_fd_set *readfds, l_fd_set *writefds, l_fd_set *exceptfds, struct l_timeval *timeout ); } 24 AUE_NULL NOPROTO { int sched_yield(void); } 25 AUE_NULL STD { int linux_mremap( l_ulong addr, l_ulong old_len, l_ulong new_len, l_ulong flags, l_ulong new_addr ); } 26 AUE_MSYNC STD { int linux_msync( l_ulong addr, l_size_t len, l_int fl ); } 27 AUE_MINCORE STD { int linux_mincore( l_ulong start, l_size_t len, u_char *vec ); } 28 AUE_MADVISE STD { int linux_madvise( l_ulong addr, l_size_t len, l_int behav ); } 29 AUE_NULL STD { int linux_shmget( l_key_t key, l_size_t size, l_int shmflg ); } 30 AUE_NULL STD { int linux_shmat( l_int shmid, char *shmaddr, l_int shmflg ); } 31 AUE_NULL STD { int linux_shmctl( l_int shmid, l_int cmd, struct l_shmid_ds *buf ); } 32 AUE_DUP NOPROTO { int dup( u_int fd ); } 33 AUE_DUP2 NOPROTO { int dup2( u_int from, u_int to ); } 34 AUE_NULL STD { int linux_pause(void); } 35 AUE_NULL STD { int linux_nanosleep( const struct l_timespec *rqtp, struct l_timespec *rmtp ); } 36 AUE_GETITIMER STD { int linux_getitimer( l_int which, struct l_itimerval *itv ); } 37 AUE_NULL STD { int linux_alarm( l_uint secs ); } 38 AUE_SETITIMER STD { int linux_setitimer( l_int which, struct l_itimerval *itv, struct l_itimerval *oitv ); } 39 AUE_GETPID STD { int linux_getpid(void); } 40 AUE_SENDFILE STD { int linux_sendfile( l_int out, l_int in, l_off_t *offset, l_size_t count ); } 41 AUE_SOCKET STD { int linux_socket( l_int domain, l_int type, l_int protocol ); } 42 AUE_CONNECT STD { int linux_connect( l_int s, l_uintptr_t name, l_int namelen ); } 43 AUE_ACCEPT STD { int linux_accept( l_int s, l_uintptr_t addr, l_uintptr_t namelen ); } 44 AUE_SENDTO STD { int linux_sendto( l_int s, l_uintptr_t msg, l_size_t len, l_uint flags, l_uintptr_t to, l_int tolen ); } 45 AUE_RECVFROM STD { int linux_recvfrom( l_int s, l_uintptr_t buf, l_size_t len, l_uint flags, l_uintptr_t from, l_uintptr_t fromlen ); } 46 AUE_SENDMSG STD { int linux_sendmsg( l_int s, l_uintptr_t msg, l_uint flags ); } 47 AUE_RECVMSG STD { int linux_recvmsg( l_int s, l_uintptr_t msg, l_uint flags ); } 48 AUE_NULL STD { int linux_shutdown( l_int s, l_int how ); } 49 AUE_BIND STD { int linux_bind( l_int s, l_uintptr_t name, l_int namelen ); } 50 AUE_LISTEN STD { int linux_listen( l_int s, l_int backlog ); } 51 AUE_GETSOCKNAME STD { int linux_getsockname( l_int s, l_uintptr_t addr, l_uintptr_t namelen ); } 52 AUE_GETPEERNAME STD { int linux_getpeername( l_int s, l_uintptr_t addr, l_uintptr_t namelen ); } 53 AUE_SOCKETPAIR STD { int linux_socketpair( l_int domain, l_int type, l_int protocol, l_uintptr_t rsv ); } 54 AUE_SETSOCKOPT STD { int linux_setsockopt( l_int s, l_int level, l_int optname, l_uintptr_t optval, l_int optlen ); } 55 AUE_GETSOCKOPT STD { int linux_getsockopt( l_int s, l_int level, l_int optname, l_uintptr_t optval, l_uintptr_t optlen ); } 56 AUE_RFORK STD { int linux_clone( l_ulong flags, void *stack, void *parent_tidptr, void *child_tidptr, void *tls ); } 57 AUE_FORK STD { int linux_fork(void); } 58 AUE_VFORK STD { int linux_vfork(void); } 59 AUE_EXECVE STD { int linux_execve( char *path, char **argp, char **envp ); } 60 AUE_EXIT STD { void linux_exit( l_int rval ); } 61 AUE_WAIT4 STD { int linux_wait4( l_pid_t pid, l_int *status, l_int options, struct rusage *rusage ); } 62 AUE_KILL STD { int linux_kill( l_pid_t pid, l_int signum ); } 63 AUE_NULL STD { int linux_newuname( struct l_new_utsname *buf ); } 64 AUE_NULL STD { int linux_semget( l_key_t key, l_int nsems, l_int semflg ); } 65 AUE_NULL STD { int linux_semop( l_int semid, struct l_sembuf *tsops, l_uint nsops ); } 66 AUE_NULL STD { int linux_semctl( l_int semid, l_int semnum, l_int cmd, union l_semun arg ); } 67 AUE_NULL STD { int linux_shmdt( char *shmaddr ); } 68 AUE_NULL STD { int linux_msgget( l_key_t key, l_int msgflg ); } 69 AUE_NULL STD { int linux_msgsnd( l_int msqid, struct l_msgbuf *msgp, l_size_t msgsz, l_int msgflg ); } 70 AUE_NULL STD { int linux_msgrcv( l_int msqid, struct l_msgbuf *msgp, l_size_t msgsz, l_long msgtyp, l_int msgflg ); } 71 AUE_NULL STD { int linux_msgctl( l_int msqid, l_int cmd, struct l_msqid_ds *buf ); } 72 AUE_FCNTL STD { int linux_fcntl( l_uint fd, l_uint cmd, l_ulong arg ); } 73 AUE_FLOCK NOPROTO { int flock( int fd, int how ); } 74 AUE_FSYNC NOPROTO { int fsync( int fd ); } 75 AUE_NULL STD { int linux_fdatasync( l_uint fd ); } 76 AUE_TRUNCATE STD { int linux_truncate( char *path, l_long length ); } 77 AUE_FTRUNCATE STD { int linux_ftruncate( l_int fd, l_ulong length ); } 78 AUE_GETDIRENTRIES STD { int linux_getdents( l_uint fd, void *dent, l_uint count ); } 79 AUE_GETCWD STD { int linux_getcwd( char *buf, l_ulong bufsize ); } 80 AUE_CHDIR STD { int linux_chdir( char *path ); } 81 AUE_FCHDIR NOPROTO { int fchdir( int fd ); } 82 AUE_RENAME STD { int linux_rename( char *from, char *to ); } 83 AUE_MKDIR STD { int linux_mkdir( char *path, l_mode_t mode ); } 84 AUE_RMDIR STD { int linux_rmdir( char *path ); } 85 AUE_CREAT STD { int linux_creat( char *path, l_mode_t mode ); } 86 AUE_LINK STD { int linux_link( char *path, char *to ); } 87 AUE_UNLINK STD { int linux_unlink( char *path ); } 88 AUE_SYMLINK STD { int linux_symlink( char *path, char *to ); } 89 AUE_READLINK STD { int linux_readlink( char *name, char *buf, l_int count ); } 90 AUE_CHMOD STD { int linux_chmod( char *path, l_mode_t mode ); } 91 AUE_FCHMOD NOPROTO { int fchmod( int fd, int mode ); } 92 AUE_LCHOWN STD { int linux_chown( char *path, l_uid_t uid, l_gid_t gid ); } 93 AUE_FCHOWN NOPROTO { int fchown( int fd, int uid, int gid ); } 94 AUE_LCHOWN STD { int linux_lchown( char *path, l_uid_t uid, l_gid_t gid ); } 95 AUE_UMASK NOPROTO { int umask( int newmask ); } 96 AUE_NULL NOPROTO { int gettimeofday( struct l_timeval *tp, struct timezone *tzp ); } 97 AUE_GETRLIMIT STD { int linux_getrlimit( l_uint resource, struct l_rlimit *rlim ); } 98 AUE_GETRUSAGE NOPROTO { int getrusage( int who, struct rusage *rusage ); } 99 AUE_NULL STD { int linux_sysinfo( struct l_sysinfo *info ); } 100 AUE_NULL STD { int linux_times( struct l_times_argv *buf ); } 101 AUE_PTRACE STD { int linux_ptrace( l_long req, l_long pid, l_ulong addr, l_ulong data ); } 102 AUE_GETUID STD { int linux_getuid(void); } 103 AUE_NULL STD { int linux_syslog( l_int type, char *buf, l_int len ); } 104 AUE_GETGID STD { int linux_getgid(void); } 105 AUE_SETUID NOPROTO { int setuid( uid_t uid ); } 106 AUE_SETGID NOPROTO { int setgid( gid_t gid ); } 107 AUE_GETEUID NOPROTO { int geteuid(void); } 108 AUE_GETEGID NOPROTO { int getegid(void); } 109 AUE_SETPGRP NOPROTO { int setpgid( int pid, int pgid ); } 110 AUE_GETPPID STD { int linux_getppid(void); } 111 AUE_GETPGRP NOPROTO { int getpgrp(void); } 112 AUE_SETSID NOPROTO { int setsid(void); } 113 AUE_SETREUID NOPROTO { int setreuid( uid_t ruid, uid_t euid ); } 114 AUE_SETREGID NOPROTO { int setregid( gid_t rgid, gid_t egid ); } 115 AUE_GETGROUPS STD { int linux_getgroups( l_int gidsetsize, l_gid_t *grouplist ); } 116 AUE_SETGROUPS STD { int linux_setgroups( l_int gidsetsize, l_gid_t *grouplist ); } 117 AUE_SETRESUID NOPROTO { int setresuid( uid_t ruid, uid_t euid, uid_t suid ); } 118 AUE_GETRESUID NOPROTO { int getresuid( uid_t *ruid, uid_t *euid, uid_t *suid ); } 119 AUE_SETRESGID NOPROTO { int setresgid( gid_t rgid, gid_t egid, gid_t sgid ); } 120 AUE_GETRESGID NOPROTO { int getresgid( gid_t *rgid, gid_t *egid, gid_t *sgid ); } 121 AUE_GETPGID NOPROTO { int getpgid( int pid ); } 122 AUE_SETFSUID STD { int linux_setfsuid( l_uid_t uid ); } 123 AUE_SETFSGID STD { int linux_setfsgid( l_gid_t gid ); } 124 AUE_GETSID STD { int linux_getsid( l_pid_t pid ); } 125 AUE_CAPGET STD { int linux_capget( struct l_user_cap_header *hdrp, struct l_user_cap_data *datap ); } 126 AUE_CAPSET STD { int linux_capset( struct l_user_cap_header *hdrp, struct l_user_cap_data *datap ); } 127 AUE_NULL STD { int linux_rt_sigpending( l_sigset_t *set, l_size_t sigsetsize ); } 128 AUE_NULL STD { int linux_rt_sigtimedwait( l_sigset_t *mask, l_siginfo_t *ptr, struct l_timeval *timeout, l_size_t sigsetsize ); } 129 AUE_NULL STD { int linux_rt_sigqueueinfo( l_pid_t pid, l_int sig, l_siginfo_t *info ); } 130 AUE_NULL STD { int linux_rt_sigsuspend( l_sigset_t *newset, l_size_t sigsetsize ); } 131 AUE_NULL STD { int linux_sigaltstack( l_stack_t *uss, l_stack_t *uoss ); } 132 AUE_UTIME STD { int linux_utime( char *fname, struct l_utimbuf *times ); } 133 AUE_MKNOD STD { int linux_mknod( char *path, l_mode_t mode, l_uint dev ); } 134 AUE_USELIB UNIMPL uselib 135 AUE_PERSONALITY STD { int linux_personality( l_uint per ); } 136 AUE_NULL STD { int linux_ustat( l_uint dev, struct l_ustat *ubuf ); } 137 AUE_STATFS STD { int linux_statfs( char *path, struct l_statfs_buf *buf ); } 138 AUE_FSTATFS STD { int linux_fstatfs( l_uint fd, struct l_statfs_buf *buf ); } 139 AUE_NULL STD { int linux_sysfs( l_int option, l_ulong arg1, l_ulong arg2 ); } 140 AUE_GETPRIORITY STD { int linux_getpriority( l_int which, l_int who ); } 141 AUE_SETPRIORITY NOPROTO { int setpriority( int which, int who, int prio ); } 142 AUE_SCHED_SETPARAM STD { int linux_sched_setparam( l_pid_t pid, struct sched_param *param ); } 143 AUE_SCHED_GETPARAM STD { int linux_sched_getparam( l_pid_t pid, struct sched_param *param ); } 144 AUE_SCHED_SETSCHEDULER STD { int linux_sched_setscheduler( l_pid_t pid, l_int policy, struct sched_param *param ); } 145 AUE_SCHED_GETSCHEDULER STD { int linux_sched_getscheduler( l_pid_t pid ); } 146 AUE_SCHED_GET_PRIORITY_MAX STD { int linux_sched_get_priority_max( l_int policy ); } 147 AUE_SCHED_GET_PRIORITY_MIN STD { int linux_sched_get_priority_min( l_int policy ); } 148 AUE_SCHED_RR_GET_INTERVAL STD { int linux_sched_rr_get_interval( l_pid_t pid, struct l_timespec *interval ); } 149 AUE_MLOCK NOPROTO { int mlock( const void *addr, size_t len ); } 150 AUE_MUNLOCK NOPROTO { int munlock( const void *addr, size_t len ); } 151 AUE_MLOCKALL NOPROTO { int mlockall( int how ); } 152 AUE_MUNLOCKALL NOPROTO { int munlockall(void); } 153 AUE_NULL STD { int linux_vhangup(void); } 154 AUE_NULL STD { int linux_modify_ldt(void); } 155 AUE_PIVOT_ROOT STD { int linux_pivot_root(void); } 156 AUE_SYSCTL STD { int linux_sysctl( struct l___sysctl_args *args ); } 157 AUE_PRCTL STD { int linux_prctl( l_int option, l_uintptr_t arg2, l_uintptr_t arg3, l_uintptr_t arg4, l_uintptr_t arg5 ); } 158 AUE_PRCTL STD { int linux_arch_prctl( l_int code, l_ulong addr ); } 159 AUE_ADJTIME STD { int linux_adjtimex(void); } 160 AUE_SETRLIMIT STD { int linux_setrlimit( l_uint resource, struct l_rlimit *rlim ); } 161 AUE_CHROOT NOPROTO { int chroot( char *path ); } 162 AUE_SYNC NOPROTO { int sync(void); } 163 AUE_ACCT NOPROTO { int acct( char *path ); } 164 AUE_SETTIMEOFDAY NOPROTO { int settimeofday( struct l_timeval *tv, struct timezone *tzp ); } 165 AUE_MOUNT STD { int linux_mount( char *specialfile, char *dir, char *filesystemtype, l_ulong rwflag, void *data ); } 166 AUE_UMOUNT STD { int linux_umount( char *path, l_int flags ); } 167 AUE_SWAPON NOPROTO { int swapon( char *name ); } 168 AUE_SWAPOFF STD { int linux_swapoff(void); } 169 AUE_REBOOT STD { int linux_reboot( l_int magic1, l_int magic2, l_uint cmd, void *arg ); } 170 AUE_SYSCTL STD { int linux_sethostname( char *hostname, l_int len ); } 171 AUE_SYSCTL STD { int linux_setdomainname( char *name, l_int len ); } 172 AUE_NULL STD { int linux_iopl( l_uint level ); } 173 AUE_NULL STD { int linux_ioperm(void); } 174 AUE_NULL UNIMPL create_module 175 AUE_NULL STD { int linux_init_module(void); } 176 AUE_NULL STD { int linux_delete_module(void); } 177 AUE_NULL UNIMPL get_kernel_syms 178 AUE_NULL UNIMPL query_module 179 AUE_QUOTACTL STD { int linux_quotactl(void); } 180 AUE_NULL UNIMPL nfsservctl 181 AUE_GETPMSG UNIMPL getpmsg 182 AUE_PUTPMSG UNIMPL putpmsg 183 AUE_NULL UNIMPL afs_syscall 184 AUE_NULL UNIMPL tuxcall 185 AUE_NULL UNIMPL security 186 AUE_NULL STD { int linux_gettid(void); } 187 AUE_NULL STD { int linux_readahead(void); } 188 AUE_NULL STD { int linux_setxattr( const char *path, const char *name, const char *value, l_size_t size, l_int flags ); } 189 AUE_NULL STD { int linux_lsetxattr( const char *path, const char *name, const char *value, l_size_t size, l_int flags ); } 190 AUE_NULL STD { int linux_fsetxattr( l_int fd, const char *name, const char *value, l_size_t size, l_int flags ); } 191 AUE_NULL STD { int linux_getxattr( const char *path, const char *name, char *value, l_size_t size ); } 192 AUE_NULL STD { int linux_lgetxattr( const char *path, const char *name, char *value, l_size_t size ); } 193 AUE_NULL STD { int linux_fgetxattr( l_int fd, const char *name, char *value, l_size_t size ); } 194 AUE_NULL STD { int linux_listxattr( const char *path, const char *list, l_size_t size ); } 195 AUE_NULL STD { int linux_llistxattr( const char *path, const char *list, l_size_t size ); } 196 AUE_NULL STD { int linux_flistxattr( l_int fd, const char *list, l_size_t size ); } 197 AUE_NULL STD { int linux_removexattr( const char *path, const char *name ); } 198 AUE_NULL STD { int linux_lremovexattr( const char *path, const char *name ); } 199 AUE_NULL STD { int linux_fremovexattr( l_int fd, const char *name ); } 200 AUE_NULL STD { int linux_tkill( l_pid_t tid, l_int sig ); } 201 AUE_NULL STD { int linux_time( l_time_t *tm ); } 202 AUE_NULL STD { int linux_sys_futex( void *uaddr, l_int op, l_int val, struct l_timespec *timeout, void *uaddr2, l_int val3 ); } 203 AUE_NULL STD { int linux_sched_setaffinity( l_pid_t pid, l_uint len, l_ulong *user_mask_ptr ); } 204 AUE_NULL STD { int linux_sched_getaffinity( l_pid_t pid, l_uint len, l_ulong *user_mask_ptr ); } 205 AUE_NULL UNIMPL set_thread_area 206 AUE_NULL STD { int linux_io_setup(void); } 207 AUE_NULL STD { int linux_io_destroy(void); } 208 AUE_NULL STD { int linux_io_getevents(void); } 209 AUE_NULL STD { int linux_io_submit(void); } 210 AUE_NULL STD { int linux_io_cancel(void); } 211 AUE_NULL UNIMPL get_thread_area 212 AUE_NULL STD { int linux_lookup_dcookie(void); } 213 AUE_NULL STD { int linux_epoll_create( l_int size ); } 214 AUE_NULL UNIMPL epoll_ctl_old 215 AUE_NULL UNIMPL epoll_wait_old 216 AUE_NULL STD { int linux_remap_file_pages(void); } 217 AUE_GETDIRENTRIES STD { int linux_getdents64( l_uint fd, void *dirent, l_uint count ); } 218 AUE_NULL STD { int linux_set_tid_address( l_int *tidptr ); } 219 AUE_NULL STD { int linux_restart_syscall(void); } 220 AUE_NULL STD { int linux_semtimedop(void); } 221 AUE_NULL STD { int linux_fadvise64( l_int fd, l_loff_t offset, l_size_t len, l_int advice ); } 222 AUE_NULL STD { int linux_timer_create( clockid_t clock_id, struct sigevent *evp, l_timer_t *timerid ); } 223 AUE_NULL STD { int linux_timer_settime( l_timer_t timerid, l_int flags, const struct itimerspec *new, struct itimerspec *old ); } 224 AUE_NULL STD { int linux_timer_gettime( l_timer_t timerid, struct itimerspec *setting ); } 225 AUE_NULL STD { int linux_timer_getoverrun( l_timer_t timerid ); } 226 AUE_NULL STD { int linux_timer_delete( l_timer_t timerid ); } 227 AUE_CLOCK_SETTIME STD { int linux_clock_settime( clockid_t which, struct l_timespec *tp ); } 228 AUE_NULL STD { int linux_clock_gettime( clockid_t which, struct l_timespec *tp ); } 229 AUE_NULL STD { int linux_clock_getres( clockid_t which, struct l_timespec *tp ); } 230 AUE_NULL STD { int linux_clock_nanosleep( clockid_t which, l_int flags, struct l_timespec *rqtp, struct l_timespec *rmtp ); } 231 AUE_EXIT STD { int linux_exit_group( l_int error_code ); } 232 AUE_NULL STD { int linux_epoll_wait( l_int epfd, struct epoll_event *events, l_int maxevents, l_int timeout ); } 233 AUE_NULL STD { int linux_epoll_ctl( l_int epfd, l_int op, l_int fd, struct epoll_event *event ); } 234 AUE_NULL STD { int linux_tgkill( l_pid_t tgid, l_pid_t pid, l_int sig ); } 235 AUE_UTIMES STD { int linux_utimes( char *fname, struct l_timeval *tptr ); } 236 AUE_NULL UNIMPL vserver 237 AUE_NULL STD { int linux_mbind(void); } 238 AUE_NULL STD { int linux_set_mempolicy(void); } 239 AUE_NULL STD { int linux_get_mempolicy(void); } 240 AUE_NULL STD { int linux_mq_open( const char *name, l_int oflag, l_mode_t mode, struct mq_attr *attr ); } 241 AUE_NULL STD { int linux_mq_unlink( const char *name ); } 242 AUE_NULL STD { int linux_mq_timedsend( l_mqd_t mqd, const char *msg_ptr, l_size_t msg_len, l_uint msg_prio, const struct l_timespec *abs_timeout ); } 243 AUE_NULL STD { int linux_mq_timedreceive( l_mqd_t mqd, char *msg_ptr, l_size_t msg_len, l_uint *msg_prio, const struct l_timespec *abs_timeout ); } 244 AUE_NULL STD { int linux_mq_notify( l_mqd_t mqd, const struct l_timespec *abs_timeout ); } 245 AUE_NULL STD { int linux_mq_getsetattr( l_mqd_t mqd, const struct mq_attr *attr, struct mq_attr *oattr ); } 246 AUE_NULL STD { int linux_kexec_load(void); } 247 AUE_WAIT6 STD { int linux_waitid( l_int idtype, l_pid_t id, l_siginfo_t *info, l_int options, struct rusage *rusage ); } 248 AUE_NULL STD { int linux_add_key(void); } 249 AUE_NULL STD { int linux_request_key(void); } 250 AUE_NULL STD { int linux_keyctl(void); } 251 AUE_NULL STD { int linux_ioprio_set(void); } 252 AUE_NULL STD { int linux_ioprio_get(void); } 253 AUE_NULL STD { int linux_inotify_init(void); } 254 AUE_NULL STD { int linux_inotify_add_watch(void); } 255 AUE_NULL STD { int linux_inotify_rm_watch(void); } 256 AUE_NULL STD { int linux_migrate_pages(void); } 257 AUE_OPEN_RWTC STD { int linux_openat( l_int dfd, const char *filename, l_int flags, l_mode_t mode ); } 258 AUE_MKDIRAT STD { int linux_mkdirat( l_int dfd, const char *pathname, l_mode_t mode ); } 259 AUE_MKNODAT STD { int linux_mknodat( l_int dfd, const char *filename, l_mode_t mode, l_uint dev ); } 260 AUE_FCHOWNAT STD { int linux_fchownat( l_int dfd, const char *filename, l_uid_t uid, l_gid_t gid, l_int flag ); } 261 AUE_FUTIMESAT STD { int linux_futimesat( l_int dfd, char *filename, struct l_timeval *utimes ); } 262 AUE_FSTATAT STD { int linux_newfstatat( l_int dfd, char *pathname, struct l_stat64 *statbuf, l_int flag ); } 263 AUE_UNLINKAT STD { int linux_unlinkat( l_int dfd, const char *pathname, l_int flag ); } 264 AUE_RENAMEAT STD { int linux_renameat( l_int olddfd, const char *oldname, l_int newdfd, const char *newname ); } 265 AUE_LINKAT STD { int linux_linkat( l_int olddfd, const char *oldname, l_int newdfd, const char *newname, l_int flag ); } 266 AUE_SYMLINKAT STD { int linux_symlinkat( const char *oldname, l_int newdfd, const char *newname ); } 267 AUE_READLINKAT STD { int linux_readlinkat( l_int dfd, const char *path, char *buf, l_int bufsiz ); } 268 AUE_FCHMODAT STD { int linux_fchmodat( l_int dfd, const char *filename, l_mode_t mode ); } 269 AUE_FACCESSAT STD { int linux_faccessat( l_int dfd, const char *filename, l_int amode ); } 270 AUE_SELECT STD { int linux_pselect6( l_int nfds, l_fd_set *readfds, l_fd_set *writefds, l_fd_set *exceptfds, struct l_timespec *tsp, l_uintptr_t *sig ); } 271 AUE_POLL STD { int linux_ppoll( struct pollfd *fds, l_uint nfds, struct l_timespec *tsp, l_sigset_t *sset, l_size_t ssize ); } 272 AUE_NULL STD { int linux_unshare(void); } 273 AUE_NULL STD { int linux_set_robust_list( struct linux_robust_list_head *head, l_size_t len ); } 274 AUE_NULL STD { int linux_get_robust_list( l_int pid, struct linux_robust_list_head **head, l_size_t *len ); } 275 AUE_NULL STD { int linux_splice( int fd_in, l_loff_t *off_in, int fd_out, l_loff_t *off_out, l_size_t len, l_uint flags ); } 276 AUE_NULL STD { int linux_tee(void); } 277 AUE_NULL STD { int linux_sync_file_range( l_int fd, l_loff_t offset, l_loff_t nbytes, l_uint flags ); } 278 AUE_NULL STD { int linux_vmsplice(void); } 279 AUE_NULL STD { int linux_move_pages(void); } 280 AUE_FUTIMESAT STD { int linux_utimensat( l_int dfd, const char *pathname, const struct l_timespec *times, l_int flags ); } 281 AUE_NULL STD { int linux_epoll_pwait( l_int epfd, struct epoll_event *events, l_int maxevents, l_int timeout, l_sigset_t *mask, l_size_t sigsetsize ); } 282 AUE_NULL STD { int linux_signalfd(void); } 283 AUE_NULL STD { int linux_timerfd_create( l_int clockid, l_int flags ); } 284 AUE_NULL STD { int linux_eventfd( l_uint initval ); } 285 AUE_NULL STD { int linux_fallocate( l_int fd, l_int mode, l_loff_t offset, l_loff_t len ); } 286 AUE_NULL STD { int linux_timerfd_settime( l_int fd, l_int flags, const struct l_itimerspec *new_value, struct l_itimerspec *old_value ); } 287 AUE_NULL STD { int linux_timerfd_gettime( l_int fd, struct l_itimerspec *old_value ); } 288 AUE_ACCEPT STD { int linux_accept4( l_int s, l_uintptr_t addr, l_uintptr_t namelen, l_int flags ); } ; Linux 2.6.27: 289 AUE_NULL STD { int linux_signalfd4(void); } 290 AUE_NULL STD { int linux_eventfd2( l_uint initval, l_int flags ); } 291 AUE_NULL STD { int linux_epoll_create1( l_int flags ); } 292 AUE_NULL STD { int linux_dup3( l_uint oldfd, l_uint newfd, l_int flags ); } 293 AUE_NULL STD { int linux_pipe2( l_int *pipefds, l_int flags ); } 294 AUE_NULL STD { int linux_inotify_init1( l_int flags ); } ; Linux 2.6.30: 295 AUE_NULL STD { int linux_preadv( l_ulong fd, struct iovec *vec, l_ulong vlen, l_ulong pos_l, l_ulong pos_h ); } 296 AUE_NULL STD { int linux_pwritev( l_ulong fd, struct iovec *vec, l_ulong vlen, l_ulong pos_l, l_ulong pos_h ); } ; Linux 2.6.31: 297 AUE_NULL STD { int linux_rt_tgsigqueueinfo( l_pid_t tgid, l_pid_t tid, l_int sig, l_siginfo_t *uinfo ); } 298 AUE_NULL STD { int linux_perf_event_open(void); } ; Linux 2.6.33: 299 AUE_NULL STD { int linux_recvmmsg( l_int s, struct l_mmsghdr *msg, l_uint vlen, l_uint flags, struct l_timespec *timeout ); } ; Linux 2.6.37: 300 AUE_NULL STD { int linux_fanotify_init(void); } 301 AUE_NULL STD { int linux_fanotify_mark(void); } ; Linux 2.6.36: 302 AUE_NULL STD { int linux_prlimit64( l_pid_t pid, l_uint resource, struct rlimit *new, struct rlimit *old ); } ; Linux 2.6.39 (glibc 2.14): 303 AUE_NULL STD { - int linux_name_to_handle_at(void); + int linux_name_to_handle_at( + l_int dirfd, + const char *name, + struct l_file_handle *handle, + l_int *mnt_id, + l_int flags + ); } 304 AUE_NULL STD { - int linux_open_by_handle_at(void); + int linux_open_by_handle_at( + l_int mountdirfd, + struct l_file_handle *handle, + l_int flags + ); } 305 AUE_NULL STD { int linux_clock_adjtime(void); } 306 AUE_SYNC STD { int linux_syncfs( l_int fd ); } ; Linux 3.0 (glibc 2.14): 307 AUE_NULL STD { int linux_sendmmsg( l_int s, struct l_mmsghdr *msg, l_uint vlen, l_uint flags ); } 308 AUE_NULL STD { int linux_setns( l_int fd, l_int nstype ); } ; Linux 2.6.19 (no glibc wrapper): 309 AUE_NULL STD { int linux_getcpu( l_uint *cpu, l_uint *node, void *cache ); } ; Linux 3.2 (glibc 2.15): 310 AUE_NULL STD { int linux_process_vm_readv( l_pid_t pid, const struct iovec *lvec, l_ulong liovcnt, const struct iovec *rvec, l_ulong riovcnt, l_ulong flags ); } 311 AUE_NULL STD { int linux_process_vm_writev( l_pid_t pid, const struct iovec *lvec, l_ulong liovcnt, const struct iovec *rvec, l_ulong riovcnt, l_ulong flags ); } ; Linux 3.5 (no glibc wrapper): 312 AUE_NULL STD { int linux_kcmp( l_pid_t pid1, l_pid_t pid2, l_int type, l_ulong idx1, l_ulong idx ); } ; Linux 3.8 (no glibc wrapper): 313 AUE_NULL STD { int linux_finit_module( l_int fd, const char *uargs, l_int flags ); } ; Linux 3.14: 314 AUE_NULL STD { int linux_sched_setattr( l_pid_t pid, void *attr, l_uint flags ); } 315 AUE_NULL STD { int linux_sched_getattr( l_pid_t pid, void *attr, l_uint size, l_uint flags ); } ; Linux 3.15: 316 AUE_NULL STD { int linux_renameat2( l_int olddfd, const char *oldname, l_int newdfd, const char *newname, l_uint flags ); } ; Linux 3.17: 317 AUE_NULL STD { int linux_seccomp( l_uint op, l_uint flags, const char *uargs ); } 318 AUE_NULL STD { int linux_getrandom( char *buf, l_size_t count, l_uint flags ); } 319 AUE_NULL STD { int linux_memfd_create( const char *uname_ptr, l_uint flags ); } 320 AUE_NULL STD { int linux_kexec_file_load( l_int kernel_fd, l_int initrd_fd, l_ulong cmdline_len, const char *cmdline_ptr, l_ulong flags ); } ; Linux 3.18: 321 AUE_NULL STD { int linux_bpf( l_int cmd, void *attr, l_uint size ); } ; Linux 3.19: 322 AUE_NULL STD { int linux_execveat( l_int dfd, const char *filename, const char **argv, const char **envp, l_int flags ); } ; Linux 4.2: 323 AUE_NULL STD { int linux_userfaultfd( l_int flags ); } ; Linux 4.3: 324 AUE_NULL STD { int linux_membarrier( l_int cmd, l_int flags ); } ; Linux 4.4: 325 AUE_NULL STD { int linux_mlock2( l_ulong start, l_size_t len, l_int flags ); } ; Linux 4.5: 326 AUE_NULL STD { int linux_copy_file_range( l_int fd_in, l_loff_t *off_in, l_int fd_out, l_loff_t *off_out, l_size_t len, l_uint flags ); } ; Linux 4.6: 327 AUE_NULL STD { int linux_preadv2( l_ulong fd, const struct iovec *vec, l_ulong vlen, l_ulong pos_l, l_ulong pos_h, l_int flags ); } 328 AUE_NULL STD { int linux_pwritev2( l_ulong fd, const struct iovec *vec, l_ulong vlen, l_ulong pos_l, l_ulong pos_h, l_int flags ); } ; Linux 4.8: 329 AUE_NULL STD { int linux_pkey_mprotect( l_ulong start, l_size_t len, l_ulong prot, l_int pkey ); } 330 AUE_NULL STD { int linux_pkey_alloc( l_ulong flags, l_ulong init_val ); } 331 AUE_NULL STD { int linux_pkey_free( l_int pkey ); } ; Linux 4.11: 332 AUE_NULL STD { int linux_statx( l_int dirfd, const char *pathname, l_uint flags, l_uint mask, void *statxbuf ); } ; Linux 4.18: 333 AUE_NULL STD { int linux_io_pgetevents(void); } 334 AUE_NULL STD { int linux_rseq(void); } ; Linux 5.0: 335-423 AUE_NULL UNIMPL nosys 424 AUE_NULL STD { int linux_pidfd_send_signal( l_int pidfd, l_int sig, l_siginfo_t *info, l_uint flags ); } 425 AUE_NULL STD { int linux_io_uring_setup(void); } 426 AUE_NULL STD { int linux_io_uring_enter(void); } 427 AUE_NULL STD { int linux_io_uring_register(void); } ; please, keep this line at the end. 428 AUE_NULL UNIMPL nosys ; vim: syntax=off Index: head/sys/amd64/linux32/syscalls.master =================================================================== --- head/sys/amd64/linux32/syscalls.master (revision 367772) +++ head/sys/amd64/linux32/syscalls.master (revision 367773) @@ -1,2413 +1,2423 @@ $FreeBSD$ ; @(#)syscalls.master 8.1 (Berkeley) 7/19/93 ; System call name/number master file (or rather, slave, from LINUX). ; Processed to create linux32_sysent.c, linux32_proto.h and linux32_syscall.h. ; Columns: number audit type nargs name alt{name,tag,rtyp}/comments ; number system call number, must be in order ; audit the audit event associated with the system call ; A value of AUE_NULL means no auditing, but it also means that ; there is no audit event for the call at this time. For the ; case where the event exists, but we don't want auditing, the ; event should be #defined to AUE_NULL in audit_kevents.h. ; type one of STD, NOPROTO, UNIMPL ; name pseudo-prototype of syscall routine ; If one of the following alts is different, then all appear: ; altname name of system call if different ; alttag name of args struct tag if different from [o]`name'"_args" ; altrtyp return type if not int (bogus - syscalls always return int) ; for UNIMPL, name continues with comments ; types: ; STD always included ; UNIMPL not implemented, placeholder only ; NOPROTO same as STD except do not create structure or ; function prototype in sys/sysproto.h. Does add a ; definition to syscall.h besides adding a sysent. #include #include #include #include #include #include ; Isn't pretty, but there seems to be no other way to trap nosys #define nosys linux_nosys ; #ifdef's, etc. may be included, and are copied to the output files. 0 AUE_NULL UNIMPL setup 1 AUE_EXIT STD { void linux_exit( int rval ); } 2 AUE_FORK STD { int linux_fork(void); } 3 AUE_NULL NOPROTO { int read( int fd, char *buf, u_int nbyte ); } 4 AUE_NULL NOPROTO { int write( int fd, char *buf, u_int nbyte ); } 5 AUE_OPEN_RWTC STD { int linux_open( char *path, l_int flags, l_int mode ); } 6 AUE_CLOSE NOPROTO { int close( int fd ); } 7 AUE_WAIT4 STD { int linux_waitpid( l_pid_t pid, l_int *status, l_int options ); } 8 AUE_CREAT STD { int linux_creat( char *path, l_int mode ); } 9 AUE_LINK STD { int linux_link( char *path, char *to ); } 10 AUE_UNLINK STD { int linux_unlink( char *path ); } 11 AUE_EXECVE STD { int linux_execve( char *path, uint32_t *argp, uint32_t *envp ); } 12 AUE_CHDIR STD { int linux_chdir( char *path ); } 13 AUE_NULL STD { int linux_time( l_time_t *tm ); } 14 AUE_MKNOD STD { int linux_mknod( char *path, l_int mode, l_dev_t dev ); } 15 AUE_CHMOD STD { int linux_chmod( char *path, l_mode_t mode ); } 16 AUE_LCHOWN STD { int linux_lchown16( char *path, l_uid16_t uid, l_gid16_t gid ); } 17 AUE_NULL UNIMPL break 18 AUE_STAT STD { int linux_stat( char *path, struct linux_stat *up ); } 19 AUE_LSEEK STD { int linux_lseek( l_uint fdes, l_off_t off, l_int whence ); } 20 AUE_GETPID STD { int linux_getpid(void); } 21 AUE_MOUNT STD { int linux_mount( char *specialfile, char *dir, char *filesystemtype, l_ulong rwflag, void *data ); } 22 AUE_UMOUNT STD { int linux_oldumount( char *path ); } 23 AUE_SETUID STD { int linux_setuid16( l_uid16_t uid ); } 24 AUE_GETUID STD { int linux_getuid16(void); } 25 AUE_SETTIMEOFDAY STD { int linux_stime(void); } 26 AUE_PTRACE STD { int linux_ptrace( l_long req, l_long pid, l_long addr, l_long data ); } 27 AUE_NULL STD { int linux_alarm( l_uint secs ); } 28 AUE_FSTAT UNIMPL fstat 29 AUE_NULL STD { int linux_pause(void); } 30 AUE_UTIME STD { int linux_utime( char *fname, struct l_utimbuf *times ); } 31 AUE_NULL UNIMPL stty 32 AUE_NULL UNIMPL gtty 33 AUE_ACCESS STD { int linux_access( char *path, l_int amode ); } 34 AUE_NICE STD { int linux_nice( l_int inc ); } 35 AUE_NULL UNIMPL ftime 36 AUE_SYNC NOPROTO { int sync(void); } 37 AUE_KILL STD { int linux_kill( l_int pid, l_int signum ); } 38 AUE_RENAME STD { int linux_rename( char *from, char *to ); } 39 AUE_MKDIR STD { int linux_mkdir( char *path, l_int mode ); } 40 AUE_RMDIR STD { int linux_rmdir( char *path ); } 41 AUE_DUP NOPROTO { int dup( u_int fd ); } 42 AUE_PIPE STD { int linux_pipe( l_int *pipefds ); } 43 AUE_NULL STD { int linux_times( struct l_times_argv *buf ); } 44 AUE_NULL UNIMPL prof 45 AUE_NULL STD { int linux_brk( l_ulong dsend ); } 46 AUE_SETGID STD { int linux_setgid16( l_gid16_t gid ); } 47 AUE_GETGID STD { int linux_getgid16(void); } 48 AUE_NULL STD { int linux_signal( l_int sig, l_handler_t handler ); } 49 AUE_GETEUID STD { int linux_geteuid16(void); } 50 AUE_GETEGID STD { int linux_getegid16(void); } 51 AUE_ACCT NOPROTO { int acct( char *path ); } 52 AUE_UMOUNT STD { int linux_umount( char *path, l_int flags ); } 53 AUE_NULL UNIMPL lock 54 AUE_IOCTL STD { int linux_ioctl( l_uint fd, l_uint cmd, uintptr_t arg ); } 55 AUE_FCNTL STD { int linux_fcntl( l_uint fd, l_uint cmd, uintptr_t arg ); } 56 AUE_NULL UNIMPL mpx 57 AUE_SETPGRP NOPROTO { int setpgid( int pid, int pgid ); } 58 AUE_NULL UNIMPL ulimit 59 AUE_NULL STD { int linux_olduname(void); } 60 AUE_UMASK NOPROTO { int umask( int newmask ); } 61 AUE_CHROOT NOPROTO { int chroot( char *path ); } 62 AUE_NULL STD { int linux_ustat( l_dev_t dev, struct l_ustat *ubuf ); } 63 AUE_DUP2 NOPROTO { int dup2( u_int from, u_int to ); } 64 AUE_GETPPID STD { int linux_getppid(void); } 65 AUE_GETPGRP NOPROTO { int getpgrp(void); } 66 AUE_SETSID NOPROTO { int setsid(void); } 67 AUE_NULL STD { int linux_sigaction( l_int sig, l_osigaction_t *nsa, l_osigaction_t *osa ); } 68 AUE_NULL STD { int linux_sgetmask(void); } 69 AUE_NULL STD { int linux_ssetmask( l_osigset_t mask ); } 70 AUE_SETREUID STD { int linux_setreuid16( l_uid16_t ruid, l_uid16_t euid ); } 71 AUE_SETREGID STD { int linux_setregid16( l_gid16_t rgid, l_gid16_t egid ); } 72 AUE_NULL STD { int linux_sigsuspend( l_int hist0, l_int hist1, l_osigset_t mask ); } 73 AUE_NULL STD { int linux_sigpending( l_osigset_t *mask ); } 74 AUE_SYSCTL STD { int linux_sethostname( char *hostname, u_int len ); } 75 AUE_SETRLIMIT STD { int linux_setrlimit( l_uint resource, struct l_rlimit *rlim ); } 76 AUE_GETRLIMIT STD { int linux_old_getrlimit( l_uint resource, struct l_rlimit *rlim ); } 77 AUE_GETRUSAGE STD { int linux_getrusage( int who, struct l_rusage *rusage ); } 78 AUE_NULL STD { int linux_gettimeofday( struct l_timeval *tp, struct timezone *tzp ); } 79 AUE_SETTIMEOFDAY STD { int linux_settimeofday( struct l_timeval *tp, struct timezone *tzp ); } 80 AUE_GETGROUPS STD { int linux_getgroups16( l_uint gidsetsize, l_gid16_t *gidset ); } 81 AUE_SETGROUPS STD { int linux_setgroups16( l_uint gidsetsize, l_gid16_t *gidset ); } 82 AUE_SELECT STD { int linux_old_select( struct l_old_select_argv *ptr ); } 83 AUE_SYMLINK STD { int linux_symlink( char *path, char *to ); } ; 84: oldlstat 84 AUE_LSTAT STD { int linux_lstat( char *path, struct linux_lstat *up ); } 85 AUE_READLINK STD { int linux_readlink( char *name, char *buf, l_int count ); } 86 AUE_USELIB UNIMPL linux_uselib 87 AUE_SWAPON NOPROTO { int swapon( char *name ); } 88 AUE_REBOOT STD { int linux_reboot( l_int magic1, l_int magic2, l_uint cmd, void *arg ); } ; 89: old_readdir 89 AUE_GETDIRENTRIES STD { int linux_readdir( l_uint fd, struct l_dirent *dent, l_uint count ); } ; 90: old_mmap 90 AUE_MMAP STD { int linux_mmap( struct l_mmap_argv *ptr ); } 91 AUE_MUNMAP NOPROTO { int munmap( caddr_t addr, int len ); } 92 AUE_TRUNCATE STD { int linux_truncate( char *path, l_ulong length ); } 93 AUE_FTRUNCATE STD { int linux_ftruncate( int fd, long length ); } 94 AUE_FCHMOD NOPROTO { int fchmod( int fd, int mode ); } 95 AUE_FCHOWN NOPROTO { int fchown( int fd, int uid, int gid ); } 96 AUE_GETPRIORITY STD { int linux_getpriority( int which, int who ); } 97 AUE_SETPRIORITY NOPROTO { int setpriority( int which, int who, int prio ); } 98 AUE_PROFILE UNIMPL profil 99 AUE_STATFS STD { int linux_statfs( char *path, struct l_statfs_buf *buf ); } 100 AUE_FSTATFS STD { int linux_fstatfs( l_uint fd, struct l_statfs_buf *buf ); } 101 AUE_NULL UNIMPL ioperm 102 AUE_NULL STD { int linux_socketcall( l_int what, l_ulong args ); } 103 AUE_NULL STD { int linux_syslog( l_int type, char *buf, l_int len ); } 104 AUE_SETITIMER STD { int linux_setitimer( l_int which, struct l_itimerval *itv, struct l_itimerval *oitv ); } 105 AUE_GETITIMER STD { int linux_getitimer( l_int which, struct l_itimerval *itv ); } 106 AUE_STAT STD { int linux_newstat( char *path, struct l_newstat *buf ); } 107 AUE_LSTAT STD { int linux_newlstat( char *path, struct l_newstat *buf ); } 108 AUE_FSTAT STD { int linux_newfstat( l_uint fd, struct l_newstat *buf ); } ; 109: olduname 109 AUE_NULL STD { int linux_uname(void); } 110 AUE_NULL STD { int linux_iopl( l_int level ); } 111 AUE_NULL STD { int linux_vhangup(void); } 112 AUE_NULL UNIMPL idle 113 AUE_NULL UNIMPL vm86old 114 AUE_WAIT4 STD { int linux_wait4( l_pid_t pid, l_int *status, l_int options, struct l_rusage *rusage ); } 115 AUE_SWAPOFF STD { int linux_swapoff(void); } 116 AUE_NULL STD { int linux_sysinfo( struct l_sysinfo *info ); } 117 AUE_NULL STD { int linux_ipc( l_uint what, l_int arg1, l_int arg2, l_uint arg3, l_uintptr_t ptr, l_uint arg5 ); } 118 AUE_FSYNC NOPROTO { int fsync( int fd ); } 119 AUE_SIGRETURN STD { int linux_sigreturn( struct l_sigframe *sfp ); } 120 AUE_RFORK STD { int linux_clone( l_int flags, void *stack, void *parent_tidptr, void *tls, void *child_tidptr ); } 121 AUE_SYSCTL STD { int linux_setdomainname( char *name, int len ); } 122 AUE_NULL STD { int linux_newuname( struct l_new_utsname *buf ); } 123 AUE_NULL UNIMPL modify_ldt 124 AUE_ADJTIME STD { int linux_adjtimex(void); } 125 AUE_MPROTECT STD { int linux_mprotect( caddr_t addr, int len, int prot ); } 126 AUE_SIGPROCMASK STD { int linux_sigprocmask( l_int how, l_osigset_t *mask, l_osigset_t *omask ); } 127 AUE_NULL UNIMPL create_module 128 AUE_NULL STD { int linux_init_module(void); } 129 AUE_NULL STD { int linux_delete_module(void); } 130 AUE_NULL UNIMPL get_kernel_syms 131 AUE_QUOTACTL STD { int linux_quotactl(void); } 132 AUE_GETPGID NOPROTO { int getpgid( int pid ); } 133 AUE_FCHDIR NOPROTO { int fchdir( int fd ); } 134 AUE_BDFLUSH STD { int linux_bdflush(void); } 135 AUE_NULL STD { int linux_sysfs( l_int option, l_ulong arg1, l_ulong arg2 ); } 136 AUE_PERSONALITY STD { int linux_personality( l_uint per ); } 137 AUE_NULL UNIMPL afs_syscall 138 AUE_SETFSUID STD { int linux_setfsuid16( l_uid16_t uid ); } 139 AUE_SETFSGID STD { int linux_setfsgid16( l_gid16_t gid ); } 140 AUE_LSEEK STD { int linux_llseek( l_int fd, l_ulong ohigh, l_ulong olow, l_loff_t *res, l_uint whence ); } 141 AUE_GETDIRENTRIES STD { int linux_getdents( l_uint fd, void *dent, l_uint count ); } ; 142: newselect 142 AUE_SELECT STD { int linux_select( l_int nfds, l_fd_set *readfds, l_fd_set *writefds, l_fd_set *exceptfds, struct l_timeval *timeout ); } 143 AUE_FLOCK NOPROTO { int flock( int fd, int how ); } 144 AUE_MSYNC STD { int linux_msync( l_ulong addr, l_size_t len, l_int fl ); } 145 AUE_READV STD { int linux_readv( l_ulong fd, struct l_iovec32 *iovp, l_ulong iovcnt ); } 146 AUE_WRITEV STD { int linux_writev( l_ulong fd, struct l_iovec32 *iovp, l_ulong iovcnt ); } 147 AUE_GETSID STD { int linux_getsid( l_pid_t pid ); } 148 AUE_NULL STD { int linux_fdatasync( l_uint fd ); } 149 AUE_SYSCTL STD { int linux_sysctl( struct l___sysctl_args *args ); } 150 AUE_MLOCK NOPROTO { int mlock( const void *addr, size_t len ); } 151 AUE_MUNLOCK NOPROTO { int munlock( const void *addr, size_t len ); } 152 AUE_MLOCKALL NOPROTO { int mlockall( int how ); } 153 AUE_MUNLOCKALL NOPROTO { int munlockall(void); } 154 AUE_SCHED_SETPARAM STD { int linux_sched_setparam( l_pid_t pid, struct sched_param *param ); } 155 AUE_SCHED_GETPARAM STD { int linux_sched_getparam( l_pid_t pid, struct sched_param *param ); } 156 AUE_SCHED_SETSCHEDULER STD { int linux_sched_setscheduler( l_pid_t pid, l_int policy, struct sched_param *param ); } 157 AUE_SCHED_GETSCHEDULER STD { int linux_sched_getscheduler( l_pid_t pid ); } 158 AUE_NULL NOPROTO { int sched_yield(void); } 159 AUE_SCHED_GET_PRIORITY_MAX STD { int linux_sched_get_priority_max( l_int policy ); } 160 AUE_SCHED_GET_PRIORITY_MIN STD { int linux_sched_get_priority_min( l_int policy ); } 161 AUE_SCHED_RR_GET_INTERVAL STD { int linux_sched_rr_get_interval( l_pid_t pid, struct l_timespec *interval ); } 162 AUE_NULL STD { int linux_nanosleep( const struct l_timespec *rqtp, struct l_timespec *rmtp ); } 163 AUE_NULL STD { int linux_mremap( l_ulong addr, l_ulong old_len, l_ulong new_len, l_ulong flags, l_ulong new_addr ); } 164 AUE_SETRESUID STD { int linux_setresuid16( l_uid16_t ruid, l_uid16_t euid, l_uid16_t suid ); } 165 AUE_GETRESUID STD { int linux_getresuid16( l_uid16_t *ruid, l_uid16_t *euid, l_uid16_t *suid ); } 166 AUE_NULL UNIMPL vm86 167 AUE_NULL UNIMPL query_module 168 AUE_POLL NOPROTO { int poll( struct pollfd *fds, unsigned int nfds, int timeout ); } 169 AUE_NULL UNIMPL nfsservctl 170 AUE_SETRESGID STD { int linux_setresgid16( l_gid16_t rgid, l_gid16_t egid, l_gid16_t sgid ); } 171 AUE_GETRESGID STD { int linux_getresgid16( l_gid16_t *rgid, l_gid16_t *egid, l_gid16_t *sgid ); } 172 AUE_PRCTL STD { int linux_prctl( l_int option, l_int arg2, l_int arg3, l_int arg4, l_int arg5 ); } 173 AUE_NULL STD { int linux_rt_sigreturn( struct l_ucontext *ucp ); } 174 AUE_NULL STD { int linux_rt_sigaction( l_int sig, l_sigaction_t *act, l_sigaction_t *oact, l_size_t sigsetsize ); } 175 AUE_NULL STD { int linux_rt_sigprocmask( l_int how, l_sigset_t *mask, l_sigset_t *omask, l_size_t sigsetsize ); } 176 AUE_NULL STD { int linux_rt_sigpending( l_sigset_t *set, l_size_t sigsetsize ); } 177 AUE_NULL STD { int linux_rt_sigtimedwait( l_sigset_t *mask, l_siginfo_t *ptr, struct l_timeval *timeout, l_size_t sigsetsize ); } 178 AUE_NULL STD { int linux_rt_sigqueueinfo( l_pid_t pid, l_int sig, l_siginfo_t *info ); } 179 AUE_NULL STD { int linux_rt_sigsuspend( l_sigset_t *newset, l_size_t sigsetsize ); } 180 AUE_PREAD STD { int linux_pread( l_uint fd, char *buf, l_size_t nbyte, uint32_t offset1, uint32_t offset2 ); } 181 AUE_PWRITE STD { int linux_pwrite( l_uint fd, char *buf, l_size_t nbyte, uint32_t offset1, uint32_t offset2 ); } 182 AUE_CHOWN STD { int linux_chown16( char *path, l_uid16_t uid, l_gid16_t gid ); } 183 AUE_GETCWD STD { int linux_getcwd( char *buf, l_ulong bufsize ); } 184 AUE_CAPGET STD { int linux_capget( struct l_user_cap_header *hdrp, struct l_user_cap_data *datap ); } 185 AUE_CAPSET STD { int linux_capset( struct l_user_cap_header *hdrp, struct l_user_cap_data *datap ); } 186 AUE_NULL STD { int linux_sigaltstack( l_stack_t *uss, l_stack_t *uoss ); } 187 AUE_SENDFILE STD { int linux_sendfile( l_int out, l_int in, l_long *offset, l_size_t count ); } 188 AUE_GETPMSG UNIMPL getpmsg 189 AUE_PUTPMSG UNIMPL putpmsg 190 AUE_VFORK STD { int linux_vfork(void); } ; 191: ugetrlimit 191 AUE_GETRLIMIT STD { int linux_getrlimit( l_uint resource, struct l_rlimit *rlim ); } 192 AUE_MMAP STD { int linux_mmap2( l_ulong addr, l_ulong len, l_ulong prot, l_ulong flags, l_ulong fd, l_ulong pgoff ); } 193 AUE_TRUNCATE STD { int linux_truncate64( char *path, uint32_t length1, uint32_t length2 ); } 194 AUE_FTRUNCATE STD { int linux_ftruncate64( l_uint fd, uint32_t length1, uint32_t length2 ); } 195 AUE_STAT STD { int linux_stat64( const char *filename, struct l_stat64 *statbuf ); } 196 AUE_LSTAT STD { int linux_lstat64( const char *filename, struct l_stat64 *statbuf ); } 197 AUE_FSTAT STD { int linux_fstat64( l_int fd, struct l_stat64 *statbuf ); } 198 AUE_LCHOWN STD { int linux_lchown( char *path, l_uid_t uid, l_gid_t gid ); } 199 AUE_GETUID STD { int linux_getuid(void); } 200 AUE_GETGID STD { int linux_getgid(void); } 201 AUE_GETEUID NOPROTO { int geteuid(void); } 202 AUE_GETEGID NOPROTO { int getegid(void); } 203 AUE_SETREUID NOPROTO { int setreuid( uid_t ruid, uid_t euid ); } 204 AUE_SETREGID NOPROTO { int setregid( gid_t rgid, gid_t egid ); } 205 AUE_GETGROUPS STD { int linux_getgroups( l_int gidsetsize, l_gid_t *grouplist ); } 206 AUE_SETGROUPS STD { int linux_setgroups( l_int gidsetsize, l_gid_t *grouplist ); } 207 AUE_FCHOWN NODEF fchown fchown fchown_args int 208 AUE_SETRESUID NOPROTO { int setresuid( uid_t ruid, uid_t euid, uid_t suid ); } 209 AUE_GETRESUID NOPROTO { int getresuid( uid_t *ruid, uid_t *euid, uid_t *suid ); } 210 AUE_SETRESGID NOPROTO { int setresgid( gid_t rgid, gid_t egid, gid_t sgid ); } 211 AUE_GETRESGID NOPROTO { int getresgid( gid_t *rgid, gid_t *egid, gid_t *sgid ); } 212 AUE_CHOWN STD { int linux_chown( char *path, l_uid_t uid, l_gid_t gid ); } 213 AUE_SETUID NOPROTO { int setuid( uid_t uid ); } 214 AUE_SETGID NOPROTO { int setgid( gid_t gid ); } 215 AUE_SETFSUID STD { int linux_setfsuid( l_uid_t uid ); } 216 AUE_SETFSGID STD { int linux_setfsgid( l_gid_t gid ); } 217 AUE_PIVOT_ROOT STD { int linux_pivot_root( char *new_root, char *put_old ); } 218 AUE_MINCORE STD { int linux_mincore( l_ulong start, l_size_t len, u_char *vec ); } 219 AUE_MADVISE STD { int linux_madvise( void *addr, size_t len, int behav ); } 220 AUE_GETDIRENTRIES STD { int linux_getdents64( l_uint fd, void *dirent, l_uint count ); } 221 AUE_FCNTL STD { int linux_fcntl64( l_uint fd, l_uint cmd, uintptr_t arg ); } 222 AUE_NULL UNIMPL 223 AUE_NULL UNIMPL 224 AUE_NULL STD { long linux_gettid(void); } 225 AUE_NULL UNIMPL linux_readahead 226 AUE_NULL STD { int linux_setxattr( const char *path, const char *name, const char *value, l_size_t size, l_int flags ); } 227 AUE_NULL STD { int linux_lsetxattr( const char *path, const char *name, const char *value, l_size_t size, l_int flags ); } 228 AUE_NULL STD { int linux_fsetxattr( l_int fd, const char *name, const char *value, l_size_t size, l_int flags ); } 229 AUE_NULL STD { int linux_getxattr( const char *path, const char *name, char *value, l_size_t size ); } 230 AUE_NULL STD { int linux_lgetxattr( const char *path, const char *name, char *value, l_size_t size ); } 231 AUE_NULL STD { int linux_fgetxattr( l_int fd, const char *name, char *value, l_size_t size ); } 232 AUE_NULL STD { int linux_listxattr( const char *path, const char *list, l_size_t size ); } 233 AUE_NULL STD { int linux_llistxattr( const char *path, const char *list, l_size_t size ); } 234 AUE_NULL STD { int linux_flistxattr( l_int fd, const char *list, l_size_t size ); } 235 AUE_NULL STD { int linux_removexattr( const char *path, const char *name ); } 236 AUE_NULL STD { int linux_lremovexattr( const char *path, const char *name ); } 237 AUE_NULL STD { int linux_fremovexattr( l_int fd, const char *name ); } 238 AUE_NULL STD { int linux_tkill( int tid, int sig ); } 239 AUE_SENDFILE STD { int linux_sendfile64( l_int out, l_int in, l_loff_t *offset, l_size_t count ); } 240 AUE_NULL STD { int linux_sys_futex( void *uaddr, int op, uint32_t val, struct l_timespec *timeout, uint32_t *uaddr2, uint32_t val3 ); } 241 AUE_NULL STD { int linux_sched_setaffinity( l_pid_t pid, l_uint len, l_ulong *user_mask_ptr ); } 242 AUE_NULL STD { int linux_sched_getaffinity( l_pid_t pid, l_uint len, l_ulong *user_mask_ptr ); } 243 AUE_NULL STD { int linux_set_thread_area( struct l_user_desc *desc ); } 244 AUE_NULL UNIMPL linux_get_thread_area 245 AUE_NULL UNIMPL linux_io_setup 246 AUE_NULL UNIMPL linux_io_destroy 247 AUE_NULL UNIMPL linux_io_getevents 248 AUE_NULL UNIMPL linux_io_submit 249 AUE_NULL UNIMPL linux_io_cancel 250 AUE_NULL STD { int linux_fadvise64( int fd, uint32_t offset1, uint32_t offset2, l_size_t len, int advice ); } 251 AUE_NULL UNIMPL 252 AUE_EXIT STD { int linux_exit_group( int error_code ); } 253 AUE_NULL STD { int linux_lookup_dcookie(void); } 254 AUE_NULL STD { int linux_epoll_create( l_int size ); } 255 AUE_NULL STD { int linux_epoll_ctl( l_int epfd, l_int op, l_int fd, struct epoll_event *event ); } 256 AUE_NULL STD { int linux_epoll_wait( l_int epfd, struct epoll_event *events, l_int maxevents, l_int timeout ); } 257 AUE_NULL STD { int linux_remap_file_pages(void); } 258 AUE_NULL STD { int linux_set_tid_address( int *tidptr ); } 259 AUE_NULL STD { int linux_timer_create( clockid_t clock_id, struct sigevent *evp, l_timer_t *timerid ); } 260 AUE_NULL STD { int linux_timer_settime( l_timer_t timerid, l_int flags, const struct itimerspec *new, struct itimerspec *old ); } 261 AUE_NULL STD { int linux_timer_gettime( l_timer_t timerid, struct itimerspec *setting ); } 262 AUE_NULL STD { int linux_timer_getoverrun( l_timer_t timerid ); } 263 AUE_NULL STD { int linux_timer_delete( l_timer_t timerid ); } 264 AUE_CLOCK_SETTIME STD { int linux_clock_settime( clockid_t which, struct l_timespec *tp ); } 265 AUE_NULL STD { int linux_clock_gettime( clockid_t which, struct l_timespec *tp ); } 266 AUE_NULL STD { int linux_clock_getres( clockid_t which, struct l_timespec *tp ); } 267 AUE_NULL STD { int linux_clock_nanosleep( clockid_t which, int flags, struct l_timespec *rqtp, struct l_timespec *rmtp ); } 268 AUE_STATFS STD { int linux_statfs64( char *path, size_t bufsize, struct l_statfs64_buf *buf ); } 269 AUE_FSTATFS STD { int linux_fstatfs64( l_uint fd, size_t bufsize, struct l_statfs64_buf *buf ); } 270 AUE_NULL STD { int linux_tgkill( int tgid, int pid, int sig ); } 271 AUE_UTIMES STD { int linux_utimes( char *fname, struct l_timeval *tptr ); } 272 AUE_NULL STD { int linux_fadvise64_64( int fd, uint32_t offset1, uint32_t offset2, uint32_t len1, uint32_t len2, int advice ); } 273 AUE_NULL UNIMPL vserver 274 AUE_NULL STD { int linux_mbind(void); } 275 AUE_NULL STD { int linux_get_mempolicy(void); } 276 AUE_NULL STD { int linux_set_mempolicy(void); } ; Linux 2.6.6: 277 AUE_NULL STD { int linux_mq_open( const char *name, l_int oflag, l_mode_t mode, struct mq_attr *attr ); } 278 AUE_NULL STD { int linux_mq_unlink( const char *name ); } 279 AUE_NULL STD { int linux_mq_timedsend( l_mqd_t mqd, const char *msg_ptr, l_size_t msg_len, l_uint msg_prio, const struct l_timespec *abs_timeout ); } 280 AUE_NULL STD { int linux_mq_timedreceive( l_mqd_t mqd, char *msg_ptr, l_size_t msg_len, l_uint *msg_prio, const struct l_timespec *abs_timeout ); } 281 AUE_NULL STD { int linux_mq_notify( l_mqd_t mqd, const struct l_timespec *abs_timeout ); } 282 AUE_NULL STD { int linux_mq_getsetattr( l_mqd_t mqd, const struct mq_attr *attr, struct mq_attr *oattr ); } 283 AUE_NULL STD { int linux_kexec_load(void); } 284 AUE_WAIT6 STD { int linux_waitid( int idtype, l_pid_t id, l_siginfo_t *info, int options, struct l_rusage *rusage ); } 285 AUE_NULL UNIMPL ; Linux 2.6.11: 286 AUE_NULL STD { int linux_add_key(void); } 287 AUE_NULL STD { int linux_request_key(void); } 288 AUE_NULL STD { int linux_keyctl(void); } ; Linux 2.6.13: 289 AUE_NULL STD { int linux_ioprio_set(void); } 290 AUE_NULL STD { int linux_ioprio_get(void); } 291 AUE_NULL STD { int linux_inotify_init(void); } 292 AUE_NULL STD { int linux_inotify_add_watch(void); } 293 AUE_NULL STD { int linux_inotify_rm_watch(void); } ; Linux 2.6.16: 294 AUE_NULL STD { int linux_migrate_pages(void); } 295 AUE_OPEN_RWTC STD { int linux_openat( l_int dfd, const char *filename, l_int flags, l_int mode ); } 296 AUE_MKDIRAT STD { int linux_mkdirat( l_int dfd, const char *pathname, l_int mode ); } 297 AUE_MKNODAT STD { int linux_mknodat( l_int dfd, const char *filename, l_int mode, l_uint dev ); } 298 AUE_FCHOWNAT STD { int linux_fchownat( l_int dfd, const char *filename, l_uid16_t uid, l_gid16_t gid, l_int flag ); } 299 AUE_FUTIMESAT STD { int linux_futimesat( l_int dfd, char *filename, struct l_timeval *utimes ); } 300 AUE_FSTATAT STD { int linux_fstatat64( l_int dfd, char *pathname, struct l_stat64 *statbuf, l_int flag ); } 301 AUE_UNLINKAT STD { int linux_unlinkat( l_int dfd, const char *pathname, l_int flag ); } 302 AUE_RENAMEAT STD { int linux_renameat( l_int olddfd, const char *oldname, l_int newdfd, const char *newname ); } 303 AUE_LINKAT STD { int linux_linkat( l_int olddfd, const char *oldname, l_int newdfd, const char *newname, l_int flag ); } 304 AUE_SYMLINKAT STD { int linux_symlinkat( const char *oldname, l_int newdfd, const char *newname ); } 305 AUE_READLINKAT STD { int linux_readlinkat( l_int dfd, const char *path, char *buf, l_int bufsiz ); } 306 AUE_FCHMODAT STD { int linux_fchmodat( l_int dfd, const char *filename, l_mode_t mode ); } 307 AUE_FACCESSAT STD { int linux_faccessat( l_int dfd, const char *filename, l_int amode ); } 308 AUE_SELECT STD { int linux_pselect6( l_int nfds, l_fd_set *readfds, l_fd_set *writefds, l_fd_set *exceptfds, struct l_timespec *tsp, l_uintptr_t *sig ); } 309 AUE_POLL STD { int linux_ppoll( struct pollfd *fds, uint32_t nfds, struct l_timespec *tsp, l_sigset_t *sset, l_size_t ssize ); } 310 AUE_NULL STD { int linux_unshare(void); } ; Linux 2.6.17: 311 AUE_NULL STD { int linux_set_robust_list( struct linux_robust_list_head *head, l_size_t len ); } 312 AUE_NULL STD { int linux_get_robust_list( l_int pid, struct linux_robust_list_head **head, l_size_t *len ); } 313 AUE_NULL STD { int linux_splice( int fd_in, l_loff_t *off_in, int fd_out, l_loff_t *off_out, l_size_t len, l_uint flags ); } 314 AUE_NULL STD { int linux_sync_file_range( l_int fd, uint32_t offset1, uint32_t offset2, uint32_t nbytes1, uint32_t nbytes2, unsigned int flags ); } 315 AUE_NULL STD { int linux_tee(void); } 316 AUE_NULL STD { int linux_vmsplice(void); } ; Linux 2.6.18: 317 AUE_NULL STD { int linux_move_pages(void); } ; Linux 2.6.19: 318 AUE_NULL STD { int linux_getcpu( l_uint *cpu, l_uint *node, void *cache ); } 319 AUE_NULL STD { int linux_epoll_pwait( l_int epfd, struct epoll_event *events, l_int maxevents, l_int timeout, l_sigset_t *mask, l_size_t sigsetsize ); } ; Linux 2.6.22: 320 AUE_FUTIMESAT STD { int linux_utimensat( l_int dfd, const char *pathname, const struct l_timespec *times, l_int flags ); } 321 AUE_NULL STD { int linux_signalfd(void); } 322 AUE_NULL STD { int linux_timerfd_create( l_int clockid, l_int flags ); } 323 AUE_NULL STD { int linux_eventfd( l_uint initval ); } ; Linux 2.6.23: 324 AUE_NULL STD { int linux_fallocate( l_int fd, l_int mode, uint32_t offset1, uint32_t offset2, uint32_t len1, uint32_t len2 ); } ; Linux 2.6.25: 325 AUE_NULL STD { int linux_timerfd_settime( l_int fd, l_int flags, const struct l_itimerspec *new_value, struct l_itimerspec *old_value ); } 326 AUE_NULL STD { int linux_timerfd_gettime( l_int fd, struct l_itimerspec *old_value ); } ; Linux 2.6.27: 327 AUE_NULL STD { int linux_signalfd4(void); } 328 AUE_NULL STD { int linux_eventfd2( l_uint initval, l_int flags ); } 329 AUE_NULL STD { int linux_epoll_create1( l_int flags ); } 330 AUE_NULL STD { int linux_dup3( l_int oldfd, l_int newfd, l_int flags ); } 331 AUE_NULL STD { int linux_pipe2( l_int *pipefds, l_int flags ); } 332 AUE_NULL STD { int linux_inotify_init1(void); } ; Linux 2.6.30: 333 AUE_NULL STD { int linux_preadv( l_ulong fd, struct iovec *vec, l_ulong vlen, l_ulong pos_l, l_ulong pos_h ); } 334 AUE_NULL STD { int linux_pwritev( l_ulong fd, struct iovec *vec, l_ulong vlen, l_ulong pos_l, l_ulong pos_h ); } ; Linux 2.6.31: 335 AUE_NULL STD { int linux_rt_tgsigqueueinfo( l_pid_t tgid, l_pid_t tid, l_int sig, l_siginfo_t *uinfo ); } 336 AUE_NULL STD { int linux_perf_event_open(void); } ; Linux 2.6.33: 337 AUE_NULL STD { int linux_recvmmsg( l_int s, struct l_mmsghdr *msg, l_uint vlen, l_uint flags, struct l_timespec *timeout ); } 338 AUE_NULL STD { int linux_fanotify_init(void); } 339 AUE_NULL STD { int linux_fanotify_mark(void); } ; Linux 2.6.36: 340 AUE_NULL STD { int linux_prlimit64( l_pid_t pid, l_uint resource, struct rlimit *new, struct rlimit *old ); } ; Linux 2.6.39: 341 AUE_NULL STD { - int linux_name_to_handle_at(void); + int linux_name_to_handle_at( + l_int dirfd, + const char *name, + struct l_file_handle *handle, + l_int *mnt_id, + l_int flags + ); } 342 AUE_NULL STD { - int linux_open_by_handle_at(void); + int linux_open_by_handle_at( + l_int mountdirfd, + struct l_file_handle *handle, + l_int flags + ); } 343 AUE_NULL STD { int linux_clock_adjtime(void); } 344 AUE_SYNC STD { int linux_syncfs( l_int fd ); } ; Linux 3.0: 345 AUE_NULL STD { int linux_sendmmsg( l_int s, struct l_mmsghdr *msg, l_uint vlen, l_uint flags ); } 346 AUE_NULL STD { int linux_setns(void); } ; Linux 3.2 (glibc 2.15): 347 AUE_NULL STD { int linux_process_vm_readv( l_pid_t pid, const struct iovec *lvec, l_ulong liovcnt, const struct iovec *rvec, l_ulong riovcnt, l_ulong flags ); } 348 AUE_NULL STD { int linux_process_vm_writev( l_pid_t pid, const struct iovec *lvec, l_ulong liovcnt, const struct iovec *rvec, l_ulong riovcnt, l_ulong flags ); } ; Linux 3.5 (no glibc wrapper): 349 AUE_NULL STD { int linux_kcmp( l_pid_t pid1, l_pid_t pid2, l_int type, l_ulong idx1, l_ulong idx ); } ; Linux 3.8 (no glibc wrapper): 350 AUE_NULL STD { int linux_finit_module( l_int fd, const char *uargs, l_int flags ); } ; Linux 3.14: 351 AUE_NULL STD { int linux_sched_setattr( l_pid_t pid, void *attr, l_uint flags ); } 352 AUE_NULL STD { int linux_sched_getattr( l_pid_t pid, void *attr, l_uint size, l_uint flags ); } ; Linux 3.15: 353 AUE_NULL STD { int linux_renameat2( l_int olddfd, const char *oldname, l_int newdfd, const char *newname, unsigned int flags ); } ; Linux 3.17: 354 AUE_NULL STD { int linux_seccomp( l_uint op, l_uint flags, const char *uargs ); } 355 AUE_NULL STD { int linux_getrandom( char *buf, l_size_t count, l_uint flags ); } 356 AUE_NULL STD { int linux_memfd_create( const char *uname_ptr, l_uint flags ); } ; Linux 3.18: 357 AUE_NULL STD { int linux_bpf( l_int cmd, void *attr, l_uint size ); } ; Linux 3.19: 358 AUE_NULL STD { int linux_execveat( l_int dfd, const char *filename, const char **argv, const char **envp, l_int flags ); } ; Linux 4.3: sockets now direct system calls: 359 AUE_SOCKET STD { int linux_socket( l_int domain, l_int type, l_int protocol ); } 360 AUE_SOCKETPAIR STD { int linux_socketpair( l_int domain, l_int type, l_int protocol, l_uintptr_t rsv ); } 361 AUE_BIND STD { int linux_bind( l_int s, l_uintptr_t name, l_int namelen ); } 362 AUE_CONNECT STD { int linux_connect( l_int s, l_uintptr_t name, l_int namelen ); } 363 AUE_LISTEN STD { int linux_listen( l_int s, l_int backlog ); } 364 AUE_ACCEPT STD { int linux_accept4( l_int s, l_uintptr_t addr, l_uintptr_t namelen, l_int flags ); } 365 AUE_GETSOCKOPT STD { int linux_getsockopt( l_int s, l_int level, l_int optname, l_uintptr_t optval, l_uintptr_t optlen ); } 366 AUE_SETSOCKOPT STD { int linux_setsockopt( l_int s, l_int level, l_int optname, l_uintptr_t optval, l_int optlen ); } 367 AUE_GETSOCKNAME STD { int linux_getsockname( l_int s, l_uintptr_t addr, l_uintptr_t namelen ); } 368 AUE_GETPEERNAME STD { int linux_getpeername( l_int s, l_uintptr_t addr, l_uintptr_t namelen ); } 369 AUE_SENDTO STD { int linux_sendto( l_int s, l_uintptr_t msg, l_int len, l_int flags, l_uintptr_t to, l_int tolen ); } 370 AUE_SENDMSG STD { int linux_sendmsg( l_int s, l_uintptr_t msg, l_int flags ); } 371 AUE_RECVFROM STD { int linux_recvfrom( l_int s, l_uintptr_t buf, l_size_t len, l_int flags, l_uintptr_t from, l_uintptr_t fromlen ); } 372 AUE_RECVMSG STD { int linux_recvmsg( l_int s, l_uintptr_t msg, l_int flags ); } 373 AUE_NULL STD { int linux_shutdown( l_int s, l_int how ); } ; Linux 4.2: 374 AUE_NULL STD { int linux_userfaultfd( l_int flags ); } ; Linux 4.3: 375 AUE_NULL STD { int linux_membarrier( l_int cmd, l_int flags ); } ; Linux 4.4: 376 AUE_NULL STD { int linux_mlock2( l_ulong start, l_size_t len, l_int flags ); } ; Linux 4.5: 377 AUE_NULL STD { int linux_copy_file_range( l_int fd_in, l_loff_t *off_in, l_int fd_out, l_loff_t *off_out, l_size_t len, l_uint flags ); } ; Linux 4.6: 378 AUE_NULL STD { int linux_preadv2( l_ulong fd, const struct iovec *vec, l_ulong vlen, l_ulong pos_l, l_ulong pos_h, l_int flags ); } 379 AUE_NULL STD { int linux_pwritev2( l_ulong fd, const struct iovec *vec, l_ulong vlen, l_ulong pos_l, l_ulong pos_h, l_int flags ); } ; Linux 4.8: 380 AUE_NULL STD { int linux_pkey_mprotect( l_ulong start, l_size_t len, l_ulong prot, l_int pkey ); } 381 AUE_NULL STD { int linux_pkey_alloc( l_ulong flags, l_ulong init_val ); } 382 AUE_NULL STD { int linux_pkey_free( l_int pkey ); } ; Linux 4.11: 383 AUE_NULL STD { int linux_statx( l_int dirfd, const char *pathname, l_uint flags, l_uint mask, void *statxbuf ); } 384 AUE_NULL STD { int linux_arch_prctl( l_int option, l_ulong arg2 ); } ; Linux 4.18: 385 AUE_NULL STD { int linux_io_pgetevents(void); } 386 AUE_NULL STD { int linux_rseq(void); } 387-392 AUE_NULL UNIMPL nosys 393 AUE_NULL STD { int linux_semget( l_key_t key, l_int nsems, l_int semflg ); } 394 AUE_NULL STD { int linux_semctl( l_int semid, l_int semnum, l_int cmd, union l_semun arg ); } 395 AUE_NULL STD { int linux_shmget( l_key_t key, l_size_t size, l_int shmflg ); } 396 AUE_NULL STD { int linux_shmctl( l_int shmid, l_int cmd, struct l_shmid_ds *buf ); } 397 AUE_NULL STD { int linux_shmat( l_int shmid, char *shmaddr, l_int shmflg ); } 398 AUE_NULL STD { int linux_shmdt( char *shmaddr ); } 399 AUE_NULL STD { int linux_msgget( l_key_t key, l_int msgflg ); } 400 AUE_NULL STD { int linux_msgsnd( l_int msqid, struct l_msgbuf *msgp, l_size_t msgsz, l_int msgflg ); } 401 AUE_NULL STD { int linux_msgrcv( l_int msqid, struct l_msgbuf *msgp, l_size_t msgsz, l_long msgtyp, l_int msgflg ); } 402 AUE_NULL STD { int linux_msgctl( l_int msqid, l_int cmd, struct l_msqid_ds *buf ); } ; Linux 5.0: 403 AUE_NULL STD { int linux_clock_gettime64(void); } 404 AUE_NULL STD { int linux_clock_settime64(void); } 405 AUE_NULL STD { int linux_clock_adjtime64(void); } 406 AUE_NULL STD { int linux_clock_getres_time64(void); } 407 AUE_NULL STD { int linux_clock_nanosleep_time64(void); } 408 AUE_NULL STD { int linux_timer_gettime64(void); } 409 AUE_NULL STD { int linux_timer_settime64(void); } 410 AUE_NULL STD { int linux_timerfd_gettime64(void); } 411 AUE_NULL STD { int linux_timerfd_settime64(void); } 412 AUE_NULL STD { int linux_utimensat_time64(void); } 413 AUE_NULL STD { int linux_pselect6_time64(void); } 414 AUE_NULL STD { int linux_ppoll_time64(void); } 415 AUE_NULL UNIMPL nosys 416 AUE_NULL STD { int linux_io_pgetevents_time64(void); } 417 AUE_NULL STD { int linux_recvmmsg_time64(void); } 418 AUE_NULL STD { int linux_mq_timedsend_time64(void); } 419 AUE_NULL STD { int linux_mq_timedreceive_time64(void); } 420 AUE_NULL STD { int linux_semtimedop_time64(void); } 421 AUE_NULL STD { int linux_rt_sigtimedwait_time64(void); } 422 AUE_NULL STD { int linux_futex_time64(void); } 423 AUE_NULL STD { int linux_sched_rr_get_interval_time64(void); } 424 AUE_NULL STD { int linux_pidfd_send_signal( l_int pidfd, l_int sig, l_siginfo_t *info, l_uint flags ); } 425 AUE_NULL STD { int linux_io_uring_setup(void); } 426 AUE_NULL STD { int linux_io_uring_enter(void); } 427 AUE_NULL STD { int linux_io_uring_register(void); } ; please, keep this line at the end. 428 AUE_NULL UNIMPL nosys ; vim: syntax=off Index: head/sys/arm64/linux/syscalls.master =================================================================== --- head/sys/arm64/linux/syscalls.master (revision 367772) +++ head/sys/arm64/linux/syscalls.master (revision 367773) @@ -1,1669 +1,1679 @@ $FreeBSD$ ; Linux ABI system call generic name/number map, based on Linux file ; include/uapi/asm-generic/unistd.h #include #include #include #include #include #include ; Isn't pretty, but there seems to be no other way to trap nosys #define nosys linux_nosys 0 AUE_NULL UNIMPL linux_io_setup 1 AUE_NULL UNIMPL linux_io_destroy 2 AUE_NULL UNIMPL linux_io_submit 3 AUE_NULL UNIMPL linux_io_cancel 4 AUE_NULL UNIMPL linux_io_getevents 5 AUE_NULL STD { int linux_setxattr( const char *path, const char *name, const char *value, l_size_t size, l_int flags ); } 6 AUE_NULL STD { int linux_lsetxattr( const char *path, const char *name, const char *value, l_size_t size, l_int flags ); } 7 AUE_NULL STD { int linux_fsetxattr( l_int fd, const char *name, const char *value, l_size_t size, l_int flags ); } 8 AUE_NULL STD { int linux_getxattr( const char *path, const char *name, char *value, l_size_t size ); } 9 AUE_NULL STD { int linux_lgetxattr( const char *path, const char *name, char *value, l_size_t size ); } 10 AUE_NULL STD { int linux_fgetxattr( l_int fd, const char *name, char *value, l_size_t size ); } 11 AUE_NULL STD { int linux_listxattr( const char *path, const char *list, l_size_t size ); } 12 AUE_NULL STD { int linux_llistxattr( const char *path, const char *list, l_size_t size ); } 13 AUE_NULL STD { int linux_flistxattr( l_int fd, const char *list, l_size_t size ); } 14 AUE_NULL STD { int linux_removexattr( const char *path, const char *name ); } 15 AUE_NULL STD { int linux_lremovexattr( const char *path, const char *name ); } 16 AUE_NULL STD { int linux_fremovexattr( l_int fd, const char *name ); } 17 AUE_GETCWD STD { int linux_getcwd( char *buf, l_ulong bufsize ); } 18 AUE_NULL STD { int linux_lookup_dcookie(void); } 19 AUE_NULL STD { int linux_eventfd2( l_uint initval, l_int flags ); } 20 AUE_NULL STD { int linux_epoll_create1( l_int flags ); } 21 AUE_NULL STD { int linux_epoll_ctl( l_int epfd, l_int op, l_int fd, struct epoll_event *event ); } 22 AUE_NULL STD { int linux_epoll_pwait( l_int epfd, struct epoll_event *events, l_int maxevents, l_int timeout, l_sigset_t *mask, l_size_t sigsetsize ); } 23 AUE_DUP NOPROTO { int dup( u_int fd); } 24 AUE_NULL STD { int linux_dup3( l_int oldfd, l_int newfd, l_int flags ); } 25 AUE_FCNTL STD { int linux_fcntl( l_uint fd, l_uint cmd, l_ulong arg ); } 26 AUE_NULL STD { int linux_inotify_init1( l_int flags ); } 27 AUE_NULL STD { int linux_inotify_add_watch(void); } 28 AUE_NULL STD { int linux_inotify_rm_watch(void); } 29 AUE_IOCTL STD { int linux_ioctl( l_uint fd, l_uint cmd, l_ulong arg ); } 30 AUE_NULL STD { int linux_ioprio_set(void); } 31 AUE_NULL STD { int linux_ioprio_get(void); } 32 AUE_FLOCK NOPROTO { int flock( int fd, int how ); } 33 AUE_MKNODAT STD { int linux_mknodat( l_int dfd, const char *filename, l_int mode, l_uint dev ); } 34 AUE_MKDIRAT STD { int linux_mkdirat( l_int dfd, const char *pathname, l_mode_t mode ); } 35 AUE_UNLINKAT STD { int linux_unlinkat( l_int dfd, const char *pathname, l_int flag ); } 36 AUE_SYMLINKAT STD { int linux_symlinkat( const char *oldname, l_int newdfd, const char *newname ); } 37 AUE_LINKAT STD { int linux_linkat( l_int olddfd, const char *oldname, l_int newdfd, const char *newname, l_int flag ); } 38 AUE_RENAMEAT STD { int linux_renameat( l_int olddfd, const char *oldname, l_int newdfd, const char *newname ); } 39 AUE_NULL UNIMPL linux_umount2 40 AUE_MOUNT STD { int linux_mount( char *specialfile, char *dir, char *filesystemtype, l_ulong rwflag, void *data ); } 41 AUE_PIVOT_ROOT STD { int linux_pivot_root(void); } 42 AUE_NULL UNIMPL nfsservctl 43 AUE_STATFS STD { int linux_statfs( char *path, struct l_statfs_buf *buf ); } 44 AUE_FSTATFS STD { int linux_fstatfs( l_uint fd, struct l_statfs_buf *buf ); } 45 AUE_TRUNCATE STD { int linux_truncate( char *path, l_ulong length ); } 46 AUE_FTRUNCATE STD { int linux_ftruncate( l_int fd, l_long length ); } 47 AUE_NULL STD { int linux_fallocate( l_int fd, l_int mode, l_loff_t offset, l_loff_t len ); } 48 AUE_FACCESSAT STD { int linux_faccessat( l_int dfd, const char *filename, l_int amode ); } 49 AUE_CHDIR STD { int linux_chdir( char *path ); } 50 AUE_FCHDIR NOPROTO { int fchdir( int fd); } 51 AUE_CHROOT NOPROTO { int chroot( char *path ); } 52 AUE_FCHMOD NOPROTO { int fchmod( int fd, int mode ); } 53 AUE_FCHMODAT STD { int linux_fchmodat( l_int dfd, const char *filename, l_mode_t mode ); } 54 AUE_FCHOWNAT STD { int linux_fchownat( l_int dfd, const char *filename, l_uid_t uid, l_gid_t gid, l_int flag ); } 55 AUE_FCHOWN NOPROTO { int fchown( int fd, int uid, int gid); } 56 AUE_OPEN_RWTC STD { int linux_openat( l_int dfd, const char *filename, l_int flags, l_mode_t mode ); } 57 AUE_CLOSE NOPROTO { int close( int fd); } 58 AUE_NULL STD { int linux_vhangup(void); } 59 AUE_NULL STD { int linux_pipe2( l_int *pipefds, l_int flags ); } 60 AUE_NULL UNIMPL linux_quotactl 61 AUE_GETDIRENTRIES STD { int linux_getdents64( l_uint fd, void *dirent, l_uint count ); } 62 AUE_LSEEK STD { int linux_lseek( l_uint fdes, l_off_t off, l_int whence ); } 63 AUE_NULL NOPROTO { int read( int fd, char *buf, l_size_t nbyte ); } 64 AUE_NULL NOPROTO { int write( int fd, char *buf, l_size_t nbyte ); } 65 AUE_READV NOPROTO { int readv( int fd, struct iovec *iovp, u_int iovcnt ); } 66 AUE_WRITEV NOPROTO { int writev( int fd, struct iovec *iovp, u_int iovcnt ); } 67 AUE_PREAD STD { int linux_pread( l_uint fd, char *buf, l_size_t nbyte, l_loff_t offset ); } 68 AUE_PWRITE STD { int linux_pwrite( l_uint fd, char *buf, l_size_t nbyte, l_loff_t offset ); } 69 AUE_NULL STD { int linux_preadv( l_ulong fd, struct iovec *vec, l_ulong vlen, l_ulong pos_l, l_ulong pos_h ); } 70 AUE_NULL STD { int linux_pwritev( l_ulong fd, struct iovec *vec, l_ulong vlen, l_ulong pos_l, l_ulong pos_h ); } 71 AUE_SENDFILE STD { int linux_sendfile( l_int out, l_int in, l_off_t *offset, l_size_t count ); } 72 AUE_SELECT STD { int linux_pselect6( l_int nfds, l_fd_set *readfds, l_fd_set *writefds, l_fd_set *exceptfds, struct l_timespec *tsp, l_uintptr_t *sig ); } 73 AUE_POLL STD { int linux_ppoll( struct pollfd *fds, l_uint nfds, struct l_timespec *tsp, l_sigset_t *sset, l_size_t ssize ); } 74 AUE_NULL STD { int linux_signalfd4(void); } 75 AUE_NULL STD { int linux_vmsplice(void); } 76 AUE_NULL STD { int linux_splice( int fd_in, l_loff_t *off_in, int fd_out, l_loff_t *off_out, l_size_t len, l_uint flags ); } 77 AUE_NULL STD { int linux_tee(void); } 78 AUE_READLINKAT STD { int linux_readlinkat( l_int dfd, const char *path, char *buf, l_int bufsiz ); } 79 AUE_FSTATAT STD { int linux_newfstatat( l_int dfd, char *pathname, struct l_stat64 *statbuf, l_int flag ); } 80 AUE_FSTAT STD { int linux_newfstat( l_uint fd, struct l_newstat *buf ); } 81 AUE_NULL UNIMPL linux_sync 82 AUE_FSYNC NOPROTO { int fsync( int fd); } 83 AUE_NULL STD { int linux_fdatasync( l_uint fd); } 84 AUE_NULL STD { int linux_sync_file_range( l_int fd, l_loff_t offset, l_loff_t nbytes, l_uint flags ); } 85 AUE_NULL STD { int linux_timerfd_create( l_int clockid, l_int flags ); } 86 AUE_NULL STD { int linux_timerfd_settime( l_int fd, l_int flags, const struct l_itimerspec *new_value, struct l_itimerspec *old_value ); } 87 AUE_NULL STD { int linux_timerfd_gettime( l_int fd, struct l_itimerspec *old_value ); } 88 AUE_FUTIMESAT STD { int linux_utimensat( l_int dfd, const char *pathname, const struct l_timespec *times, l_int flags ); } 89 AUE_ACCT NOPROTO { int acct( char *path ); } 90 AUE_CAPGET STD { int linux_capget( struct l_user_cap_header *hdrp, struct l_user_cap_data *datap ); } 91 AUE_CAPSET STD { int linux_capset( struct l_user_cap_header *hdrp, struct l_user_cap_data *datap ); } 92 AUE_PERSONALITY STD { int linux_personality( l_uint per ); } 93 AUE_EXIT STD { int linux_exit( u_int rval ); } 94 AUE_EXIT STD { int linux_exit_group( l_int error_code ); } 95 AUE_WAIT6 STD { int linux_waitid( l_int idtype, l_pid_t id, l_siginfo_t *info, l_int options, struct rusage *rusage ); } 96 AUE_NULL STD { int linux_set_tid_address( l_int *tidptr ); } 97 AUE_NULL STD { int linux_unshare(void); } 98 AUE_NULL STD { int linux_sys_futex(void *uaddr, int op, int val, struct l_timespec *timeout, void *uaddr2, int val3 ); } 99 AUE_NULL STD { int linux_set_robust_list( struct linux_robust_list_head *head, l_size_t len ); } 100 AUE_NULL STD { int linux_get_robust_list( l_int pid, struct linux_robust_list_head **head, l_size_t *len ); } 101 AUE_NULL STD { int linux_nanosleep( const struct l_timespec *rqtp, struct l_timespec *rmtp ); } 102 AUE_GETITIMER STD { int linux_getitimer( l_int which, struct l_itimerval *itv ); } 103 AUE_SETITIMER STD { int linux_setitimer( l_int which, struct l_itimerval *itv, struct l_itimerval *oitv ); } 104 AUE_NULL STD { int linux_kexec_load(void); } 105 AUE_NULL STD { int linux_init_module(void); } 106 AUE_NULL STD { int linux_delete_module(void); } 107 AUE_NULL STD { int linux_timer_create( clockid_t clock_id, struct sigevent *evp, l_timer_t *timerid); } 108 AUE_NULL STD { int linux_timer_gettime( l_timer_t timerid, struct itimerspec *setting ); } 109 AUE_NULL STD { int linux_timer_getoverrun( l_timer_t timerid); } 110 AUE_NULL STD { int linux_timer_settime( l_timer_t timerid, l_int flags, const struct itimerspec *new, struct itimerspec *old); } 111 AUE_NULL STD { int linux_timer_delete( l_timer_t timerid); } 112 AUE_CLOCK_SETTIME STD { int linux_clock_settime( clockid_t which, struct l_timespec *tp ); } 113 AUE_NULL STD { int linux_clock_gettime( clockid_t which, struct l_timespec *tp ); } 114 AUE_NULL STD { int linux_clock_getres( clockid_t which, struct l_timespec *tp ); } 115 AUE_NULL STD { int linux_clock_nanosleep( clockid_t which, l_int flags, struct l_timespec *rqtp, struct l_timespec *rmtp ); } 116 AUE_NULL STD { int linux_syslog( l_int type, char *buf, l_int len ); } 117 AUE_PTRACE STD { int linux_ptrace( l_long req, l_long pid, l_ulong addr, l_ulong data ); } 118 AUE_SCHED_SETPARAM STD { int linux_sched_setparam( l_pid_t pid, struct sched_param *param ); } 119 AUE_SCHED_SETSCHEDULER STD { int linux_sched_setscheduler( l_pid_t pid, l_int policy, struct sched_param *param ); } 120 AUE_SCHED_GETSCHEDULER STD { int linux_sched_getscheduler( l_pid_t pid); } 121 AUE_SCHED_GETPARAM STD { int linux_sched_getparam( l_pid_t pid, struct sched_param *param ); } 122 AUE_NULL STD { int linux_sched_setaffinity( l_pid_t pid, l_uint len, l_ulong *user_mask_ptr ); } 123 AUE_NULL STD { int linux_sched_getaffinity( l_pid_t pid, l_uint len, l_ulong *user_mask_ptr ); } 124 AUE_NULL NOPROTO { int sched_yield(void); } 125 AUE_SCHED_GET_PRIORITY_MAX STD { int linux_sched_get_priority_max( \ l_int policy ); } 126 AUE_SCHED_GET_PRIORITY_MIN STD { int linux_sched_get_priority_min( \ l_int policy ); } 127 AUE_SCHED_RR_GET_INTERVAL STD { int linux_sched_rr_get_interval( l_pid_t pid, struct l_timespec *interval ); } 128 AUE_NULL UNIMPL restart_syscall 129 AUE_KILL STD { int linux_kill( l_pid_t pid, l_int signum ); } 130 AUE_NULL STD { int linux_tkill( l_pid_t tid, l_int sig ); } 131 AUE_NULL STD { int linux_tgkill( l_pid_t tgid, l_pid_t pid, l_int sig ); } 132 AUE_NULL STD { int linux_sigaltstack( l_stack_t *uss, l_stack_t *uoss ); } 133 AUE_NULL STD { int linux_rt_sigsuspend( l_sigset_t *newset, l_size_t sigsetsize ); } 134 AUE_NULL STD { int linux_rt_sigaction( l_int sig, l_sigaction_t *act, l_sigaction_t *oact, l_size_t sigsetsize ); } 135 AUE_NULL STD { int linux_rt_sigprocmask( l_int how, l_sigset_t *mask, l_sigset_t *omask, l_size_t sigsetsize ); } 136 AUE_NULL STD { int linux_rt_sigpending( l_sigset_t *set, l_size_t sigsetsize ); } 137 AUE_NULL STD { int linux_rt_sigtimedwait( l_sigset_t *mask, l_siginfo_t *ptr, struct l_timeval *timeout, l_size_t sigsetsize ); } 138 AUE_NULL STD { int linux_rt_sigqueueinfo( l_pid_t pid, l_int sig, l_siginfo_t *info ); } 139 AUE_NULL STD { int linux_rt_sigreturn( struct l_ucontext *ucp ); } 140 AUE_SETPRIORITY NOPROTO { int setpriority( int which, int who, int prio ); } 141 AUE_GETPRIORITY STD { int linux_getpriority( l_int which, l_int who ); } 142 AUE_REBOOT STD { int linux_reboot( l_int magic1, l_int magic2, l_uint cmd, void *arg ); } 143 AUE_SETREGID NOPROTO { int setregid( gid_t rgid, gid_t egid); } 144 AUE_SETGID NOPROTO { int setgid( gid_t gid); } 145 AUE_SETREUID NOPROTO { int setreuid( uid_t ruid, uid_t euid); } 146 AUE_SETUID NOPROTO { int setuid( uid_t uid); } 147 AUE_SETRESUID NOPROTO { int setresuid( uid_t ruid, uid_t euid, uid_t suid); } 148 AUE_GETRESUID NOPROTO { int getresuid( uid_t *ruid, uid_t *euid, uid_t *suid); } 149 AUE_SETRESGID NOPROTO { int setresgid( gid_t rgid, gid_t egid, gid_t sgid); } 150 AUE_GETRESGID NOPROTO { int getresgid( gid_t *rgid, gid_t *egid, gid_t *sgid); } 151 AUE_SETFSUID STD { int linux_setfsuid( l_uid_t uid); } 152 AUE_SETFSGID STD { int linux_setfsgid( l_gid_t gid); } 153 AUE_NULL STD { int linux_times( struct l_times_argv *buf ); } 154 AUE_SETPGRP NOPROTO { int setpgid( int pid, int pgid); } 155 AUE_GETPGID NOPROTO { int getpgid( int pid); } 156 AUE_GETSID STD { int linux_getsid( l_pid_t pid); } 157 AUE_SETSID NOPROTO { int setsid(void); } 158 AUE_GETGROUPS STD { int linux_getgroups( l_int gidsetsize, l_gid_t *grouplist ); } 159 AUE_SETGROUPS STD { int linux_setgroups( l_int gidsetsize, l_gid_t *grouplist ); } 160 AUE_NULL STD { int linux_newuname( struct l_new_utsname *buf ); } 161 AUE_SYSCTL STD { int linux_sethostname( char *hostname, l_uint len ); } 162 AUE_SYSCTL STD { int linux_setdomainname( char *name, l_int len ); } 163 AUE_GETRLIMIT STD { int linux_getrlimit( l_uint resource, struct l_rlimit *rlim ); } 164 AUE_SETRLIMIT STD { int linux_setrlimit( l_uint resource, struct l_rlimit *rlim ); } 165 AUE_GETRUSAGE NOPROTO { int getrusage( int who, struct rusage *rusage ); } 166 AUE_UMASK NOPROTO { int umask( int newmask ); } 167 AUE_PRCTL STD { int linux_prctl( l_int option, l_uintptr_t arg2, l_uintptr_t arg3, l_uintptr_t arg4, l_uintptr_t arg5 ); } 168 AUE_NULL STD { int linux_getcpu( l_uint *cpu, l_uint *node, void *cache ); } 169 AUE_NULL NOPROTO { int gettimeofday( struct l_timeval *tp, struct timezone *tzp ); } 170 AUE_SETTIMEOFDAY NOPROTO { int settimeofday( struct l_timeval *tv, struct timezone *tzp ); } 171 AUE_ADJTIME STD { int linux_adjtimex(void); } 172 AUE_GETPID STD { int linux_getpid(void); } 173 AUE_GETPPID STD { int linux_getppid(void); } 174 AUE_GETUID STD { int linux_getuid(void); } 175 AUE_GETEUID NOPROTO { int geteuid(void); } 176 AUE_GETGID STD { int linux_getgid(void); } 177 AUE_GETEGID NOPROTO { int getegid(void); } 178 AUE_NULL STD { int linux_gettid(void); } 179 AUE_NULL STD { int linux_sysinfo( struct l_sysinfo *info ); } 180 AUE_NULL STD { int linux_mq_open( const char *name, l_int oflag, l_mode_t mode, struct mq_attr *attr ); } 181 AUE_NULL STD { int linux_mq_unlink( const char *name ); } 182 AUE_NULL STD { int linux_mq_timedsend( l_mqd_t mqd, const char *msg_ptr, l_size_t msg_len, l_uint msg_prio, const struct l_timespec *abs_timeout ); } 183 AUE_NULL STD { int linux_mq_timedreceive( l_mqd_t mqd, char *msg_ptr, l_size_t msg_len, l_uint *msg_prio, const struct l_timespec *abs_timeout ); } 184 AUE_NULL STD { int linux_mq_notify( l_mqd_t mqd, const struct l_timespec *abs_timeout ); } 185 AUE_NULL STD { int linux_mq_getsetattr( l_mqd_t mqd, const struct mq_attr *attr, struct mq_attr *oattr ); } 186 AUE_NULL STD { int linux_msgget( l_key_t key, l_int msgflg ); } 187 AUE_NULL STD { int linux_msgctl( l_int msqid, l_int cmd, struct l_msqid_ds *buf ); } 188 AUE_NULL STD { int linux_msgrcv( l_int msqid, struct l_msgbuf *msgp, l_size_t msgsz, l_long msgtyp, l_int msgflg ); } 189 AUE_NULL STD { int linux_msgsnd( l_int msqid, struct l_msgbuf *msgp, l_size_t msgsz, l_int msgflg ); } 190 AUE_NULL STD { int linux_semget( l_key_t key, l_int nsems, l_int semflg ); } 191 AUE_NULL STD { int linux_semctl( l_int semid, l_int semnum, l_int cmd, union l_semun arg ); } 192 AUE_NULL STD { int linux_semtimedop(void); } 193 AUE_NULL STD { int linux_semop( l_int semid, struct l_sembuf *tsops, l_uint nsops ); } 194 AUE_NULL STD { int linux_shmget( l_key_t key, l_size_t size, l_int shmflg ); } 195 AUE_NULL STD { int linux_shmctl( l_int shmid, l_int cmd, struct l_shmid_ds *buf ); } 196 AUE_NULL STD { int linux_shmat( l_int shmid, char *shmaddr, l_int shmflg ); } 197 AUE_NULL STD { int linux_shmdt( char *shmaddr ); } 198 AUE_SOCKET STD { int linux_socket( l_int domain, l_int type, l_int protocol ); } 199 AUE_SOCKETPAIR STD { int linux_socketpair( l_int domain, l_int type, l_int protocol, l_uintptr_t rsv ); } 200 AUE_BIND STD { int linux_bind( l_int s, l_uintptr_t name, l_int namelen ); } 201 AUE_LISTEN STD { int linux_listen( l_int s, l_int backlog ); } 202 AUE_ACCEPT STD { int linux_accept( l_int s, l_uintptr_t addr, l_uintptr_t namelen ); } 203 AUE_CONNECT STD { int linux_connect( l_int s, l_uintptr_t name, l_int namelen ); } 204 AUE_GETSOCKNAME STD { int linux_getsockname( l_int s, l_uintptr_t addr, l_uintptr_t namelen ); } 205 AUE_GETPEERNAME STD { int linux_getpeername( l_int s, l_uintptr_t addr, l_uintptr_t namelen ); } 206 AUE_SENDTO STD { int linux_sendto( l_int s, l_uintptr_t msg, l_size_t len, l_uint flags, l_uintptr_t to, l_int tolen ); } 207 AUE_RECVFROM STD { int linux_recvfrom( l_int s, l_uintptr_t buf, l_size_t len, l_uint flags, l_uintptr_t from, l_uintptr_t fromlen ); } 208 AUE_SETSOCKOPT STD { int linux_setsockopt( l_int s, l_int level, l_int optname, l_uintptr_t optval, l_int optlen ); } 209 AUE_GETSOCKOPT STD { int linux_getsockopt( l_int s, l_int level, l_int optname, l_uintptr_t optval, l_uintptr_t optlen ); } 210 AUE_NULL STD { int linux_shutdown( l_int s, l_int how ); } 211 AUE_SENDMSG STD { int linux_sendmsg( l_int s, l_uintptr_t msg, l_uint flags ); } 212 AUE_RECVMSG STD { int linux_recvmsg( l_int s, l_uintptr_t msg, l_uint flags ); } 213 AUE_NULL UNIMPL linux_readahead 214 AUE_NULL STD { int linux_brk( l_ulong dsend); } 215 AUE_MUNMAP NOPROTO { int munmap( void *addr, l_size_t len ); } 216 AUE_NULL STD { int linux_mremap( l_ulong addr, l_ulong old_len, l_ulong new_len, l_ulong flags, l_ulong new_addr ); } 217 AUE_NULL STD { int linux_add_key(void); } 218 AUE_NULL STD { int linux_request_key(void); } 219 AUE_NULL STD { int linux_keyctl(void); } 220 AUE_RFORK STD { int linux_clone( l_ulong flags, void *stack, void *parent_tidptr, void *tls, void *child_tidptr ); } 221 AUE_EXECVE STD { int linux_execve( char *path, char **argp, char **envp ); } 222 AUE_MMAP STD { int linux_mmap2( l_ulong addr, l_ulong len, l_ulong prot, l_ulong flags, l_ulong fd, l_ulong pgoff ); } 223 AUE_NULL STD { int linux_fadvise64( l_int fd, l_loff_t offset, l_size_t len, l_int advice ); } 224 AUE_SWAPON NOPROTO { int swapon( char *name ); } 225 AUE_SWAPOFF STD { int linux_swapoff(void); } 226 AUE_MPROTECT STD { int linux_mprotect( l_ulong addr, l_size_t len, l_ulong prot ); } 227 AUE_MSYNC STD { int linux_msync( l_ulong addr, l_size_t len, l_int fl ); } 228 AUE_MLOCK NOPROTO { int mlock( const void *addr, size_t len ); } 229 AUE_MUNLOCK NOPROTO { int munlock( const void *addr, size_t len ); } 230 AUE_MLOCKALL NOPROTO { int mlockall( int how ); } 231 AUE_MUNLOCKALL NOPROTO { int munlockall(void); } 232 AUE_MINCORE STD { int linux_mincore( l_ulong start, l_size_t len, u_char *vec ); } 233 AUE_MADVISE STD { int linux_madvise( l_ulong addr, l_size_t len, l_int behav ); } 234 AUE_NULL STD { int linux_remap_file_pages(void); } 235 AUE_NULL STD { int linux_mbind(void); } 236 AUE_NULL STD { int linux_get_mempolicy(void); } 237 AUE_NULL STD { int linux_set_mempolicy(void); } 238 AUE_NULL STD { int linux_migrate_pages(void); } 239 AUE_NULL STD { int linux_move_pages(void); } 240 AUE_NULL STD { int linux_rt_tgsigqueueinfo( l_pid_t tgid, l_pid_t tid, l_int sig, l_siginfo_t *uinfo ); } 241 AUE_NULL STD { int linux_perf_event_open(void); } 242 AUE_ACCEPT STD { int linux_accept4( l_int s, l_uintptr_t addr, l_uintptr_t namelen, l_int flags ); } 243 AUE_NULL STD { int linux_recvmmsg( l_int s, struct l_mmsghdr *msg, l_uint vlen, l_uint flags, struct l_timespec *timeout ); } 244-259 AUE_NULL UNIMPL unimpl_md_syscall 260 AUE_WAIT4 STD { int linux_wait4( l_pid_t pid, l_int *status, l_int options, struct rusage *rusage ); } 261 AUE_NULL STD { int linux_prlimit64( l_pid_t pid, l_uint resource, struct rlimit *new, struct rlimit *old); } 262 AUE_NULL STD { int linux_fanotify_init(void); } 263 AUE_NULL STD { int linux_fanotify_mark(void); } 264 AUE_NULL STD { - int linux_name_to_handle_at(void); + int linux_name_to_handle_at( + l_int dirfd, + const char *name, + struct l_file_handle *handle, + l_int *mnt_id, + l_int flags + ); } 265 AUE_NULL STD { - int linux_open_by_handle_at(void); + int linux_open_by_handle_at( + l_int mountdirfd, + struct l_file_handle *handle, + l_int flags + ); } 266 AUE_NULL STD { int linux_clock_adjtime(void); } 267 AUE_SYNC STD { int linux_syncfs( l_int fd); } 268 AUE_NULL STD { int linux_setns( l_int fd, l_int nstype ); } 269 AUE_NULL STD { int linux_sendmmsg( l_int s, struct l_mmsghdr *msg, l_uint vlen, l_uint flags ); } 270 AUE_NULL STD { int linux_process_vm_readv( l_pid_t pid, const struct iovec *lvec, l_ulong liovcnt, const struct iovec *rvec, l_ulong riovcnt, l_ulong flags ); } 271 AUE_NULL STD { int linux_process_vm_writev( l_pid_t pid, const struct iovec *lvec, l_ulong liovcnt, const struct iovec *rvec, l_ulong riovcnt, l_ulong flags ); } 272 AUE_NULL STD { int linux_kcmp( l_pid_t pid1, l_pid_t pid2, l_int type, l_ulong idx1, l_ulong idx ); } 273 AUE_NULL STD { int linux_finit_module( l_int fd, const char *uargs, l_int flags ); } 274 AUE_NULL STD { int linux_sched_setattr( l_pid_t pid, void *attr, l_uint flags ); } 275 AUE_NULL STD { int linux_sched_getattr( l_pid_t pid, void *attr, l_uint size, l_uint flags ); } 276 AUE_NULL STD { int linux_renameat2( l_int olddfd, const char *oldname, l_int newdfd, const char *newname, l_uint flags ); } 277 AUE_NULL STD { int linux_seccomp( l_uint op, l_uint flags, const char *uargs ); } 278 AUE_NULL STD { int linux_getrandom( char *buf, l_size_t count, l_uint flags ); } 279 AUE_NULL STD { int linux_memfd_create( const char *uname_ptr, l_uint flags ); } 280 AUE_NULL STD { int linux_bpf( l_int cmd, void *attr, l_uint size ); } 281 AUE_NULL STD { int linux_execveat( l_int dfd, const char *filename, const char **argv, const char **envp, l_int flags ); } 282 AUE_NULL STD { int linux_userfaultfd( l_int flags ); } 283 AUE_NULL STD { int linux_membarrier( l_int cmd, l_int flags ); } 284 AUE_NULL STD { int linux_mlock2( l_ulong start, l_size_t len, l_int flags ); } 285 AUE_NULL STD { int linux_copy_file_range( l_int fd_in, l_loff_t *off_in, l_int fd_out, l_loff_t *off_out, l_size_t len, l_uint flags ); } 286 AUE_NULL STD { int linux_preadv2( l_ulong fd, const struct iovec *vec, l_ulong vlen, l_ulong pos_l, l_ulong pos_h, l_int flags ); } 287 AUE_NULL STD { int linux_pwritev2( l_ulong fd, const struct iovec *vec, l_ulong vlen, l_ulong pos_l, l_ulong pos_h, l_int flags ); } 288 AUE_NULL STD { int linux_pkey_mprotect( l_ulong start, l_size_t len, l_ulong prot, l_int pkey ); } 289 AUE_NULL STD { int linux_pkey_alloc( l_ulong flags, l_ulong init_val ); } 290 AUE_NULL STD { int linux_pkey_free( l_int pkey ); } ; please, keep this line at the end. 291 AUE_NULL UNIMPL nosys ; vim: syntax=off Index: head/sys/compat/linux/linux_dummy.c =================================================================== --- head/sys/compat/linux/linux_dummy.c (revision 367772) +++ head/sys/compat/linux/linux_dummy.c (revision 367773) @@ -1,157 +1,155 @@ /*- * SPDX-License-Identifier: BSD-2-Clause-FreeBSD * * Copyright (c) 2013 Dmitry Chagin * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */ #include __FBSDID("$FreeBSD$"); #include #include #include #include #include /* * Including linux vs linux32 here is arbitrary -- the syscall args structures * (proto.h) are not dereferenced by the DUMMY stub implementations, and * suitable for use by both native and compat32 entrypoints. */ #include #include #include #include /* DTrace init */ LIN_SDT_PROVIDER_DECLARE(LINUX_DTRACE); UNIMPLEMENTED(afs_syscall); UNIMPLEMENTED(create_module); /* Added in Linux 1.0 removed in 2.6. */ UNIMPLEMENTED(epoll_ctl_old); UNIMPLEMENTED(epoll_wait_old); UNIMPLEMENTED(get_kernel_syms); /* Added in Linux 1.0 removed in 2.6. */ UNIMPLEMENTED(getpmsg); UNIMPLEMENTED(nfsservctl); /* Added in Linux 2.2 removed in 3.1. */ UNIMPLEMENTED(putpmsg); UNIMPLEMENTED(query_module); /* Added in Linux 2.2 removed in 2.6. */ UNIMPLEMENTED(security); UNIMPLEMENTED(vserver); DUMMY(setfsuid); DUMMY(setfsgid); DUMMY(vhangup); DUMMY(pivot_root); DUMMY(adjtimex); DUMMY(swapoff); DUMMY(init_module); DUMMY(delete_module); DUMMY(lookup_dcookie); DUMMY(remap_file_pages); DUMMY(mbind); DUMMY(get_mempolicy); DUMMY(set_mempolicy); DUMMY(kexec_load); /* Linux 2.6.11: */ DUMMY(add_key); DUMMY(request_key); DUMMY(keyctl); /* Linux 2.6.13: */ DUMMY(ioprio_set); DUMMY(ioprio_get); DUMMY(inotify_add_watch); DUMMY(inotify_rm_watch); /* Linux 2.6.16: */ DUMMY(migrate_pages); DUMMY(unshare); /* Linux 2.6.17: */ DUMMY(tee); DUMMY(vmsplice); /* Linux 2.6.18: */ DUMMY(move_pages); /* Linux 2.6.27: */ DUMMY(signalfd4); DUMMY(inotify_init1); /* Linux 2.6.31: */ DUMMY(perf_event_open); /* Linux 2.6.36: */ DUMMY(fanotify_init); DUMMY(fanotify_mark); /* Linux 2.6.39: */ -DUMMY(name_to_handle_at); -DUMMY(open_by_handle_at); DUMMY(clock_adjtime); /* Linux 3.0: */ DUMMY(setns); /* Linux 3.2: */ DUMMY(process_vm_readv); DUMMY(process_vm_writev); /* Linux 3.5: */ DUMMY(kcmp); /* Linux 3.8: */ DUMMY(finit_module); DUMMY(sched_setattr); DUMMY(sched_getattr); /* Linux 3.17: */ DUMMY(seccomp); /* Linux 3.18: */ DUMMY(bpf); /* Linux 3.19: */ DUMMY(execveat); /* Linux 4.2: */ DUMMY(userfaultfd); /* Linux 4.3: */ DUMMY(membarrier); /* Linux 4.4: */ DUMMY(mlock2); /* Linux 4.6: */ DUMMY(preadv2); DUMMY(pwritev2); /* Linux 4.8: */ DUMMY(pkey_mprotect); DUMMY(pkey_alloc); DUMMY(pkey_free); #define DUMMY_XATTR(s) \ int \ linux_ ## s ## xattr( \ struct thread *td, struct linux_ ## s ## xattr_args *arg) \ { \ \ return (EOPNOTSUPP); \ } DUMMY_XATTR(set); DUMMY_XATTR(lset); DUMMY_XATTR(fset); DUMMY_XATTR(get); DUMMY_XATTR(lget); DUMMY_XATTR(fget); DUMMY_XATTR(list); DUMMY_XATTR(llist); DUMMY_XATTR(flist); DUMMY_XATTR(remove); DUMMY_XATTR(lremove); DUMMY_XATTR(fremove); Index: head/sys/compat/linux/linux_file.c =================================================================== --- head/sys/compat/linux/linux_file.c (revision 367772) +++ head/sys/compat/linux/linux_file.c (revision 367773) @@ -1,1920 +1,2024 @@ /*- * SPDX-License-Identifier: BSD-2-Clause-FreeBSD * * Copyright (c) 1994-1995 Søren Schmidt * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */ #include __FBSDID("$FreeBSD$"); #include "opt_compat.h" #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #ifdef COMPAT_LINUX32 #include #include #include #else #include #include #endif #include #include #include static int linux_common_open(struct thread *, int, const char *, int, int, enum uio_seg); static int linux_getdents_error(struct thread *, int, int); static struct bsd_to_linux_bitmap seal_bitmap[] = { BITMAP_1t1_LINUX(F_SEAL_SEAL), BITMAP_1t1_LINUX(F_SEAL_SHRINK), BITMAP_1t1_LINUX(F_SEAL_GROW), BITMAP_1t1_LINUX(F_SEAL_WRITE), }; #define MFD_HUGETLB_ENTRY(_size) \ { \ .bsd_value = MFD_HUGE_##_size, \ .linux_value = LINUX_HUGETLB_FLAG_ENCODE_##_size \ } static struct bsd_to_linux_bitmap mfd_bitmap[] = { BITMAP_1t1_LINUX(MFD_CLOEXEC), BITMAP_1t1_LINUX(MFD_ALLOW_SEALING), BITMAP_1t1_LINUX(MFD_HUGETLB), MFD_HUGETLB_ENTRY(64KB), MFD_HUGETLB_ENTRY(512KB), MFD_HUGETLB_ENTRY(1MB), MFD_HUGETLB_ENTRY(2MB), MFD_HUGETLB_ENTRY(8MB), MFD_HUGETLB_ENTRY(16MB), MFD_HUGETLB_ENTRY(32MB), MFD_HUGETLB_ENTRY(256MB), MFD_HUGETLB_ENTRY(512MB), MFD_HUGETLB_ENTRY(1GB), MFD_HUGETLB_ENTRY(2GB), MFD_HUGETLB_ENTRY(16GB), }; #undef MFD_HUGETLB_ENTRY #ifdef LINUX_LEGACY_SYSCALLS int linux_creat(struct thread *td, struct linux_creat_args *args) { char *path; int error; if (!LUSECONVPATH(td)) { return (kern_openat(td, AT_FDCWD, args->path, UIO_USERSPACE, O_WRONLY | O_CREAT | O_TRUNC, args->mode)); } LCONVPATHEXIST(td, args->path, &path); error = kern_openat(td, AT_FDCWD, path, UIO_SYSSPACE, O_WRONLY | O_CREAT | O_TRUNC, args->mode); LFREEPATH(path); return (error); } #endif static int -linux_common_open(struct thread *td, int dirfd, const char *path, int l_flags, - int mode, enum uio_seg seg) +linux_common_openflags(int l_flags) { - struct proc *p = td->td_proc; - struct file *fp; - int fd; - int bsd_flags, error; + int bsd_flags; bsd_flags = 0; switch (l_flags & LINUX_O_ACCMODE) { case LINUX_O_WRONLY: bsd_flags |= O_WRONLY; break; case LINUX_O_RDWR: bsd_flags |= O_RDWR; break; default: bsd_flags |= O_RDONLY; } if (l_flags & LINUX_O_NDELAY) bsd_flags |= O_NONBLOCK; if (l_flags & LINUX_O_APPEND) bsd_flags |= O_APPEND; if (l_flags & LINUX_O_SYNC) bsd_flags |= O_FSYNC; if (l_flags & LINUX_O_CLOEXEC) bsd_flags |= O_CLOEXEC; if (l_flags & LINUX_O_NONBLOCK) bsd_flags |= O_NONBLOCK; if (l_flags & LINUX_O_ASYNC) bsd_flags |= O_ASYNC; if (l_flags & LINUX_O_CREAT) bsd_flags |= O_CREAT; if (l_flags & LINUX_O_TRUNC) bsd_flags |= O_TRUNC; if (l_flags & LINUX_O_EXCL) bsd_flags |= O_EXCL; if (l_flags & LINUX_O_NOCTTY) bsd_flags |= O_NOCTTY; if (l_flags & LINUX_O_DIRECT) bsd_flags |= O_DIRECT; if (l_flags & LINUX_O_NOFOLLOW) bsd_flags |= O_NOFOLLOW; if (l_flags & LINUX_O_DIRECTORY) bsd_flags |= O_DIRECTORY; /* XXX LINUX_O_NOATIME: unable to be easily implemented. */ + return (bsd_flags); +} +static int +linux_common_open(struct thread *td, int dirfd, const char *path, int l_flags, + int mode, enum uio_seg seg) +{ + struct proc *p = td->td_proc; + struct file *fp; + int fd; + int bsd_flags, error; + + bsd_flags = linux_common_openflags(l_flags); error = kern_openat(td, dirfd, path, seg, bsd_flags, mode); if (error != 0) { if (error == EMLINK) error = ELOOP; goto done; } if (p->p_flag & P_CONTROLT) goto done; if (bsd_flags & O_NOCTTY) goto done; /* * XXX In between kern_openat() and fget(), another process * having the same filedesc could use that fd without * checking below. */ fd = td->td_retval[0]; if (fget(td, fd, &cap_ioctl_rights, &fp) == 0) { if (fp->f_type != DTYPE_VNODE) { fdrop(fp, td); goto done; } sx_slock(&proctree_lock); PROC_LOCK(p); if (SESS_LEADER(p) && !(p->p_flag & P_CONTROLT)) { PROC_UNLOCK(p); sx_sunlock(&proctree_lock); /* XXXPJD: Verify if TIOCSCTTY is allowed. */ (void) fo_ioctl(fp, TIOCSCTTY, (caddr_t) 0, td->td_ucred, td); } else { PROC_UNLOCK(p); sx_sunlock(&proctree_lock); } fdrop(fp, td); } done: return (error); } int linux_openat(struct thread *td, struct linux_openat_args *args) { char *path; int dfd, error; dfd = (args->dfd == LINUX_AT_FDCWD) ? AT_FDCWD : args->dfd; if (!LUSECONVPATH(td)) { return (linux_common_open(td, dfd, args->filename, args->flags, args->mode, UIO_USERSPACE)); } if (args->flags & LINUX_O_CREAT) LCONVPATH_AT(td, args->filename, &path, 1, dfd); else LCONVPATH_AT(td, args->filename, &path, 0, dfd); error = linux_common_open(td, dfd, path, args->flags, args->mode, UIO_SYSSPACE); LFREEPATH(path); return (error); } #ifdef LINUX_LEGACY_SYSCALLS int linux_open(struct thread *td, struct linux_open_args *args) { char *path; int error; if (!LUSECONVPATH(td)) { return (linux_common_open(td, AT_FDCWD, args->path, args->flags, args->mode, UIO_USERSPACE)); } if (args->flags & LINUX_O_CREAT) LCONVPATHCREAT(td, args->path, &path); else LCONVPATHEXIST(td, args->path, &path); error = linux_common_open(td, AT_FDCWD, path, args->flags, args->mode, UIO_SYSSPACE); LFREEPATH(path); return (error); } #endif + +int +linux_name_to_handle_at(struct thread *td, + struct linux_name_to_handle_at_args *args) +{ + static const l_int valid_flags = (LINUX_AT_SYMLINK_FOLLOW | + LINUX_AT_EMPTY_PATH); + static const l_uint fh_size = sizeof(fhandle_t); + + fhandle_t fh; + l_uint fh_bytes; + l_int mount_id; + int error, fd, bsd_flags; + + if (args->flags & ~valid_flags) + return (EINVAL); + if (args->flags & LINUX_AT_EMPTY_PATH) + /* XXX: not supported yet */ + return (EOPNOTSUPP); + + fd = args->dirfd; + if (fd == LINUX_AT_FDCWD) + fd = AT_FDCWD; + + bsd_flags = 0; + if (!(args->flags & LINUX_AT_SYMLINK_FOLLOW)) + bsd_flags |= AT_SYMLINK_NOFOLLOW; + + if (!LUSECONVPATH(td)) { + error = kern_getfhat(td, bsd_flags, fd, args->name, + UIO_USERSPACE, &fh, UIO_SYSSPACE); + } else { + char *path; + + LCONVPATH_AT(td, args->name, &path, 0, fd); + error = kern_getfhat(td, bsd_flags, fd, path, UIO_SYSSPACE, + &fh, UIO_SYSSPACE); + LFREEPATH(path); + } + if (error != 0) + return (error); + + /* Emit mount_id -- required before EOVERFLOW case. */ + mount_id = (fh.fh_fsid.val[0] ^ fh.fh_fsid.val[1]); + error = copyout(&mount_id, args->mnt_id, sizeof(mount_id)); + if (error != 0) + return (error); + + /* Check if there is room for handle. */ + error = copyin(&args->handle->handle_bytes, &fh_bytes, + sizeof(fh_bytes)); + if (error != 0) + return (error); + + if (fh_bytes < fh_size) { + error = copyout(&fh_size, &args->handle->handle_bytes, + sizeof(fh_size)); + if (error == 0) + error = EOVERFLOW; + return (error); + } + + /* Emit handle. */ + mount_id = 0; + /* + * We don't use handle_type for anything yet, but initialize a known + * value. + */ + error = copyout(&mount_id, &args->handle->handle_type, + sizeof(mount_id)); + if (error != 0) + return (error); + + error = copyout(&fh, &args->handle->f_handle, + sizeof(fh)); + return (error); +} + +int +linux_open_by_handle_at(struct thread *td, + struct linux_open_by_handle_at_args *args) +{ + l_uint fh_bytes; + int bsd_flags, error; + + error = copyin(&args->handle->handle_bytes, &fh_bytes, + sizeof(fh_bytes)); + if (error != 0) + return (error); + + if (fh_bytes < sizeof(fhandle_t)) + return (EINVAL); + + bsd_flags = linux_common_openflags(args->flags); + return (kern_fhopen(td, (void *)&args->handle->f_handle, bsd_flags)); +} int linux_lseek(struct thread *td, struct linux_lseek_args *args) { return (kern_lseek(td, args->fdes, args->off, args->whence)); } #if defined(__i386__) || (defined(__amd64__) && defined(COMPAT_LINUX32)) int linux_llseek(struct thread *td, struct linux_llseek_args *args) { int error; off_t off; off = (args->olow) | (((off_t) args->ohigh) << 32); error = kern_lseek(td, args->fd, off, args->whence); if (error != 0) return (error); error = copyout(td->td_retval, args->res, sizeof(off_t)); if (error != 0) return (error); td->td_retval[0] = 0; return (0); } #endif /* __i386__ || (__amd64__ && COMPAT_LINUX32) */ /* * Note that linux_getdents(2) and linux_getdents64(2) have the same * arguments. They only differ in the definition of struct dirent they * operate on. * Note that linux_readdir(2) is a special case of linux_getdents(2) * where count is always equals 1, meaning that the buffer is one * dirent-structure in size and that the code can't handle more anyway. * Note that linux_readdir(2) can't be implemented by means of linux_getdents(2) * as in case when the *dent buffer size is equal to 1 linux_getdents(2) will * trash user stack. */ static int linux_getdents_error(struct thread *td, int fd, int err) { struct vnode *vp; struct file *fp; int error; /* Linux return ENOTDIR in case when fd is not a directory. */ error = getvnode(td, fd, &cap_read_rights, &fp); if (error != 0) return (error); vp = fp->f_vnode; if (vp->v_type != VDIR) { fdrop(fp, td); return (ENOTDIR); } fdrop(fp, td); return (err); } struct l_dirent { l_ulong d_ino; l_off_t d_off; l_ushort d_reclen; char d_name[LINUX_NAME_MAX + 1]; }; struct l_dirent64 { uint64_t d_ino; int64_t d_off; l_ushort d_reclen; u_char d_type; char d_name[LINUX_NAME_MAX + 1]; }; /* * Linux uses the last byte in the dirent buffer to store d_type, * at least glibc-2.7 requires it. That is why l_dirent is padded with 2 bytes. */ #define LINUX_RECLEN(namlen) \ roundup(offsetof(struct l_dirent, d_name) + (namlen) + 2, sizeof(l_ulong)) #define LINUX_RECLEN64(namlen) \ roundup(offsetof(struct l_dirent64, d_name) + (namlen) + 1, \ sizeof(uint64_t)) #ifdef LINUX_LEGACY_SYSCALLS int linux_getdents(struct thread *td, struct linux_getdents_args *args) { struct dirent *bdp; caddr_t inp, buf; /* BSD-format */ int len, reclen; /* BSD-format */ caddr_t outp; /* Linux-format */ int resid, linuxreclen; /* Linux-format */ caddr_t lbuf; /* Linux-format */ off_t base; struct l_dirent *linux_dirent; int buflen, error; size_t retval; buflen = min(args->count, MAXBSIZE); buf = malloc(buflen, M_TEMP, M_WAITOK); error = kern_getdirentries(td, args->fd, buf, buflen, &base, NULL, UIO_SYSSPACE); if (error != 0) { error = linux_getdents_error(td, args->fd, error); goto out1; } lbuf = malloc(LINUX_RECLEN(LINUX_NAME_MAX), M_TEMP, M_WAITOK | M_ZERO); len = td->td_retval[0]; inp = buf; outp = (caddr_t)args->dent; resid = args->count; retval = 0; while (len > 0) { bdp = (struct dirent *) inp; reclen = bdp->d_reclen; linuxreclen = LINUX_RECLEN(bdp->d_namlen); /* * No more space in the user supplied dirent buffer. * Return EINVAL. */ if (resid < linuxreclen) { error = EINVAL; goto out; } linux_dirent = (struct l_dirent*)lbuf; linux_dirent->d_ino = bdp->d_fileno; linux_dirent->d_off = base + reclen; linux_dirent->d_reclen = linuxreclen; /* * Copy d_type to last byte of l_dirent buffer */ lbuf[linuxreclen - 1] = bdp->d_type; strlcpy(linux_dirent->d_name, bdp->d_name, linuxreclen - offsetof(struct l_dirent, d_name)-1); error = copyout(linux_dirent, outp, linuxreclen); if (error != 0) goto out; inp += reclen; base += reclen; len -= reclen; retval += linuxreclen; outp += linuxreclen; resid -= linuxreclen; } td->td_retval[0] = retval; out: free(lbuf, M_TEMP); out1: free(buf, M_TEMP); return (error); } #endif int linux_getdents64(struct thread *td, struct linux_getdents64_args *args) { struct dirent *bdp; caddr_t inp, buf; /* BSD-format */ int len, reclen; /* BSD-format */ caddr_t outp; /* Linux-format */ int resid, linuxreclen; /* Linux-format */ caddr_t lbuf; /* Linux-format */ off_t base; struct l_dirent64 *linux_dirent64; int buflen, error; size_t retval; buflen = min(args->count, MAXBSIZE); buf = malloc(buflen, M_TEMP, M_WAITOK); error = kern_getdirentries(td, args->fd, buf, buflen, &base, NULL, UIO_SYSSPACE); if (error != 0) { error = linux_getdents_error(td, args->fd, error); goto out1; } lbuf = malloc(LINUX_RECLEN64(LINUX_NAME_MAX), M_TEMP, M_WAITOK | M_ZERO); len = td->td_retval[0]; inp = buf; outp = (caddr_t)args->dirent; resid = args->count; retval = 0; while (len > 0) { bdp = (struct dirent *) inp; reclen = bdp->d_reclen; linuxreclen = LINUX_RECLEN64(bdp->d_namlen); /* * No more space in the user supplied dirent buffer. * Return EINVAL. */ if (resid < linuxreclen) { error = EINVAL; goto out; } linux_dirent64 = (struct l_dirent64*)lbuf; linux_dirent64->d_ino = bdp->d_fileno; linux_dirent64->d_off = base + reclen; linux_dirent64->d_reclen = linuxreclen; linux_dirent64->d_type = bdp->d_type; strlcpy(linux_dirent64->d_name, bdp->d_name, linuxreclen - offsetof(struct l_dirent64, d_name)); error = copyout(linux_dirent64, outp, linuxreclen); if (error != 0) goto out; inp += reclen; base += reclen; len -= reclen; retval += linuxreclen; outp += linuxreclen; resid -= linuxreclen; } td->td_retval[0] = retval; out: free(lbuf, M_TEMP); out1: free(buf, M_TEMP); return (error); } #if defined(__i386__) || (defined(__amd64__) && defined(COMPAT_LINUX32)) int linux_readdir(struct thread *td, struct linux_readdir_args *args) { struct dirent *bdp; caddr_t buf; /* BSD-format */ int linuxreclen; /* Linux-format */ caddr_t lbuf; /* Linux-format */ off_t base; struct l_dirent *linux_dirent; int buflen, error; buflen = LINUX_RECLEN(LINUX_NAME_MAX); buf = malloc(buflen, M_TEMP, M_WAITOK); error = kern_getdirentries(td, args->fd, buf, buflen, &base, NULL, UIO_SYSSPACE); if (error != 0) { error = linux_getdents_error(td, args->fd, error); goto out; } if (td->td_retval[0] == 0) goto out; lbuf = malloc(LINUX_RECLEN(LINUX_NAME_MAX), M_TEMP, M_WAITOK | M_ZERO); bdp = (struct dirent *) buf; linuxreclen = LINUX_RECLEN(bdp->d_namlen); linux_dirent = (struct l_dirent*)lbuf; linux_dirent->d_ino = bdp->d_fileno; linux_dirent->d_off = linuxreclen; linux_dirent->d_reclen = bdp->d_namlen; strlcpy(linux_dirent->d_name, bdp->d_name, linuxreclen - offsetof(struct l_dirent, d_name)); error = copyout(linux_dirent, args->dent, linuxreclen); if (error == 0) td->td_retval[0] = linuxreclen; free(lbuf, M_TEMP); out: free(buf, M_TEMP); return (error); } #endif /* __i386__ || (__amd64__ && COMPAT_LINUX32) */ /* * These exist mainly for hooks for doing /compat/linux translation. */ #ifdef LINUX_LEGACY_SYSCALLS int linux_access(struct thread *td, struct linux_access_args *args) { char *path; int error; /* Linux convention. */ if (args->amode & ~(F_OK | X_OK | W_OK | R_OK)) return (EINVAL); if (!LUSECONVPATH(td)) { error = kern_accessat(td, AT_FDCWD, args->path, UIO_USERSPACE, 0, args->amode); } else { LCONVPATHEXIST(td, args->path, &path); error = kern_accessat(td, AT_FDCWD, path, UIO_SYSSPACE, 0, args->amode); LFREEPATH(path); } return (error); } #endif int linux_faccessat(struct thread *td, struct linux_faccessat_args *args) { char *path; int error, dfd; /* Linux convention. */ if (args->amode & ~(F_OK | X_OK | W_OK | R_OK)) return (EINVAL); dfd = (args->dfd == LINUX_AT_FDCWD) ? AT_FDCWD : args->dfd; if (!LUSECONVPATH(td)) { error = kern_accessat(td, dfd, args->filename, UIO_USERSPACE, 0, args->amode); } else { LCONVPATHEXIST_AT(td, args->filename, &path, dfd); error = kern_accessat(td, dfd, path, UIO_SYSSPACE, 0, args->amode); LFREEPATH(path); } return (error); } #ifdef LINUX_LEGACY_SYSCALLS int linux_unlink(struct thread *td, struct linux_unlink_args *args) { char *path; int error; struct stat st; if (!LUSECONVPATH(td)) { error = kern_funlinkat(td, AT_FDCWD, args->path, FD_NONE, UIO_USERSPACE, 0, 0); if (error == EPERM) { /* Introduce POSIX noncompliant behaviour of Linux */ if (kern_statat(td, 0, AT_FDCWD, args->path, UIO_SYSSPACE, &st, NULL) == 0) { if (S_ISDIR(st.st_mode)) error = EISDIR; } } } else { LCONVPATHEXIST(td, args->path, &path); error = kern_funlinkat(td, AT_FDCWD, path, FD_NONE, UIO_SYSSPACE, 0, 0); if (error == EPERM) { /* Introduce POSIX noncompliant behaviour of Linux */ if (kern_statat(td, 0, AT_FDCWD, path, UIO_SYSSPACE, &st, NULL) == 0) { if (S_ISDIR(st.st_mode)) error = EISDIR; } } LFREEPATH(path); } return (error); } #endif static int linux_unlinkat_impl(struct thread *td, enum uio_seg pathseg, const char *path, int dfd, struct linux_unlinkat_args *args) { struct stat st; int error; if (args->flag & LINUX_AT_REMOVEDIR) error = kern_frmdirat(td, dfd, path, FD_NONE, pathseg, 0); else error = kern_funlinkat(td, dfd, path, FD_NONE, pathseg, 0, 0); if (error == EPERM && !(args->flag & LINUX_AT_REMOVEDIR)) { /* Introduce POSIX noncompliant behaviour of Linux */ if (kern_statat(td, AT_SYMLINK_NOFOLLOW, dfd, path, UIO_SYSSPACE, &st, NULL) == 0 && S_ISDIR(st.st_mode)) error = EISDIR; } return (error); } int linux_unlinkat(struct thread *td, struct linux_unlinkat_args *args) { char *path; int error, dfd; if (args->flag & ~LINUX_AT_REMOVEDIR) return (EINVAL); dfd = (args->dfd == LINUX_AT_FDCWD) ? AT_FDCWD : args->dfd; if (!LUSECONVPATH(td)) { return (linux_unlinkat_impl(td, UIO_USERSPACE, args->pathname, dfd, args)); } LCONVPATHEXIST_AT(td, args->pathname, &path, dfd); error = linux_unlinkat_impl(td, UIO_SYSSPACE, path, dfd, args); LFREEPATH(path); return (error); } int linux_chdir(struct thread *td, struct linux_chdir_args *args) { char *path; int error; if (!LUSECONVPATH(td)) { return (kern_chdir(td, args->path, UIO_USERSPACE)); } LCONVPATHEXIST(td, args->path, &path); error = kern_chdir(td, path, UIO_SYSSPACE); LFREEPATH(path); return (error); } #ifdef LINUX_LEGACY_SYSCALLS int linux_chmod(struct thread *td, struct linux_chmod_args *args) { char *path; int error; if (!LUSECONVPATH(td)) { return (kern_fchmodat(td, AT_FDCWD, args->path, UIO_USERSPACE, args->mode, 0)); } LCONVPATHEXIST(td, args->path, &path); error = kern_fchmodat(td, AT_FDCWD, path, UIO_SYSSPACE, args->mode, 0); LFREEPATH(path); return (error); } #endif int linux_fchmodat(struct thread *td, struct linux_fchmodat_args *args) { char *path; int error, dfd; dfd = (args->dfd == LINUX_AT_FDCWD) ? AT_FDCWD : args->dfd; if (!LUSECONVPATH(td)) { return (kern_fchmodat(td, dfd, args->filename, UIO_USERSPACE, args->mode, 0)); } LCONVPATHEXIST_AT(td, args->filename, &path, dfd); error = kern_fchmodat(td, dfd, path, UIO_SYSSPACE, args->mode, 0); LFREEPATH(path); return (error); } #ifdef LINUX_LEGACY_SYSCALLS int linux_mkdir(struct thread *td, struct linux_mkdir_args *args) { char *path; int error; if (!LUSECONVPATH(td)) { return (kern_mkdirat(td, AT_FDCWD, args->path, UIO_USERSPACE, args->mode)); } LCONVPATHCREAT(td, args->path, &path); error = kern_mkdirat(td, AT_FDCWD, path, UIO_SYSSPACE, args->mode); LFREEPATH(path); return (error); } #endif int linux_mkdirat(struct thread *td, struct linux_mkdirat_args *args) { char *path; int error, dfd; dfd = (args->dfd == LINUX_AT_FDCWD) ? AT_FDCWD : args->dfd; if (!LUSECONVPATH(td)) { return (kern_mkdirat(td, dfd, args->pathname, UIO_USERSPACE, args->mode)); } LCONVPATHCREAT_AT(td, args->pathname, &path, dfd); error = kern_mkdirat(td, dfd, path, UIO_SYSSPACE, args->mode); LFREEPATH(path); return (error); } #ifdef LINUX_LEGACY_SYSCALLS int linux_rmdir(struct thread *td, struct linux_rmdir_args *args) { char *path; int error; if (!LUSECONVPATH(td)) { return (kern_frmdirat(td, AT_FDCWD, args->path, FD_NONE, UIO_USERSPACE, 0)); } LCONVPATHEXIST(td, args->path, &path); error = kern_frmdirat(td, AT_FDCWD, path, FD_NONE, UIO_SYSSPACE, 0); LFREEPATH(path); return (error); } int linux_rename(struct thread *td, struct linux_rename_args *args) { char *from, *to; int error; if (!LUSECONVPATH(td)) { return (kern_renameat(td, AT_FDCWD, args->from, AT_FDCWD, args->to, UIO_USERSPACE)); } LCONVPATHEXIST(td, args->from, &from); /* Expand LCONVPATHCREATE so that `from' can be freed on errors */ error = linux_emul_convpath(td, args->to, UIO_USERSPACE, &to, 1, AT_FDCWD); if (to == NULL) { LFREEPATH(from); return (error); } error = kern_renameat(td, AT_FDCWD, from, AT_FDCWD, to, UIO_SYSSPACE); LFREEPATH(from); LFREEPATH(to); return (error); } #endif int linux_renameat(struct thread *td, struct linux_renameat_args *args) { struct linux_renameat2_args renameat2_args = { .olddfd = args->olddfd, .oldname = args->oldname, .newdfd = args->newdfd, .newname = args->newname, .flags = 0 }; return (linux_renameat2(td, &renameat2_args)); } int linux_renameat2(struct thread *td, struct linux_renameat2_args *args) { char *from, *to; int error, olddfd, newdfd; if (args->flags != 0) { if (args->flags & ~(LINUX_RENAME_EXCHANGE | LINUX_RENAME_NOREPLACE | LINUX_RENAME_WHITEOUT)) return (EINVAL); if (args->flags & LINUX_RENAME_EXCHANGE && args->flags & (LINUX_RENAME_NOREPLACE | LINUX_RENAME_WHITEOUT)) return (EINVAL); #if 0 /* * This spams the console on Ubuntu Focal. * * What's needed here is a general mechanism to let users know * about missing features without hogging the system. */ linux_msg(td, "renameat2 unsupported flags 0x%x", args->flags); #endif return (EINVAL); } olddfd = (args->olddfd == LINUX_AT_FDCWD) ? AT_FDCWD : args->olddfd; newdfd = (args->newdfd == LINUX_AT_FDCWD) ? AT_FDCWD : args->newdfd; if (!LUSECONVPATH(td)) { return (kern_renameat(td, olddfd, args->oldname, newdfd, args->newname, UIO_USERSPACE)); } LCONVPATHEXIST_AT(td, args->oldname, &from, olddfd); /* Expand LCONVPATHCREATE so that `from' can be freed on errors */ error = linux_emul_convpath(td, args->newname, UIO_USERSPACE, &to, 1, newdfd); if (to == NULL) { LFREEPATH(from); return (error); } error = kern_renameat(td, olddfd, from, newdfd, to, UIO_SYSSPACE); LFREEPATH(from); LFREEPATH(to); return (error); } #ifdef LINUX_LEGACY_SYSCALLS int linux_symlink(struct thread *td, struct linux_symlink_args *args) { char *path, *to; int error; if (!LUSECONVPATH(td)) { return (kern_symlinkat(td, args->path, AT_FDCWD, args->to, UIO_USERSPACE)); } LCONVPATHEXIST(td, args->path, &path); /* Expand LCONVPATHCREATE so that `path' can be freed on errors */ error = linux_emul_convpath(td, args->to, UIO_USERSPACE, &to, 1, AT_FDCWD); if (to == NULL) { LFREEPATH(path); return (error); } error = kern_symlinkat(td, path, AT_FDCWD, to, UIO_SYSSPACE); LFREEPATH(path); LFREEPATH(to); return (error); } #endif int linux_symlinkat(struct thread *td, struct linux_symlinkat_args *args) { char *path, *to; int error, dfd; dfd = (args->newdfd == LINUX_AT_FDCWD) ? AT_FDCWD : args->newdfd; if (!LUSECONVPATH(td)) { return (kern_symlinkat(td, args->oldname, dfd, args->newname, UIO_USERSPACE)); } LCONVPATHEXIST(td, args->oldname, &path); /* Expand LCONVPATHCREATE so that `path' can be freed on errors */ error = linux_emul_convpath(td, args->newname, UIO_USERSPACE, &to, 1, dfd); if (to == NULL) { LFREEPATH(path); return (error); } error = kern_symlinkat(td, path, dfd, to, UIO_SYSSPACE); LFREEPATH(path); LFREEPATH(to); return (error); } #ifdef LINUX_LEGACY_SYSCALLS int linux_readlink(struct thread *td, struct linux_readlink_args *args) { char *name; int error; if (!LUSECONVPATH(td)) { return (kern_readlinkat(td, AT_FDCWD, args->name, UIO_USERSPACE, args->buf, UIO_USERSPACE, args->count)); } LCONVPATHEXIST(td, args->name, &name); error = kern_readlinkat(td, AT_FDCWD, name, UIO_SYSSPACE, args->buf, UIO_USERSPACE, args->count); LFREEPATH(name); return (error); } #endif int linux_readlinkat(struct thread *td, struct linux_readlinkat_args *args) { char *name; int error, dfd; dfd = (args->dfd == LINUX_AT_FDCWD) ? AT_FDCWD : args->dfd; if (!LUSECONVPATH(td)) { return (kern_readlinkat(td, dfd, args->path, UIO_USERSPACE, args->buf, UIO_USERSPACE, args->bufsiz)); } LCONVPATHEXIST_AT(td, args->path, &name, dfd); error = kern_readlinkat(td, dfd, name, UIO_SYSSPACE, args->buf, UIO_USERSPACE, args->bufsiz); LFREEPATH(name); return (error); } int linux_truncate(struct thread *td, struct linux_truncate_args *args) { char *path; int error; if (!LUSECONVPATH(td)) { return (kern_truncate(td, args->path, UIO_USERSPACE, args->length)); } LCONVPATHEXIST(td, args->path, &path); error = kern_truncate(td, path, UIO_SYSSPACE, args->length); LFREEPATH(path); return (error); } #if defined(__i386__) || (defined(__amd64__) && defined(COMPAT_LINUX32)) int linux_truncate64(struct thread *td, struct linux_truncate64_args *args) { char *path; off_t length; int error; #if defined(__amd64__) && defined(COMPAT_LINUX32) length = PAIR32TO64(off_t, args->length); #else length = args->length; #endif if (!LUSECONVPATH(td)) { return (kern_truncate(td, args->path, UIO_USERSPACE, length)); } LCONVPATHEXIST(td, args->path, &path); error = kern_truncate(td, path, UIO_SYSSPACE, length); LFREEPATH(path); return (error); } #endif /* __i386__ || (__amd64__ && COMPAT_LINUX32) */ int linux_ftruncate(struct thread *td, struct linux_ftruncate_args *args) { return (kern_ftruncate(td, args->fd, args->length)); } #if defined(__i386__) || (defined(__amd64__) && defined(COMPAT_LINUX32)) int linux_ftruncate64(struct thread *td, struct linux_ftruncate64_args *args) { off_t length; #if defined(__amd64__) && defined(COMPAT_LINUX32) length = PAIR32TO64(off_t, args->length); #else length = args->length; #endif return (kern_ftruncate(td, args->fd, length)); } #endif #ifdef LINUX_LEGACY_SYSCALLS int linux_link(struct thread *td, struct linux_link_args *args) { char *path, *to; int error; if (!LUSECONVPATH(td)) { return (kern_linkat(td, AT_FDCWD, AT_FDCWD, args->path, args->to, UIO_USERSPACE, FOLLOW)); } LCONVPATHEXIST(td, args->path, &path); /* Expand LCONVPATHCREATE so that `path' can be freed on errors */ error = linux_emul_convpath(td, args->to, UIO_USERSPACE, &to, 1, AT_FDCWD); if (to == NULL) { LFREEPATH(path); return (error); } error = kern_linkat(td, AT_FDCWD, AT_FDCWD, path, to, UIO_SYSSPACE, FOLLOW); LFREEPATH(path); LFREEPATH(to); return (error); } #endif int linux_linkat(struct thread *td, struct linux_linkat_args *args) { char *path, *to; int error, olddfd, newdfd, follow; if (args->flag & ~LINUX_AT_SYMLINK_FOLLOW) return (EINVAL); olddfd = (args->olddfd == LINUX_AT_FDCWD) ? AT_FDCWD : args->olddfd; newdfd = (args->newdfd == LINUX_AT_FDCWD) ? AT_FDCWD : args->newdfd; follow = (args->flag & LINUX_AT_SYMLINK_FOLLOW) == 0 ? NOFOLLOW : FOLLOW; if (!LUSECONVPATH(td)) { return (kern_linkat(td, olddfd, newdfd, args->oldname, args->newname, UIO_USERSPACE, follow)); } LCONVPATHEXIST_AT(td, args->oldname, &path, olddfd); /* Expand LCONVPATHCREATE so that `path' can be freed on errors */ error = linux_emul_convpath(td, args->newname, UIO_USERSPACE, &to, 1, newdfd); if (to == NULL) { LFREEPATH(path); return (error); } error = kern_linkat(td, olddfd, newdfd, path, to, UIO_SYSSPACE, follow); LFREEPATH(path); LFREEPATH(to); return (error); } int linux_fdatasync(struct thread *td, struct linux_fdatasync_args *uap) { return (kern_fsync(td, uap->fd, false)); } int linux_sync_file_range(struct thread *td, struct linux_sync_file_range_args *uap) { off_t nbytes, offset; #if defined(__amd64__) && defined(COMPAT_LINUX32) nbytes = PAIR32TO64(off_t, uap->nbytes); offset = PAIR32TO64(off_t, uap->offset); #else nbytes = uap->nbytes; offset = uap->offset; #endif if (offset < 0 || nbytes < 0 || (uap->flags & ~(LINUX_SYNC_FILE_RANGE_WAIT_BEFORE | LINUX_SYNC_FILE_RANGE_WRITE | LINUX_SYNC_FILE_RANGE_WAIT_AFTER)) != 0) { return (EINVAL); } return (kern_fsync(td, uap->fd, false)); } int linux_pread(struct thread *td, struct linux_pread_args *uap) { struct vnode *vp; off_t offset; int error; #if defined(__amd64__) && defined(COMPAT_LINUX32) offset = PAIR32TO64(off_t, uap->offset); #else offset = uap->offset; #endif error = kern_pread(td, uap->fd, uap->buf, uap->nbyte, offset); if (error == 0) { /* This seems to violate POSIX but Linux does it. */ error = fgetvp(td, uap->fd, &cap_pread_rights, &vp); if (error != 0) return (error); if (vp->v_type == VDIR) error = EISDIR; vrele(vp); } return (error); } int linux_pwrite(struct thread *td, struct linux_pwrite_args *uap) { off_t offset; #if defined(__amd64__) && defined(COMPAT_LINUX32) offset = PAIR32TO64(off_t, uap->offset); #else offset = uap->offset; #endif return (kern_pwrite(td, uap->fd, uap->buf, uap->nbyte, offset)); } int linux_preadv(struct thread *td, struct linux_preadv_args *uap) { struct uio *auio; int error; off_t offset; /* * According http://man7.org/linux/man-pages/man2/preadv.2.html#NOTES * pos_l and pos_h, respectively, contain the * low order and high order 32 bits of offset. */ offset = (((off_t)uap->pos_h << (sizeof(offset) * 4)) << (sizeof(offset) * 4)) | uap->pos_l; if (offset < 0) return (EINVAL); #ifdef COMPAT_LINUX32 error = linux32_copyinuio(PTRIN(uap->vec), uap->vlen, &auio); #else error = copyinuio(uap->vec, uap->vlen, &auio); #endif if (error != 0) return (error); error = kern_preadv(td, uap->fd, auio, offset); free(auio, M_IOV); return (error); } int linux_pwritev(struct thread *td, struct linux_pwritev_args *uap) { struct uio *auio; int error; off_t offset; /* * According http://man7.org/linux/man-pages/man2/pwritev.2.html#NOTES * pos_l and pos_h, respectively, contain the * low order and high order 32 bits of offset. */ offset = (((off_t)uap->pos_h << (sizeof(offset) * 4)) << (sizeof(offset) * 4)) | uap->pos_l; if (offset < 0) return (EINVAL); #ifdef COMPAT_LINUX32 error = linux32_copyinuio(PTRIN(uap->vec), uap->vlen, &auio); #else error = copyinuio(uap->vec, uap->vlen, &auio); #endif if (error != 0) return (error); error = kern_pwritev(td, uap->fd, auio, offset); free(auio, M_IOV); return (error); } int linux_mount(struct thread *td, struct linux_mount_args *args) { struct mntarg *ma = NULL; char *fstypename, *mntonname, *mntfromname, *data; int error, fsflags; fstypename = malloc(MNAMELEN, M_TEMP, M_WAITOK); mntonname = malloc(MNAMELEN, M_TEMP, M_WAITOK); mntfromname = malloc(MNAMELEN, M_TEMP, M_WAITOK); data = NULL; error = copyinstr(args->filesystemtype, fstypename, MNAMELEN - 1, NULL); if (error != 0) goto out; if (args->specialfile != NULL) { error = copyinstr(args->specialfile, mntfromname, MNAMELEN - 1, NULL); if (error != 0) goto out; } else { mntfromname[0] = '\0'; } error = copyinstr(args->dir, mntonname, MNAMELEN - 1, NULL); if (error != 0) goto out; if (strcmp(fstypename, "ext2") == 0) { strcpy(fstypename, "ext2fs"); } else if (strcmp(fstypename, "proc") == 0) { strcpy(fstypename, "linprocfs"); } else if (strcmp(fstypename, "vfat") == 0) { strcpy(fstypename, "msdosfs"); } else if (strcmp(fstypename, "fuse") == 0) { char *fuse_options, *fuse_option, *fuse_name; if (strcmp(mntfromname, "fuse") == 0) strcpy(mntfromname, "/dev/fuse"); strcpy(fstypename, "fusefs"); data = malloc(MNAMELEN, M_TEMP, M_WAITOK); error = copyinstr(args->data, data, MNAMELEN - 1, NULL); if (error != 0) goto out; fuse_options = data; while ((fuse_option = strsep(&fuse_options, ",")) != NULL) { fuse_name = strsep(&fuse_option, "="); if (fuse_name == NULL || fuse_option == NULL) goto out; ma = mount_arg(ma, fuse_name, fuse_option, -1); } /* * The FUSE server uses Linux errno values instead of FreeBSD * ones; add a flag to tell fuse(4) to do errno translation. */ ma = mount_arg(ma, "linux_errnos", "1", -1); } fsflags = 0; /* * Linux SYNC flag is not included; the closest equivalent * FreeBSD has is !ASYNC, which is our default. */ if (args->rwflag & LINUX_MS_RDONLY) fsflags |= MNT_RDONLY; if (args->rwflag & LINUX_MS_NOSUID) fsflags |= MNT_NOSUID; if (args->rwflag & LINUX_MS_NOEXEC) fsflags |= MNT_NOEXEC; if (args->rwflag & LINUX_MS_REMOUNT) fsflags |= MNT_UPDATE; ma = mount_arg(ma, "fstype", fstypename, -1); ma = mount_arg(ma, "fspath", mntonname, -1); ma = mount_arg(ma, "from", mntfromname, -1); error = kernel_mount(ma, fsflags); out: free(fstypename, M_TEMP); free(mntonname, M_TEMP); free(mntfromname, M_TEMP); free(data, M_TEMP); return (error); } #if defined(__i386__) || (defined(__amd64__) && defined(COMPAT_LINUX32)) int linux_oldumount(struct thread *td, struct linux_oldumount_args *args) { return (kern_unmount(td, args->path, 0)); } #endif /* __i386__ || (__amd64__ && COMPAT_LINUX32) */ #ifdef LINUX_LEGACY_SYSCALLS int linux_umount(struct thread *td, struct linux_umount_args *args) { int flags; flags = 0; if ((args->flags & LINUX_MNT_FORCE) != 0) { args->flags &= ~LINUX_MNT_FORCE; flags |= MNT_FORCE; } if (args->flags != 0) { linux_msg(td, "unsupported umount2 flags %#x", args->flags); return (EINVAL); } return (kern_unmount(td, args->path, flags)); } #endif /* * fcntl family of syscalls */ struct l_flock { l_short l_type; l_short l_whence; l_off_t l_start; l_off_t l_len; l_pid_t l_pid; } #if defined(__amd64__) && defined(COMPAT_LINUX32) __packed #endif ; static void linux_to_bsd_flock(struct l_flock *linux_flock, struct flock *bsd_flock) { switch (linux_flock->l_type) { case LINUX_F_RDLCK: bsd_flock->l_type = F_RDLCK; break; case LINUX_F_WRLCK: bsd_flock->l_type = F_WRLCK; break; case LINUX_F_UNLCK: bsd_flock->l_type = F_UNLCK; break; default: bsd_flock->l_type = -1; break; } bsd_flock->l_whence = linux_flock->l_whence; bsd_flock->l_start = (off_t)linux_flock->l_start; bsd_flock->l_len = (off_t)linux_flock->l_len; bsd_flock->l_pid = (pid_t)linux_flock->l_pid; bsd_flock->l_sysid = 0; } static void bsd_to_linux_flock(struct flock *bsd_flock, struct l_flock *linux_flock) { switch (bsd_flock->l_type) { case F_RDLCK: linux_flock->l_type = LINUX_F_RDLCK; break; case F_WRLCK: linux_flock->l_type = LINUX_F_WRLCK; break; case F_UNLCK: linux_flock->l_type = LINUX_F_UNLCK; break; } linux_flock->l_whence = bsd_flock->l_whence; linux_flock->l_start = (l_off_t)bsd_flock->l_start; linux_flock->l_len = (l_off_t)bsd_flock->l_len; linux_flock->l_pid = (l_pid_t)bsd_flock->l_pid; } #if defined(__i386__) || (defined(__amd64__) && defined(COMPAT_LINUX32)) struct l_flock64 { l_short l_type; l_short l_whence; l_loff_t l_start; l_loff_t l_len; l_pid_t l_pid; } #if defined(__amd64__) && defined(COMPAT_LINUX32) __packed #endif ; static void linux_to_bsd_flock64(struct l_flock64 *linux_flock, struct flock *bsd_flock) { switch (linux_flock->l_type) { case LINUX_F_RDLCK: bsd_flock->l_type = F_RDLCK; break; case LINUX_F_WRLCK: bsd_flock->l_type = F_WRLCK; break; case LINUX_F_UNLCK: bsd_flock->l_type = F_UNLCK; break; default: bsd_flock->l_type = -1; break; } bsd_flock->l_whence = linux_flock->l_whence; bsd_flock->l_start = (off_t)linux_flock->l_start; bsd_flock->l_len = (off_t)linux_flock->l_len; bsd_flock->l_pid = (pid_t)linux_flock->l_pid; bsd_flock->l_sysid = 0; } static void bsd_to_linux_flock64(struct flock *bsd_flock, struct l_flock64 *linux_flock) { switch (bsd_flock->l_type) { case F_RDLCK: linux_flock->l_type = LINUX_F_RDLCK; break; case F_WRLCK: linux_flock->l_type = LINUX_F_WRLCK; break; case F_UNLCK: linux_flock->l_type = LINUX_F_UNLCK; break; } linux_flock->l_whence = bsd_flock->l_whence; linux_flock->l_start = (l_loff_t)bsd_flock->l_start; linux_flock->l_len = (l_loff_t)bsd_flock->l_len; linux_flock->l_pid = (l_pid_t)bsd_flock->l_pid; } #endif /* __i386__ || (__amd64__ && COMPAT_LINUX32) */ static int fcntl_common(struct thread *td, struct linux_fcntl_args *args) { struct l_flock linux_flock; struct flock bsd_flock; struct file *fp; long arg; int error, result; switch (args->cmd) { case LINUX_F_DUPFD: return (kern_fcntl(td, args->fd, F_DUPFD, args->arg)); case LINUX_F_GETFD: return (kern_fcntl(td, args->fd, F_GETFD, 0)); case LINUX_F_SETFD: return (kern_fcntl(td, args->fd, F_SETFD, args->arg)); case LINUX_F_GETFL: error = kern_fcntl(td, args->fd, F_GETFL, 0); result = td->td_retval[0]; td->td_retval[0] = 0; if (result & O_RDONLY) td->td_retval[0] |= LINUX_O_RDONLY; if (result & O_WRONLY) td->td_retval[0] |= LINUX_O_WRONLY; if (result & O_RDWR) td->td_retval[0] |= LINUX_O_RDWR; if (result & O_NDELAY) td->td_retval[0] |= LINUX_O_NONBLOCK; if (result & O_APPEND) td->td_retval[0] |= LINUX_O_APPEND; if (result & O_FSYNC) td->td_retval[0] |= LINUX_O_SYNC; if (result & O_ASYNC) td->td_retval[0] |= LINUX_O_ASYNC; #ifdef LINUX_O_NOFOLLOW if (result & O_NOFOLLOW) td->td_retval[0] |= LINUX_O_NOFOLLOW; #endif #ifdef LINUX_O_DIRECT if (result & O_DIRECT) td->td_retval[0] |= LINUX_O_DIRECT; #endif return (error); case LINUX_F_SETFL: arg = 0; if (args->arg & LINUX_O_NDELAY) arg |= O_NONBLOCK; if (args->arg & LINUX_O_APPEND) arg |= O_APPEND; if (args->arg & LINUX_O_SYNC) arg |= O_FSYNC; if (args->arg & LINUX_O_ASYNC) arg |= O_ASYNC; #ifdef LINUX_O_NOFOLLOW if (args->arg & LINUX_O_NOFOLLOW) arg |= O_NOFOLLOW; #endif #ifdef LINUX_O_DIRECT if (args->arg & LINUX_O_DIRECT) arg |= O_DIRECT; #endif return (kern_fcntl(td, args->fd, F_SETFL, arg)); case LINUX_F_GETLK: error = copyin((void *)args->arg, &linux_flock, sizeof(linux_flock)); if (error) return (error); linux_to_bsd_flock(&linux_flock, &bsd_flock); error = kern_fcntl(td, args->fd, F_GETLK, (intptr_t)&bsd_flock); if (error) return (error); bsd_to_linux_flock(&bsd_flock, &linux_flock); return (copyout(&linux_flock, (void *)args->arg, sizeof(linux_flock))); case LINUX_F_SETLK: error = copyin((void *)args->arg, &linux_flock, sizeof(linux_flock)); if (error) return (error); linux_to_bsd_flock(&linux_flock, &bsd_flock); return (kern_fcntl(td, args->fd, F_SETLK, (intptr_t)&bsd_flock)); case LINUX_F_SETLKW: error = copyin((void *)args->arg, &linux_flock, sizeof(linux_flock)); if (error) return (error); linux_to_bsd_flock(&linux_flock, &bsd_flock); return (kern_fcntl(td, args->fd, F_SETLKW, (intptr_t)&bsd_flock)); case LINUX_F_GETOWN: return (kern_fcntl(td, args->fd, F_GETOWN, 0)); case LINUX_F_SETOWN: /* * XXX some Linux applications depend on F_SETOWN having no * significant effect for pipes (SIGIO is not delivered for * pipes under Linux-2.2.35 at least). */ error = fget(td, args->fd, &cap_fcntl_rights, &fp); if (error) return (error); if (fp->f_type == DTYPE_PIPE) { fdrop(fp, td); return (EINVAL); } fdrop(fp, td); return (kern_fcntl(td, args->fd, F_SETOWN, args->arg)); case LINUX_F_DUPFD_CLOEXEC: return (kern_fcntl(td, args->fd, F_DUPFD_CLOEXEC, args->arg)); /* * Our F_SEAL_* values match Linux one for maximum compatibility. So we * only needed to account for different values for fcntl(2) commands. */ case LINUX_F_GET_SEALS: error = kern_fcntl(td, args->fd, F_GET_SEALS, 0); if (error != 0) return (error); td->td_retval[0] = bsd_to_linux_bits(td->td_retval[0], seal_bitmap, 0); return (0); case LINUX_F_ADD_SEALS: return (kern_fcntl(td, args->fd, F_ADD_SEALS, linux_to_bsd_bits(args->arg, seal_bitmap, 0))); default: linux_msg(td, "unsupported fcntl cmd %d\n", args->cmd); return (EINVAL); } } int linux_fcntl(struct thread *td, struct linux_fcntl_args *args) { return (fcntl_common(td, args)); } #if defined(__i386__) || (defined(__amd64__) && defined(COMPAT_LINUX32)) int linux_fcntl64(struct thread *td, struct linux_fcntl64_args *args) { struct l_flock64 linux_flock; struct flock bsd_flock; struct linux_fcntl_args fcntl_args; int error; switch (args->cmd) { case LINUX_F_GETLK64: error = copyin((void *)args->arg, &linux_flock, sizeof(linux_flock)); if (error) return (error); linux_to_bsd_flock64(&linux_flock, &bsd_flock); error = kern_fcntl(td, args->fd, F_GETLK, (intptr_t)&bsd_flock); if (error) return (error); bsd_to_linux_flock64(&bsd_flock, &linux_flock); return (copyout(&linux_flock, (void *)args->arg, sizeof(linux_flock))); case LINUX_F_SETLK64: error = copyin((void *)args->arg, &linux_flock, sizeof(linux_flock)); if (error) return (error); linux_to_bsd_flock64(&linux_flock, &bsd_flock); return (kern_fcntl(td, args->fd, F_SETLK, (intptr_t)&bsd_flock)); case LINUX_F_SETLKW64: error = copyin((void *)args->arg, &linux_flock, sizeof(linux_flock)); if (error) return (error); linux_to_bsd_flock64(&linux_flock, &bsd_flock); return (kern_fcntl(td, args->fd, F_SETLKW, (intptr_t)&bsd_flock)); } fcntl_args.fd = args->fd; fcntl_args.cmd = args->cmd; fcntl_args.arg = args->arg; return (fcntl_common(td, &fcntl_args)); } #endif /* __i386__ || (__amd64__ && COMPAT_LINUX32) */ #ifdef LINUX_LEGACY_SYSCALLS int linux_chown(struct thread *td, struct linux_chown_args *args) { char *path; int error; if (!LUSECONVPATH(td)) { return (kern_fchownat(td, AT_FDCWD, args->path, UIO_USERSPACE, args->uid, args->gid, 0)); } LCONVPATHEXIST(td, args->path, &path); error = kern_fchownat(td, AT_FDCWD, path, UIO_SYSSPACE, args->uid, args->gid, 0); LFREEPATH(path); return (error); } #endif int linux_fchownat(struct thread *td, struct linux_fchownat_args *args) { char *path; int error, dfd, flag; if (args->flag & ~LINUX_AT_SYMLINK_NOFOLLOW) return (EINVAL); dfd = (args->dfd == LINUX_AT_FDCWD) ? AT_FDCWD : args->dfd; flag = (args->flag & LINUX_AT_SYMLINK_NOFOLLOW) == 0 ? 0 : AT_SYMLINK_NOFOLLOW; if (!LUSECONVPATH(td)) { return (kern_fchownat(td, dfd, args->filename, UIO_USERSPACE, args->uid, args->gid, flag)); } LCONVPATHEXIST_AT(td, args->filename, &path, dfd); error = kern_fchownat(td, dfd, path, UIO_SYSSPACE, args->uid, args->gid, flag); LFREEPATH(path); return (error); } #ifdef LINUX_LEGACY_SYSCALLS int linux_lchown(struct thread *td, struct linux_lchown_args *args) { char *path; int error; if (!LUSECONVPATH(td)) { return (kern_fchownat(td, AT_FDCWD, args->path, UIO_USERSPACE, args->uid, args->gid, AT_SYMLINK_NOFOLLOW)); } LCONVPATHEXIST(td, args->path, &path); error = kern_fchownat(td, AT_FDCWD, path, UIO_SYSSPACE, args->uid, args->gid, AT_SYMLINK_NOFOLLOW); LFREEPATH(path); return (error); } #endif static int convert_fadvice(int advice) { switch (advice) { case LINUX_POSIX_FADV_NORMAL: return (POSIX_FADV_NORMAL); case LINUX_POSIX_FADV_RANDOM: return (POSIX_FADV_RANDOM); case LINUX_POSIX_FADV_SEQUENTIAL: return (POSIX_FADV_SEQUENTIAL); case LINUX_POSIX_FADV_WILLNEED: return (POSIX_FADV_WILLNEED); case LINUX_POSIX_FADV_DONTNEED: return (POSIX_FADV_DONTNEED); case LINUX_POSIX_FADV_NOREUSE: return (POSIX_FADV_NOREUSE); default: return (-1); } } int linux_fadvise64(struct thread *td, struct linux_fadvise64_args *args) { off_t offset; int advice; #if defined(__amd64__) && defined(COMPAT_LINUX32) offset = PAIR32TO64(off_t, args->offset); #else offset = args->offset; #endif advice = convert_fadvice(args->advice); if (advice == -1) return (EINVAL); return (kern_posix_fadvise(td, args->fd, offset, args->len, advice)); } #if defined(__i386__) || (defined(__amd64__) && defined(COMPAT_LINUX32)) int linux_fadvise64_64(struct thread *td, struct linux_fadvise64_64_args *args) { off_t len, offset; int advice; #if defined(__amd64__) && defined(COMPAT_LINUX32) len = PAIR32TO64(off_t, args->len); offset = PAIR32TO64(off_t, args->offset); #else len = args->len; offset = args->offset; #endif advice = convert_fadvice(args->advice); if (advice == -1) return (EINVAL); return (kern_posix_fadvise(td, args->fd, offset, len, advice)); } #endif /* __i386__ || (__amd64__ && COMPAT_LINUX32) */ #ifdef LINUX_LEGACY_SYSCALLS int linux_pipe(struct thread *td, struct linux_pipe_args *args) { int fildes[2]; int error; error = kern_pipe(td, fildes, 0, NULL, NULL); if (error != 0) return (error); error = copyout(fildes, args->pipefds, sizeof(fildes)); if (error != 0) { (void)kern_close(td, fildes[0]); (void)kern_close(td, fildes[1]); } return (error); } #endif int linux_pipe2(struct thread *td, struct linux_pipe2_args *args) { int fildes[2]; int error, flags; if ((args->flags & ~(LINUX_O_NONBLOCK | LINUX_O_CLOEXEC)) != 0) return (EINVAL); flags = 0; if ((args->flags & LINUX_O_NONBLOCK) != 0) flags |= O_NONBLOCK; if ((args->flags & LINUX_O_CLOEXEC) != 0) flags |= O_CLOEXEC; error = kern_pipe(td, fildes, flags, NULL, NULL); if (error != 0) return (error); error = copyout(fildes, args->pipefds, sizeof(fildes)); if (error != 0) { (void)kern_close(td, fildes[0]); (void)kern_close(td, fildes[1]); } return (error); } int linux_dup3(struct thread *td, struct linux_dup3_args *args) { int cmd; intptr_t newfd; if (args->oldfd == args->newfd) return (EINVAL); if ((args->flags & ~LINUX_O_CLOEXEC) != 0) return (EINVAL); if (args->flags & LINUX_O_CLOEXEC) cmd = F_DUP2FD_CLOEXEC; else cmd = F_DUP2FD; newfd = args->newfd; return (kern_fcntl(td, args->oldfd, cmd, newfd)); } int linux_fallocate(struct thread *td, struct linux_fallocate_args *args) { off_t len, offset; /* * We emulate only posix_fallocate system call for which * mode should be 0. */ if (args->mode != 0) return (EOPNOTSUPP); #if defined(__amd64__) && defined(COMPAT_LINUX32) len = PAIR32TO64(off_t, args->len); offset = PAIR32TO64(off_t, args->offset); #else len = args->len; offset = args->offset; #endif return (kern_posix_fallocate(td, args->fd, offset, len)); } int linux_copy_file_range(struct thread *td, struct linux_copy_file_range_args *args) { l_loff_t inoff, outoff, *inoffp, *outoffp; int error, flags; /* * copy_file_range(2) on Linux doesn't define any flags (yet), so is * the native implementation. Enforce it. */ if (args->flags != 0) { linux_msg(td, "copy_file_range unsupported flags 0x%x", args->flags); return (EINVAL); } flags = 0; inoffp = outoffp = NULL; if (args->off_in != NULL) { error = copyin(args->off_in, &inoff, sizeof(l_loff_t)); if (error != 0) return (error); inoffp = &inoff; } if (args->off_out != NULL) { error = copyin(args->off_out, &outoff, sizeof(l_loff_t)); if (error != 0) return (error); outoffp = &outoff; } error = kern_copy_file_range(td, args->fd_in, inoffp, args->fd_out, outoffp, args->len, flags); if (error == 0 && args->off_in != NULL) error = copyout(inoffp, args->off_in, sizeof(l_loff_t)); if (error == 0 && args->off_out != NULL) error = copyout(outoffp, args->off_out, sizeof(l_loff_t)); return (error); } #define LINUX_MEMFD_PREFIX "memfd:" int linux_memfd_create(struct thread *td, struct linux_memfd_create_args *args) { char memfd_name[LINUX_NAME_MAX + 1]; int error, flags, shmflags, oflags; /* * This is our clever trick to avoid the heap allocation to copy in the * uname. We don't really need to go this far out of our way, but it * does keep the rest of this function fairly clean as they don't have * to worry about cleanup on the way out. */ error = copyinstr(args->uname_ptr, memfd_name + sizeof(LINUX_MEMFD_PREFIX) - 1, LINUX_NAME_MAX - sizeof(LINUX_MEMFD_PREFIX) - 1, NULL); if (error != 0) { if (error == ENAMETOOLONG) error = EINVAL; return (error); } memcpy(memfd_name, LINUX_MEMFD_PREFIX, sizeof(LINUX_MEMFD_PREFIX) - 1); flags = linux_to_bsd_bits(args->flags, mfd_bitmap, 0); if ((flags & ~(MFD_CLOEXEC | MFD_ALLOW_SEALING | MFD_HUGETLB | MFD_HUGE_MASK)) != 0) return (EINVAL); /* Size specified but no HUGETLB. */ if ((flags & MFD_HUGE_MASK) != 0 && (flags & MFD_HUGETLB) == 0) return (EINVAL); /* We don't actually support HUGETLB. */ if ((flags & MFD_HUGETLB) != 0) return (ENOSYS); oflags = O_RDWR; shmflags = SHM_GROW_ON_WRITE; if ((flags & MFD_CLOEXEC) != 0) oflags |= O_CLOEXEC; if ((flags & MFD_ALLOW_SEALING) != 0) shmflags |= SHM_ALLOW_SEALING; return (kern_shm_open2(td, SHM_ANON, oflags, 0, shmflags, NULL, memfd_name)); } int linux_splice(struct thread *td, struct linux_splice_args *args) { linux_msg(td, "syscall splice not really implemented"); /* * splice(2) is documented to return EINVAL in various circumstances; * returning it instead of ENOSYS should hint the caller to use fallback * instead. */ return (EINVAL); } Index: head/sys/compat/linux/linux_file.h =================================================================== --- head/sys/compat/linux/linux_file.h (revision 367772) +++ head/sys/compat/linux/linux_file.h (revision 367773) @@ -1,177 +1,184 @@ /*- * SPDX-License-Identifier: BSD-2-Clause-FreeBSD * * Copyright (c) 2007 Roman Divacky * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * * $FreeBSD$ */ #ifndef _LINUX_FILE_H_ #define _LINUX_FILE_H_ #define LINUX_AT_FDCWD -100 #define LINUX_AT_SYMLINK_NOFOLLOW 0x100 #define LINUX_AT_EACCESS 0x200 #define LINUX_AT_REMOVEDIR 0x200 #define LINUX_AT_SYMLINK_FOLLOW 0x400 +#define LINUX_AT_EMPTY_PATH 0x1000 /* * posix_fadvise advice */ #define LINUX_POSIX_FADV_NORMAL 0 #define LINUX_POSIX_FADV_RANDOM 1 #define LINUX_POSIX_FADV_SEQUENTIAL 2 #define LINUX_POSIX_FADV_WILLNEED 3 #define LINUX_POSIX_FADV_DONTNEED 4 #define LINUX_POSIX_FADV_NOREUSE 5 /* * mount flags */ #define LINUX_MS_RDONLY 0x0001 #define LINUX_MS_NOSUID 0x0002 #define LINUX_MS_NODEV 0x0004 #define LINUX_MS_NOEXEC 0x0008 #define LINUX_MS_REMOUNT 0x0020 /* * umount2 flags */ #define LINUX_MNT_FORCE 0x0001 /* * common open/fcntl flags */ #define LINUX_O_RDONLY 00000000 #define LINUX_O_WRONLY 00000001 #define LINUX_O_RDWR 00000002 #define LINUX_O_ACCMODE 00000003 #define LINUX_O_CREAT 00000100 #define LINUX_O_EXCL 00000200 #define LINUX_O_NOCTTY 00000400 #define LINUX_O_TRUNC 00001000 #define LINUX_O_APPEND 00002000 #define LINUX_O_NONBLOCK 00004000 #define LINUX_O_NDELAY LINUX_O_NONBLOCK #define LINUX_O_SYNC 00010000 #define LINUX_O_ASYNC 00020000 #define LINUX_O_DIRECT 00040000 /* Direct disk access hint */ #define LINUX_O_LARGEFILE 00100000 #define LINUX_O_DIRECTORY 00200000 /* Must be a directory */ #define LINUX_O_NOFOLLOW 00400000 /* Do not follow links */ #define LINUX_O_NOATIME 01000000 #define LINUX_O_CLOEXEC 02000000 #define LINUX_F_DUPFD 0 #define LINUX_F_GETFD 1 #define LINUX_F_SETFD 2 #define LINUX_F_GETFL 3 #define LINUX_F_SETFL 4 #ifndef LINUX_F_GETLK #define LINUX_F_GETLK 5 #define LINUX_F_SETLK 6 #define LINUX_F_SETLKW 7 #endif #ifndef LINUX_F_SETOWN #define LINUX_F_SETOWN 8 #define LINUX_F_GETOWN 9 #endif #ifndef LINUX_F_SETSIG #define LINUX_F_SETSIG 10 #define LINUX_F_GETSIG 11 #endif #ifndef LINUX_F_SETOWN_EX #define LINUX_F_SETOWN_EX 15 #define LINUX_F_GETOWN_EX 16 #define LINUX_F_GETOWNER_UIDS 17 #endif #define LINUX_F_SPECIFIC_BASE 1024 #define LINUX_F_SETLEASE (LINUX_F_SPECIFIC_BASE + 0) #define LINUX_F_GETLEASE (LINUX_F_SPECIFIC_BASE + 1) #define LINUX_F_CANCELLK (LINUX_F_SPECIFIC_BASE + 5) #define LINUX_F_DUPFD_CLOEXEC (LINUX_F_SPECIFIC_BASE + 6) #define LINUX_F_NOTIFY (LINUX_F_SPECIFIC_BASE + 2) #define LINUX_F_SETPIPE_SZ (LINUX_F_SPECIFIC_BASE + 7) #define LINUX_F_GETPIPE_SZ (LINUX_F_SPECIFIC_BASE + 8) #define LINUX_F_ADD_SEALS (LINUX_F_SPECIFIC_BASE + 9) #define LINUX_F_GET_SEALS (LINUX_F_SPECIFIC_BASE + 10) #define LINUX_F_GETLKP 36 #define LINUX_F_SETLKP 37 #define LINUX_F_SETLKPW 38 #define LINUX_F_OWNER_TID 0 #define LINUX_F_OWNER_PID 1 #define LINUX_F_OWNER_PGRP 2 #ifndef LINUX_F_RDLCK #define LINUX_F_RDLCK 0 #define LINUX_F_WRLCK 1 #define LINUX_F_UNLCK 2 #endif /* * renameat2 flags */ #define LINUX_RENAME_NOREPLACE 0x00000001 #define LINUX_RENAME_EXCHANGE 0x00000002 #define LINUX_RENAME_WHITEOUT 0x00000004 /* * sync_file_range flags */ #define LINUX_SYNC_FILE_RANGE_WAIT_BEFORE 1 #define LINUX_SYNC_FILE_RANGE_WRITE 2 #define LINUX_SYNC_FILE_RANGE_WAIT_AFTER 4 #define LINUX_F_SEAL_SEAL 0x0001 #define LINUX_F_SEAL_SHRINK 0x0002 #define LINUX_F_SEAL_GROW 0x0004 #define LINUX_F_SEAL_WRITE 0x0008 #define LINUX_MFD_CLOEXEC 0x0001 #define LINUX_MFD_ALLOW_SEALING 0x0002 #define LINUX_MFD_HUGETLB 0x0004 #define LINUX_HUGETLB_FLAG_ENCODE_SHIFT 26 #define LINUX_HUGETLB_FLAG_ENCODE_MASK 0x3f #define LINUX_HUGETLB_FLAG_ENCODE_64KB (16 << LINUX_HUGETLB_FLAG_ENCODE_SHIFT) #define LINUX_HUGETLB_FLAG_ENCODE_512KB (19 << LINUX_HUGETLB_FLAG_ENCODE_SHIFT) #define LINUX_HUGETLB_FLAG_ENCODE_1MB (20 << LINUX_HUGETLB_FLAG_ENCODE_SHIFT) #define LINUX_HUGETLB_FLAG_ENCODE_2MB (21 << LINUX_HUGETLB_FLAG_ENCODE_SHIFT) #define LINUX_HUGETLB_FLAG_ENCODE_8MB (23 << LINUX_HUGETLB_FLAG_ENCODE_SHIFT) #define LINUX_HUGETLB_FLAG_ENCODE_16MB (24 << LINUX_HUGETLB_FLAG_ENCODE_SHIFT) #define LINUX_HUGETLB_FLAG_ENCODE_32MB (25 << LINUX_HUGETLB_FLAG_ENCODE_SHIFT) #define LINUX_HUGETLB_FLAG_ENCODE_256MB (28 << LINUX_HUGETLB_FLAG_ENCODE_SHIFT) #define LINUX_HUGETLB_FLAG_ENCODE_512MB (29 << LINUX_HUGETLB_FLAG_ENCODE_SHIFT) #define LINUX_HUGETLB_FLAG_ENCODE_1GB (30 << LINUX_HUGETLB_FLAG_ENCODE_SHIFT) #define LINUX_HUGETLB_FLAG_ENCODE_2GB (31 << LINUX_HUGETLB_FLAG_ENCODE_SHIFT) #define LINUX_HUGETLB_FLAG_ENCODE_16GB (34U << LINUX_HUGETLB_FLAG_ENCODE_SHIFT) + +struct l_file_handle { + l_uint handle_bytes; + l_int handle_type; + unsigned char f_handle[0]; +}; #endif /* !_LINUX_FILE_H_ */ Index: head/sys/i386/linux/syscalls.master =================================================================== --- head/sys/i386/linux/syscalls.master (revision 367772) +++ head/sys/i386/linux/syscalls.master (revision 367773) @@ -1,2431 +1,2441 @@ $FreeBSD$ ; @(#)syscalls.master 8.1 (Berkeley) 7/19/93 ; System call name/number master file (or rather, slave, from LINUX). ; Processed to create linux_sysent.c, linux_proto.h and linux_syscall.h. ; Columns: number audit type nargs name alt{name,tag,rtyp}/comments ; number system call number, must be in order ; audit the audit event associated with the system call ; A value of AUE_NULL means no auditing, but it also means that ; there is no audit event for the call at this time. For the ; case where the event exists, but we don't want auditing, the ; event should be #defined to AUE_NULL in audit_kevents.h. ; type one of STD, NOPROTO, UNIMPL ; name pseudo-prototype of syscall routine ; If one of the following alts is different, then all appear: ; altname name of system call if different ; alttag name of args struct tag if different from [o]`name'"_args" ; altrtyp return type if not int (bogus - syscalls always return int) ; for UNIMPL, name continues with comments ; types: ; STD always included ; UNIMPL not implemented, placeholder only ; NOPROTO same as STD except do not create structure or ; function prototype in sys/sysproto.h. Does add a ; definition to syscall.h besides adding a sysent. #include #include #include #include #include #include ; Isn't pretty, but there seems to be no other way to trap nosys #define nosys linux_nosys ; #ifdef's, etc. may be included, and are copied to the output files. 0 AUE_NULL UNIMPL setup 1 AUE_EXIT STD { void linux_exit( int rval ); } 2 AUE_FORK STD { int linux_fork(void); } 3 AUE_NULL NOPROTO { int read( int fd, char *buf, u_int nbyte ); } 4 AUE_NULL NOPROTO { int write( int fd, char *buf, u_int nbyte ); } 5 AUE_OPEN_RWTC STD { int linux_open( char *path, l_int flags, l_int mode ); } 6 AUE_CLOSE NOPROTO { int close( int fd ); } 7 AUE_WAIT4 STD { int linux_waitpid( l_pid_t pid, l_int *status, l_int options ); } 8 AUE_CREAT STD { int linux_creat( char *path, l_int mode ); } 9 AUE_LINK STD { int linux_link( char *path, char *to ); } 10 AUE_UNLINK STD { int linux_unlink( char *path ); } 11 AUE_EXECVE STD { int linux_execve( char *path, char **argp, char **envp ); } 12 AUE_CHDIR STD { int linux_chdir( char *path ); } 13 AUE_NULL STD { int linux_time( l_time_t *tm ); } 14 AUE_MKNOD STD { int linux_mknod( char *path, l_int mode, l_dev_t dev ); } 15 AUE_CHMOD STD { int linux_chmod( char *path, l_mode_t mode ); } 16 AUE_LCHOWN STD { int linux_lchown16( char *path, l_uid16_t uid, l_gid16_t gid ); } 17 AUE_NULL UNIMPL break 18 AUE_STAT STD { int linux_stat( char *path, struct linux_stat *up ); } 19 AUE_LSEEK STD { int linux_lseek( l_uint fdes, l_off_t off, l_int whence ); } 20 AUE_GETPID STD { int linux_getpid(void); } 21 AUE_MOUNT STD { int linux_mount( char *specialfile, char *dir, char *filesystemtype, l_ulong rwflag, void *data ); } 22 AUE_UMOUNT STD { int linux_oldumount( char *path ); } 23 AUE_SETUID STD { int linux_setuid16( l_uid16_t uid ); } 24 AUE_GETUID STD { int linux_getuid16(void); } 25 AUE_SETTIMEOFDAY STD { int linux_stime(void); } 26 AUE_PTRACE STD { int linux_ptrace( l_long req, l_long pid, l_long addr, l_long data ); } 27 AUE_NULL STD { int linux_alarm( l_uint secs ); } 28 AUE_FSTAT STD { int linux_fstat( l_uint fd, struct linux_stat *up ); } 29 AUE_NULL STD { int linux_pause(void); } 30 AUE_UTIME STD { int linux_utime( char *fname, struct l_utimbuf *times ); } 31 AUE_NULL UNIMPL stty 32 AUE_NULL UNIMPL gtty 33 AUE_ACCESS STD { int linux_access( char *path, l_int amode ); } 34 AUE_NICE STD { int linux_nice( l_int inc ); } 35 AUE_NULL UNIMPL ftime 36 AUE_SYNC NOPROTO { int sync(void); } 37 AUE_KILL STD { int linux_kill( l_int pid, l_int signum ); } 38 AUE_RENAME STD { int linux_rename( char *from, char *to ); } 39 AUE_MKDIR STD { int linux_mkdir( char *path, l_int mode ); } 40 AUE_RMDIR STD { int linux_rmdir( char *path ); } 41 AUE_DUP NOPROTO { int dup( u_int fd ); } 42 AUE_PIPE STD { int linux_pipe( l_int *pipefds ); } 43 AUE_NULL STD { int linux_times( struct l_times_argv *buf ); } 44 AUE_NULL UNIMPL prof 45 AUE_NULL STD { int linux_brk( l_ulong dsend ); } 46 AUE_SETGID STD { int linux_setgid16( l_gid16_t gid ); } 47 AUE_GETGID STD { int linux_getgid16(void); } 48 AUE_NULL STD { int linux_signal( l_int sig, void *handler ); } 49 AUE_GETEUID STD { int linux_geteuid16(void); } 50 AUE_GETEGID STD { int linux_getegid16(void); } 51 AUE_ACCT NOPROTO { int acct( char *path ); } 52 AUE_UMOUNT STD { int linux_umount( char *path, l_int flags ); } 53 AUE_NULL UNIMPL lock 54 AUE_IOCTL STD { int linux_ioctl( l_uint fd, l_uint cmd, l_ulong arg ); } 55 AUE_FCNTL STD { int linux_fcntl( l_uint fd, l_uint cmd, l_ulong arg ); } 56 AUE_NULL UNIMPL mpx 57 AUE_SETPGRP NOPROTO { int setpgid( int pid, int pgid ); } 58 AUE_NULL UNIMPL ulimit 59 AUE_NULL STD { int linux_olduname(void); } 60 AUE_UMASK NOPROTO { int umask( int newmask ); } 61 AUE_CHROOT NOPROTO { int chroot( char *path ); } 62 AUE_NULL STD { int linux_ustat( l_dev_t dev, struct l_ustat *ubuf ); } 63 AUE_DUP2 NOPROTO { int dup2( u_int from, u_int to ); } 64 AUE_GETPPID STD { int linux_getppid(void); } 65 AUE_GETPGRP NOPROTO { int getpgrp(void); } 66 AUE_SETSID NOPROTO { int setsid(void); } 67 AUE_NULL STD { int linux_sigaction( l_int sig, l_osigaction_t *nsa, l_osigaction_t *osa ); } 68 AUE_NULL STD { int linux_sgetmask(void); } 69 AUE_NULL STD { int linux_ssetmask( l_osigset_t mask ); } 70 AUE_SETREUID STD { int linux_setreuid16( l_uid16_t ruid, l_uid16_t euid ); } 71 AUE_SETREGID STD { int linux_setregid16( l_gid16_t rgid, l_gid16_t egid ); } 72 AUE_NULL STD { int linux_sigsuspend( l_int hist0, l_int hist1, l_osigset_t mask ); } 73 AUE_NULL STD { int linux_sigpending( l_osigset_t *mask ); } 74 AUE_SYSCTL STD { int linux_sethostname( char *hostname, u_int len ); } 75 AUE_SETRLIMIT STD { int linux_setrlimit( l_uint resource, struct l_rlimit *rlim ); } 76 AUE_GETRLIMIT STD { int linux_old_getrlimit( l_uint resource, struct l_rlimit *rlim ); } 77 AUE_GETRUSAGE NOPROTO { int getrusage( int who, struct rusage *rusage ); } 78 AUE_NULL NOPROTO { int gettimeofday( struct timeval *tp, struct timezone *tzp ); } 79 AUE_SETTIMEOFDAY NOPROTO { int settimeofday( struct timeval *tv, struct timezone *tzp ); } 80 AUE_GETGROUPS STD { int linux_getgroups16( l_uint gidsetsize, l_gid16_t *gidset ); } 81 AUE_SETGROUPS STD { int linux_setgroups16( l_uint gidsetsize, l_gid16_t *gidset ); } 82 AUE_SELECT STD { int linux_old_select( struct l_old_select_argv *ptr ); } 83 AUE_SYMLINK STD { int linux_symlink( char *path, char *to ); } ; 84: oldlstat 84 AUE_LSTAT STD { int linux_lstat( char *path, struct l_stat *up ); } 85 AUE_READLINK STD { int linux_readlink( char *name, char *buf, l_int count ); } 86 AUE_USELIB STD { int linux_uselib( char *library ); } 87 AUE_SWAPON NOPROTO { int swapon( char *name ); } 88 AUE_REBOOT STD { int linux_reboot( l_int magic1, l_int magic2, l_uint cmd, void *arg ); } ; 89: old_readdir 89 AUE_GETDIRENTRIES STD { int linux_readdir( l_uint fd, struct l_dirent *dent, l_uint count ); } ; 90: old_mmap 90 AUE_MMAP STD { int linux_mmap( struct l_mmap_argv *ptr ); } 91 AUE_MUNMAP NOPROTO { int munmap( caddr_t addr, int len ); } 92 AUE_TRUNCATE STD { int linux_truncate( char *path, l_ulong length ); } 93 AUE_FTRUNCATE STD { int linux_ftruncate( int fd, long length ); } 94 AUE_FCHMOD NOPROTO { int fchmod( int fd, int mode ); } 95 AUE_FCHOWN NOPROTO { int fchown( int fd, int uid, int gid ); } 96 AUE_GETPRIORITY STD { int linux_getpriority( int which, int who ); } 97 AUE_SETPRIORITY NOPROTO { int setpriority( int which, int who, int prio ); } 98 AUE_PROFILE UNIMPL profil 99 AUE_STATFS STD { int linux_statfs( char *path, struct l_statfs_buf *buf ); } 100 AUE_FSTATFS STD { int linux_fstatfs( l_uint fd, struct l_statfs_buf *buf ); } 101 AUE_NULL STD { int linux_ioperm( l_ulong start, l_ulong length, l_int enable ); } 102 AUE_NULL STD { int linux_socketcall( l_int what, l_ulong args ); } 103 AUE_NULL STD { int linux_syslog( l_int type, char *buf, l_int len ); } 104 AUE_SETITIMER STD { int linux_setitimer( l_int which, struct l_itimerval *itv, struct l_itimerval *oitv ); } 105 AUE_GETITIMER STD { int linux_getitimer( l_int which, struct l_itimerval *itv ); } 106 AUE_STAT STD { int linux_newstat( char *path, struct l_newstat *buf ); } 107 AUE_LSTAT STD { int linux_newlstat( char *path, struct l_newstat *buf ); } 108 AUE_FSTAT STD { int linux_newfstat( l_uint fd, struct l_newstat *buf ); } ; 109: olduname 109 AUE_NULL STD { int linux_uname(void); } 110 AUE_NULL STD { int linux_iopl( l_int level ); } 111 AUE_NULL STD { int linux_vhangup(void); } 112 AUE_NULL UNIMPL idle 113 AUE_NULL STD { int linux_vm86old(void); } 114 AUE_WAIT4 STD { int linux_wait4( l_pid_t pid, l_int *status, l_int options, void *rusage ); } 115 AUE_SWAPOFF STD { int linux_swapoff(void); } 116 AUE_NULL STD { int linux_sysinfo( struct l_sysinfo *info ); } 117 AUE_NULL STD { int linux_ipc( l_uint what, l_int arg1, l_int arg2, l_uint arg3, l_uintptr_t ptr, l_uint arg5 ); } 118 AUE_FSYNC NOPROTO { int fsync( int fd ); } 119 AUE_SIGRETURN STD { int linux_sigreturn( struct l_sigframe *sfp ); } 120 AUE_RFORK STD { int linux_clone( l_int flags, void *stack, void *parent_tidptr, void *tls, void *child_tidptr ); } 121 AUE_SYSCTL STD { int linux_setdomainname( char *name, int len ); } 122 AUE_NULL STD { int linux_newuname( struct l_new_utsname *buf ); } 123 AUE_NULL STD { int linux_modify_ldt( l_int func, void *ptr, l_ulong bytecount ); } 124 AUE_ADJTIME STD { int linux_adjtimex(void); } 125 AUE_MPROTECT STD { int linux_mprotect( caddr_t addr, int len, int prot ); } 126 AUE_SIGPROCMASK STD { int linux_sigprocmask( l_int how, l_osigset_t *mask, l_osigset_t *omask ); } 127 AUE_NULL UNIMPL create_module 128 AUE_NULL STD { int linux_init_module(void); } 129 AUE_NULL STD { int linux_delete_module(void); } 130 AUE_NULL UNIMPL get_kernel_syms 131 AUE_QUOTACTL STD { int linux_quotactl(void); } 132 AUE_GETPGID NOPROTO { int getpgid( int pid ); } 133 AUE_FCHDIR NOPROTO { int fchdir( int fd ); } 134 AUE_BDFLUSH STD { int linux_bdflush(void); } 135 AUE_NULL STD { int linux_sysfs( l_int option, l_ulong arg1, l_ulong arg2 ); } 136 AUE_PERSONALITY STD { int linux_personality( l_uint per ); } 137 AUE_NULL UNIMPL afs_syscall 138 AUE_SETFSUID STD { int linux_setfsuid16( l_uid16_t uid ); } 139 AUE_SETFSGID STD { int linux_setfsgid16( l_gid16_t gid ); } 140 AUE_LSEEK STD { int linux_llseek( l_int fd, l_ulong ohigh, l_ulong olow, l_loff_t *res, l_uint whence ); } 141 AUE_GETDIRENTRIES STD { int linux_getdents( l_uint fd, void *dent, l_uint count ); } ; 142: newselect 142 AUE_SELECT STD { int linux_select( l_int nfds, l_fd_set *readfds, l_fd_set *writefds, l_fd_set *exceptfds, struct l_timeval *timeout ); } 143 AUE_FLOCK NOPROTO { int flock( int fd, int how ); } 144 AUE_MSYNC STD { int linux_msync( l_ulong addr, l_size_t len, l_int fl ); } 145 AUE_READV NOPROTO { int readv( int fd, struct iovec *iovp, u_int iovcnt ); } 146 AUE_WRITEV NOPROTO { int writev( int fd, struct iovec *iovp, u_int iovcnt ); } 147 AUE_GETSID STD { int linux_getsid( l_pid_t pid ); } 148 AUE_NULL STD { int linux_fdatasync( l_uint fd ); } 149 AUE_SYSCTL STD { int linux_sysctl( struct l___sysctl_args *args ); } 150 AUE_MLOCK NOPROTO { int mlock( const void *addr, size_t len ); } 151 AUE_MUNLOCK NOPROTO { int munlock( const void *addr, size_t len ); } 152 AUE_MLOCKALL NOPROTO { int mlockall( int how ); } 153 AUE_MUNLOCKALL NOPROTO { int munlockall(void); } 154 AUE_SCHED_SETPARAM STD { int linux_sched_setparam( l_pid_t pid, struct sched_param *param ); } 155 AUE_SCHED_GETPARAM STD { int linux_sched_getparam( l_pid_t pid, struct sched_param *param ); } 156 AUE_SCHED_SETSCHEDULER STD { int linux_sched_setscheduler( l_pid_t pid, l_int policy, struct sched_param *param ); } 157 AUE_SCHED_GETSCHEDULER STD { int linux_sched_getscheduler( l_pid_t pid ); } 158 AUE_NULL NOPROTO { int sched_yield(void); } 159 AUE_SCHED_GET_PRIORITY_MAX STD { int linux_sched_get_priority_max( l_int policy ); } 160 AUE_SCHED_GET_PRIORITY_MIN STD { int linux_sched_get_priority_min( l_int policy ); } 161 AUE_SCHED_RR_GET_INTERVAL STD { int linux_sched_rr_get_interval( l_pid_t pid, struct l_timespec *interval ); } 162 AUE_NULL STD { int linux_nanosleep( const struct l_timespec *rqtp, struct l_timespec *rmtp ); } 163 AUE_NULL STD { int linux_mremap( l_ulong addr, l_ulong old_len, l_ulong new_len, l_ulong flags, l_ulong new_addr ); } 164 AUE_SETRESUID STD { int linux_setresuid16( l_uid16_t ruid, l_uid16_t euid, l_uid16_t suid ); } 165 AUE_GETRESUID STD { int linux_getresuid16( l_uid16_t *ruid, l_uid16_t *euid, l_uid16_t *suid ); } 166 AUE_NULL STD { int linux_vm86(void); } 167 AUE_NULL UNIMPL query_module 168 AUE_POLL NOPROTO { int poll( struct pollfd *fds, unsigned int nfds, long timeout ); } 169 AUE_NULL UNIMPL nfsservctl 170 AUE_SETRESGID STD { int linux_setresgid16( l_gid16_t rgid, l_gid16_t egid, l_gid16_t sgid ); } 171 AUE_GETRESGID STD { int linux_getresgid16( l_gid16_t *rgid, l_gid16_t *egid, l_gid16_t *sgid ); } 172 AUE_PRCTL STD { int linux_prctl( l_int option, l_int arg2, l_int arg3, l_int arg4, l_int arg5 ); } 173 AUE_NULL STD { int linux_rt_sigreturn( struct l_ucontext *ucp ); } 174 AUE_NULL STD { int linux_rt_sigaction( l_int sig, l_sigaction_t *act, l_sigaction_t *oact, l_size_t sigsetsize ); } 175 AUE_NULL STD { int linux_rt_sigprocmask( l_int how, l_sigset_t *mask, l_sigset_t *omask, l_size_t sigsetsize ); } 176 AUE_NULL STD { int linux_rt_sigpending( l_sigset_t *set, l_size_t sigsetsize ); } 177 AUE_NULL STD { int linux_rt_sigtimedwait( l_sigset_t *mask, l_siginfo_t *ptr, struct l_timeval *timeout, l_size_t sigsetsize ); } 178 AUE_NULL STD { int linux_rt_sigqueueinfo( l_pid_t pid, l_int sig, l_siginfo_t *info ); } 179 AUE_NULL STD { int linux_rt_sigsuspend( l_sigset_t *newset, l_size_t sigsetsize ); } 180 AUE_PREAD STD { int linux_pread( l_uint fd, char *buf, l_size_t nbyte, l_loff_t offset ); } 181 AUE_PWRITE STD { int linux_pwrite( l_uint fd, char *buf, l_size_t nbyte, l_loff_t offset ); } 182 AUE_CHOWN STD { int linux_chown16( char *path, l_uid16_t uid, l_gid16_t gid ); } 183 AUE_GETCWD STD { int linux_getcwd( char *buf, l_ulong bufsize ); } 184 AUE_CAPGET STD { int linux_capget( struct l_user_cap_header *hdrp, struct l_user_cap_data *datap ); } 185 AUE_CAPSET STD { int linux_capset( struct l_user_cap_header *hdrp, struct l_user_cap_data *datap ); } 186 AUE_NULL STD { int linux_sigaltstack( l_stack_t *uss, l_stack_t *uoss ); } 187 AUE_SENDFILE STD { int linux_sendfile( l_int out, l_int in, l_long *offset, l_size_t count ); } 188 AUE_GETPMSG UNIMPL getpmsg 189 AUE_PUTPMSG UNIMPL putpmsg 190 AUE_VFORK STD { int linux_vfork(void); } ; 191: ugetrlimit 191 AUE_GETRLIMIT STD { int linux_getrlimit( l_uint resource, struct l_rlimit *rlim ); } 192 AUE_MMAP STD { int linux_mmap2( l_ulong addr, l_ulong len, l_ulong prot, l_ulong flags, l_ulong fd, l_ulong pgoff ); } 193 AUE_TRUNCATE STD { int linux_truncate64( char *path, l_loff_t length ); } 194 AUE_FTRUNCATE STD { int linux_ftruncate64( l_uint fd, l_loff_t length ); } 195 AUE_STAT STD { int linux_stat64( const char *filename, struct l_stat64 *statbuf ); } 196 AUE_LSTAT STD { int linux_lstat64( const char *filename, struct l_stat64 *statbuf ); } 197 AUE_FSTAT STD { int linux_fstat64( l_int fd, struct l_stat64 *statbuf ); } 198 AUE_LCHOWN STD { int linux_lchown( char *path, l_uid_t uid, l_gid_t gid ); } 199 AUE_GETUID STD { int linux_getuid(void); } 200 AUE_GETGID STD { int linux_getgid(void); } 201 AUE_GETEUID NOPROTO { int geteuid(void); } 202 AUE_GETEGID NOPROTO { int getegid(void); } 203 AUE_SETREUID NOPROTO { int setreuid( uid_t ruid, uid_t euid ); } 204 AUE_SETREGID NOPROTO { int setregid( gid_t rgid, gid_t egid ); } 205 AUE_GETGROUPS STD { int linux_getgroups( l_int gidsetsize, l_gid_t *grouplist ); } 206 AUE_SETGROUPS STD { int linux_setgroups( l_int gidsetsize, l_gid_t *grouplist ); } 207 AUE_FCHOWN NODEF fchown fchown fchown_args int 208 AUE_SETRESUID NOPROTO { int setresuid( uid_t ruid, uid_t euid, uid_t suid ); } 209 AUE_GETRESUID NOPROTO { int getresuid( uid_t *ruid, uid_t *euid, uid_t *suid ); } 210 AUE_SETRESGID NOPROTO { int setresgid( gid_t rgid, gid_t egid, gid_t sgid ); } 211 AUE_GETRESGID NOPROTO { int getresgid( gid_t *rgid, gid_t *egid, gid_t *sgid ); } 212 AUE_CHOWN STD { int linux_chown( char *path, l_uid_t uid, l_gid_t gid ); } 213 AUE_SETUID NOPROTO { int setuid( uid_t uid ); } 214 AUE_SETGID NOPROTO { int setgid( gid_t gid ); } 215 AUE_SETFSUID STD { int linux_setfsuid( l_uid_t uid ); } 216 AUE_SETFSGID STD { int linux_setfsgid( l_gid_t gid ); } 217 AUE_PIVOT_ROOT STD { int linux_pivot_root( char *new_root, char *put_old ); } 218 AUE_MINCORE STD { int linux_mincore( l_ulong start, l_size_t len, u_char *vec ); } 219 AUE_MADVISE STD { int linux_madvise( void *addr, size_t len, int behav ); } 220 AUE_GETDIRENTRIES STD { int linux_getdents64( l_uint fd, void *dirent, l_uint count ); } 221 AUE_FCNTL STD { int linux_fcntl64( l_uint fd, l_uint cmd, l_ulong arg ); } 222 AUE_NULL UNIMPL 223 AUE_NULL UNIMPL 224 AUE_NULL STD { long linux_gettid(void); } 225 AUE_NULL UNIMPL linux_readahead 226 AUE_NULL STD { int linux_setxattr( const char *path, const char *name, const char *value, l_size_t size, l_int flags ); } 227 AUE_NULL STD { int linux_lsetxattr( const char *path, const char *name, const char *value, l_size_t size, l_int flags ); } 228 AUE_NULL STD { int linux_fsetxattr( l_int fd, const char *name, const char *value, l_size_t size, l_int flags ); } 229 AUE_NULL STD { int linux_getxattr( const char *path, const char *name, char *value, l_size_t size ); } 230 AUE_NULL STD { int linux_lgetxattr( const char *path, const char *name, char *value, l_size_t size ); } 231 AUE_NULL STD { int linux_fgetxattr( l_int fd, const char *name, char *value, l_size_t size ); } 232 AUE_NULL STD { int linux_listxattr( const char *path, const char *list, l_size_t size ); } 233 AUE_NULL STD { int linux_llistxattr( const char *path, const char *list, l_size_t size ); } 234 AUE_NULL STD { int linux_flistxattr( l_int fd, const char *list, l_size_t size ); } 235 AUE_NULL STD { int linux_removexattr( const char *path, const char *name ); } 236 AUE_NULL STD { int linux_lremovexattr( const char *path, const char *name ); } 237 AUE_NULL STD { int linux_fremovexattr( l_int fd, const char *name ); } 238 AUE_NULL STD { int linux_tkill( int tid, int sig ); } 239 AUE_SENDFILE STD { int linux_sendfile64( l_int out, l_int in, l_loff_t *offset, l_size_t count ); } 240 AUE_NULL STD { int linux_sys_futex( void *uaddr, int op, uint32_t val, struct l_timespec *timeout, uint32_t *uaddr2, uint32_t val3 ); } 241 AUE_NULL STD { int linux_sched_setaffinity( l_pid_t pid, l_uint len, l_ulong *user_mask_ptr ); } 242 AUE_NULL STD { int linux_sched_getaffinity( l_pid_t pid, l_uint len, l_ulong *user_mask_ptr ); } 243 AUE_NULL STD { int linux_set_thread_area( struct l_user_desc *desc ); } 244 AUE_NULL STD { int linux_get_thread_area( struct l_user_desc *desc ); } 245 AUE_NULL UNIMPL linux_io_setup 246 AUE_NULL UNIMPL linux_io_destroy 247 AUE_NULL UNIMPL linux_io_getevents 248 AUE_NULL UNIMPL linux_io_submit 249 AUE_NULL UNIMPL linux_io_cancel 250 AUE_NULL STD { int linux_fadvise64( int fd, l_loff_t offset, l_size_t len, int advice ); } 251 AUE_NULL UNIMPL 252 AUE_EXIT STD { int linux_exit_group( int error_code ); } 253 AUE_NULL STD { int linux_lookup_dcookie(void); } 254 AUE_NULL STD { int linux_epoll_create( l_int size ); } 255 AUE_NULL STD { int linux_epoll_ctl( l_int epfd, l_int op, l_int fd, struct epoll_event *event ); } 256 AUE_NULL STD { int linux_epoll_wait( l_int epfd, struct epoll_event *events, l_int maxevents, l_int timeout ); } 257 AUE_NULL STD { int linux_remap_file_pages(void); } 258 AUE_NULL STD { int linux_set_tid_address( int *tidptr ); } 259 AUE_NULL STD { int linux_timer_create( clockid_t clock_id, struct sigevent *evp, l_timer_t *timerid ); } 260 AUE_NULL STD { int linux_timer_settime( l_timer_t timerid, l_int flags, const struct itimerspec *new, struct itimerspec *old ); } 261 AUE_NULL STD { int linux_timer_gettime( l_timer_t timerid, struct itimerspec *setting ); } 262 AUE_NULL STD { int linux_timer_getoverrun( l_timer_t timerid ); } 263 AUE_NULL STD { int linux_timer_delete( l_timer_t timerid ); } 264 AUE_CLOCK_SETTIME STD { int linux_clock_settime( clockid_t which, struct l_timespec *tp ); } 265 AUE_NULL STD { int linux_clock_gettime( clockid_t which, struct l_timespec *tp ); } 266 AUE_NULL STD { int linux_clock_getres( clockid_t which, struct l_timespec *tp ); } 267 AUE_NULL STD { int linux_clock_nanosleep( clockid_t which, int flags, struct l_timespec *rqtp, struct l_timespec *rmtp ); } 268 AUE_STATFS STD { int linux_statfs64( char *path, size_t bufsize, struct l_statfs64_buf *buf ); } 269 AUE_FSTATFS STD { int linux_fstatfs64( l_uint fd, size_t bufsize, struct l_statfs64_buf *buf ); } 270 AUE_NULL STD { int linux_tgkill( int tgid, int pid, int sig ); } 271 AUE_UTIMES STD { int linux_utimes( char *fname, struct l_timeval *tptr ); } 272 AUE_NULL STD { int linux_fadvise64_64( int fd, l_loff_t offset, l_loff_t len, int advice ); } 273 AUE_NULL UNIMPL vserver 274 AUE_NULL STD { int linux_mbind(void); } 275 AUE_NULL STD { int linux_get_mempolicy(void); } 276 AUE_NULL STD { int linux_set_mempolicy(void); } ; Linux 2.6.6: 277 AUE_NULL STD { int linux_mq_open( const char *name, l_int oflag, l_mode_t mode, struct mq_attr *attr ); } 278 AUE_NULL STD { int linux_mq_unlink( const char *name ); } 279 AUE_NULL STD { int linux_mq_timedsend( l_mqd_t mqd, const char *msg_ptr, l_size_t msg_len, l_uint msg_prio, const struct l_timespec *abs_timeout ); } 280 AUE_NULL STD { int linux_mq_timedreceive( l_mqd_t mqd, char *msg_ptr, l_size_t msg_len, l_uint *msg_prio, const struct l_timespec *abs_timeout ); } 281 AUE_NULL STD { int linux_mq_notify( l_mqd_t mqd, const struct l_timespec *abs_timeout ); } 282 AUE_NULL STD { int linux_mq_getsetattr( l_mqd_t mqd, const struct mq_attr *attr, struct mq_attr *oattr ); } 283 AUE_NULL STD { int linux_kexec_load(void); } 284 AUE_WAIT6 STD { int linux_waitid( int idtype, l_pid_t id, l_siginfo_t *info, int options, void *rusage ); } 285 AUE_NULL UNIMPL ; Linux 2.6.11: 286 AUE_NULL STD { int linux_add_key(void); } 287 AUE_NULL STD { int linux_request_key(void); } 288 AUE_NULL STD { int linux_keyctl(void); } ; Linux 2.6.13: 289 AUE_NULL STD { int linux_ioprio_set(void); } 290 AUE_NULL STD { int linux_ioprio_get(void); } 291 AUE_NULL STD { int linux_inotify_init(void); } 292 AUE_NULL STD { int linux_inotify_add_watch(void); } 293 AUE_NULL STD { int linux_inotify_rm_watch(void); } ; Linux 2.6.16: 294 AUE_NULL STD { int linux_migrate_pages(void); } 295 AUE_OPEN_RWTC STD { int linux_openat( l_int dfd, const char *filename, l_int flags, l_int mode ); } 296 AUE_MKDIRAT STD { int linux_mkdirat( l_int dfd, const char *pathname, l_int mode ); } 297 AUE_MKNODAT STD { int linux_mknodat( l_int dfd, const char *filename, l_int mode, l_uint dev ); } 298 AUE_FCHOWNAT STD { int linux_fchownat( l_int dfd, const char *filename, l_uid16_t uid, l_gid16_t gid, l_int flag ); } 299 AUE_FUTIMESAT STD { int linux_futimesat( l_int dfd, char *filename, struct l_timeval *utimes ); } 300 AUE_FSTATAT STD { int linux_fstatat64( l_int dfd, char *pathname, struct l_stat64 *statbuf, l_int flag ); } 301 AUE_UNLINKAT STD { int linux_unlinkat( l_int dfd, const char *pathname, l_int flag ); } 302 AUE_RENAMEAT STD { int linux_renameat( l_int olddfd, const char *oldname, l_int newdfd, const char *newname ); } 303 AUE_LINKAT STD { int linux_linkat( l_int olddfd, const char *oldname, l_int newdfd, const char *newname, l_int flag ); } 304 AUE_SYMLINKAT STD { int linux_symlinkat( const char *oldname, l_int newdfd, const char *newname ); } 305 AUE_READLINKAT STD { int linux_readlinkat( l_int dfd, const char *path, char *buf, l_int bufsiz ); } 306 AUE_FCHMODAT STD { int linux_fchmodat( l_int dfd, const char *filename, l_mode_t mode ); } 307 AUE_FACCESSAT STD { int linux_faccessat( l_int dfd, const char *filename, l_int amode ); } 308 AUE_SELECT STD { int linux_pselect6( l_int nfds, l_fd_set *readfds, l_fd_set *writefds, l_fd_set *exceptfds, struct l_timespec *tsp, l_uintptr_t *sig ); } 309 AUE_POLL STD { int linux_ppoll( struct pollfd *fds, uint32_t nfds, struct l_timespec *tsp, l_sigset_t *sset, l_size_t ssize ); } 310 AUE_NULL STD { int linux_unshare(void); } ; Linux 2.6.17: 311 AUE_NULL STD { int linux_set_robust_list( struct linux_robust_list_head *head, l_size_t len ); } 312 AUE_NULL STD { int linux_get_robust_list( l_int pid, struct linux_robust_list_head **head, l_size_t *len ); } 313 AUE_NULL STD { int linux_splice( int fd_in, l_loff_t *off_in, int fd_out, l_loff_t *off_out, l_size_t len, l_uint flags ); } 314 AUE_NULL STD { int linux_sync_file_range( l_int fd, l_loff_t offset, l_loff_t nbytes, unsigned int flags ); } 315 AUE_NULL STD { int linux_tee(void); } 316 AUE_NULL STD { int linux_vmsplice(void); } ; Linux 2.6.18: 317 AUE_NULL STD { int linux_move_pages(void); } ; Linux 2.6.19: 318 AUE_NULL STD { int linux_getcpu( l_uint *cpu, l_uint *node, void *cache ); } 319 AUE_NULL STD { int linux_epoll_pwait( l_int epfd, struct epoll_event *events, l_int maxevents, l_int timeout, l_sigset_t *mask, l_size_t sigsetsize ); } ; Linux 2.6.22: 320 AUE_FUTIMESAT STD { int linux_utimensat( l_int dfd, const char *pathname, const struct l_timespec *times, l_int flags ); } 321 AUE_NULL STD { int linux_signalfd(void); } 322 AUE_NULL STD { int linux_timerfd_create( l_int clockid, l_int flags ); } 323 AUE_NULL STD { int linux_eventfd( l_uint initval ); } ; Linux 2.6.23: 324 AUE_NULL STD { int linux_fallocate( l_int fd, l_int mode, l_loff_t offset, l_loff_t len ); } ; Linux 2.6.25: 325 AUE_NULL STD { int linux_timerfd_settime( l_int fd, l_int flags, const struct l_itimerspec *new_value, struct l_itimerspec *old_value ); } 326 AUE_NULL STD { int linux_timerfd_gettime( l_int fd, struct l_itimerspec *old_value ); } ; Linux 2.6.27: 327 AUE_NULL STD { int linux_signalfd4(void); } 328 AUE_NULL STD { int linux_eventfd2( l_uint initval, l_int flags ); } 329 AUE_NULL STD { int linux_epoll_create1( l_int flags ); } 330 AUE_NULL STD { int linux_dup3( l_int oldfd, l_int newfd, l_int flags ); } 331 AUE_NULL STD { int linux_pipe2( l_int *pipefds, l_int flags ); } 332 AUE_NULL STD { int linux_inotify_init1(void); } ; Linux 2.6.30: 333 AUE_NULL STD { int linux_preadv( l_ulong fd, struct iovec *vec, l_ulong vlen, l_ulong pos_l, l_ulong pos_h ); } 334 AUE_NULL STD { int linux_pwritev( l_ulong fd, struct iovec *vec, l_ulong vlen, l_ulong pos_l, l_ulong pos_h ); } ; Linux 2.6.31: 335 AUE_NULL STD { int linux_rt_tgsigqueueinfo( l_pid_t tgid, l_pid_t tid, l_int sig, l_siginfo_t *uinfo ); } 336 AUE_NULL STD { int linux_perf_event_open(void); } ; Linux 2.6.33: 337 AUE_NULL STD { int linux_recvmmsg( l_int s, struct l_mmsghdr *msg, l_uint vlen, l_uint flags, struct l_timespec *timeout ); } 338 AUE_NULL STD { int linux_fanotify_init(void); } 339 AUE_NULL STD { int linux_fanotify_mark(void); } ; Linux 2.6.36: 340 AUE_NULL STD { int linux_prlimit64( l_pid_t pid, l_uint resource, struct rlimit *new, struct rlimit *old ); } ; Linux 2.6.39: 341 AUE_NULL STD { - int linux_name_to_handle_at(void); + int linux_name_to_handle_at( + l_int dirfd, + const char *name, + struct l_file_handle *handle, + l_int *mnt_id, + l_int flags + ); } 342 AUE_NULL STD { - int linux_open_by_handle_at(void); + int linux_open_by_handle_at( + l_int mountdirfd, + struct l_file_handle *handle, + l_int flags + ); } 343 AUE_NULL STD { int linux_clock_adjtime(void); } 344 AUE_SYNC STD { int linux_syncfs( l_int fd ); } ; Linux 3.0: 345 AUE_NULL STD { int linux_sendmmsg( l_int s, struct l_mmsghdr *msg, l_uint vlen, l_uint flags ); } 346 AUE_NULL STD { int linux_setns(void); } ; Linux 3.2 (glibc 2.15): 347 AUE_NULL STD { int linux_process_vm_readv( l_pid_t pid, const struct iovec *lvec, l_ulong liovcnt, const struct iovec *rvec, l_ulong riovcnt, l_ulong flags ); } 348 AUE_NULL STD { int linux_process_vm_writev( l_pid_t pid, const struct iovec *lvec, l_ulong liovcnt, const struct iovec *rvec, l_ulong riovcnt, l_ulong flags ); } ; Linux 3.5 (no glibc wrapper): 349 AUE_NULL STD { int linux_kcmp( l_pid_t pid1, l_pid_t pid2, l_int type, l_ulong idx1, l_ulong idx ); } ; Linux 3.8 (no glibc wrapper): 350 AUE_NULL STD { int linux_finit_module( l_int fd, const char *uargs, l_int flags ); } ; Linux 3.14: 351 AUE_NULL STD { int linux_sched_setattr( l_pid_t pid, void *attr, l_uint flags ); } 352 AUE_NULL STD { int linux_sched_getattr( l_pid_t pid, void *attr, l_uint size, l_uint flags ); } ; Linux 3.15: 353 AUE_NULL STD { int linux_renameat2( l_int olddfd, const char *oldname, l_int newdfd, const char *newname, unsigned int flags ); } ; Linux 3.17: 354 AUE_NULL STD { int linux_seccomp( l_uint op, l_uint flags, const char *uargs ); } 355 AUE_NULL STD { int linux_getrandom( char *buf, l_size_t count, l_uint flags ); } 356 AUE_NULL STD { int linux_memfd_create( const char *uname_ptr, l_uint flags ); } ; Linux 3.18: 357 AUE_NULL STD { int linux_bpf( l_int cmd, void *attr, l_uint size ); } ; Linux 3.19: 358 AUE_NULL STD { int linux_execveat( l_int dfd, const char *filename, const char **argv, const char **envp, l_int flags ); } ; Linux 4.3: sockets now direct system calls: 359 AUE_SOCKET STD { int linux_socket( l_int domain, l_int type, l_int protocol ); } 360 AUE_SOCKETPAIR STD { int linux_socketpair( l_int domain, l_int type, l_int protocol, l_uintptr_t rsv ); } 361 AUE_BIND STD { int linux_bind( l_int s, l_uintptr_t name, l_int namelen ); } 362 AUE_CONNECT STD { int linux_connect( l_int s, l_uintptr_t name, l_int namelen ); } 363 AUE_LISTEN STD { int linux_listen( l_int s, l_int backlog ); } 364 AUE_ACCEPT STD { int linux_accept4( l_int s, l_uintptr_t addr, l_uintptr_t namelen, l_int flags ); } 365 AUE_GETSOCKOPT STD { int linux_getsockopt( l_int s, l_int level, l_int optname, l_uintptr_t optval, l_uintptr_t optlen ); } 366 AUE_SETSOCKOPT STD { int linux_setsockopt( l_int s, l_int level, l_int optname, l_uintptr_t optval, l_int optlen ); } 367 AUE_GETSOCKNAME STD { int linux_getsockname( l_int s, l_uintptr_t addr, l_uintptr_t namelen ); } 368 AUE_GETPEERNAME STD { int linux_getpeername( l_int s, l_uintptr_t addr, l_uintptr_t namelen ); } 369 AUE_SENDTO STD { int linux_sendto( l_int s, l_uintptr_t msg, l_int len, l_int flags, l_uintptr_t to, l_int tolen ); } 370 AUE_SENDMSG STD { int linux_sendmsg( l_int s, l_uintptr_t msg, l_int flags ); } 371 AUE_RECVFROM STD { int linux_recvfrom( l_int s, l_uintptr_t buf, l_size_t len, l_int flags, l_uintptr_t from, l_uintptr_t fromlen ); } 372 AUE_RECVMSG STD { int linux_recvmsg( l_int s, l_uintptr_t msg, l_int flags ); } 373 AUE_NULL STD { int linux_shutdown( l_int s, l_int how ); } ; Linux 4.2: 374 AUE_NULL STD { int linux_userfaultfd( l_int flags ); } ; Linux 4.3: 375 AUE_NULL STD { int linux_membarrier( l_int cmd, l_int flags ); } ; Linux 4.4: 376 AUE_NULL STD { int linux_mlock2( l_ulong start, l_size_t len, l_int flags ); } ; Linux 4.5: 377 AUE_NULL STD { int linux_copy_file_range( l_int fd_in, l_loff_t *off_in, l_int fd_out, l_loff_t *off_out, l_size_t len, l_uint flags ); } ; Linux 4.6: 378 AUE_NULL STD { int linux_preadv2( l_ulong fd, const struct iovec *vec, l_ulong vlen, l_ulong pos_l, l_ulong pos_h, l_int flags ); } 379 AUE_NULL STD { int linux_pwritev2( l_ulong fd, const struct iovec *vec, l_ulong vlen, l_ulong pos_l, l_ulong pos_h, l_int flags ); } ; Linux 4.8: 380 AUE_NULL STD { int linux_pkey_mprotect( l_ulong start, l_size_t len, l_ulong prot, l_int pkey ); } 381 AUE_NULL STD { int linux_pkey_alloc( l_ulong flags, l_ulong init_val ); } 382 AUE_NULL STD { int linux_pkey_free( l_int pkey ); } ; Linux 4.11: 383 AUE_NULL STD { int linux_statx( l_int dirfd, const char *pathname, l_uint flags, l_uint mask, void *statxbuf ); } 384 AUE_PRCTL STD { int linux_arch_prctl( l_int option, l_ulong arg2 ); } ; Linux 4.18: 385 AUE_NULL STD { int linux_io_pgetevents(void); } 386 AUE_NULL STD { int linux_rseq(void); } 387-392 AUE_NULL UNIMPL nosys 393 AUE_NULL STD { int linux_semget( l_key_t key, l_int nsems, l_int semflg ); } 394 AUE_NULL STD { int linux_semctl( l_int semid, l_int semnum, l_int cmd, union l_semun arg ); } 395 AUE_NULL STD { int linux_shmget( l_key_t key, l_size_t size, l_int shmflg ); } 396 AUE_NULL STD { int linux_shmctl( l_int shmid, l_int cmd, struct l_shmid_ds *buf ); } 397 AUE_NULL STD { int linux_shmat( l_int shmid, char *shmaddr, l_int shmflg ); } 398 AUE_NULL STD { int linux_shmdt( char *shmaddr ); } 399 AUE_NULL STD { int linux_msgget( l_key_t key, l_int msgflg ); } 400 AUE_NULL STD { int linux_msgsnd( l_int msqid, struct l_msgbuf *msgp, l_size_t msgsz, l_int msgflg ); } 401 AUE_NULL STD { int linux_msgrcv( l_int msqid, struct l_msgbuf *msgp, l_size_t msgsz, l_long msgtyp, l_int msgflg ); } 402 AUE_NULL STD { int linux_msgctl( l_int msqid, l_int cmd, struct l_msqid_ds *buf ); } ; Linux 5.0: 403 AUE_NULL STD { int linux_clock_gettime64(void); } 404 AUE_NULL STD { int linux_clock_settime64(void); } 405 AUE_NULL STD { int linux_clock_adjtime64(void); } 406 AUE_NULL STD { int linux_clock_getres_time64(void); } 407 AUE_NULL STD { int linux_clock_nanosleep_time64(void); } 408 AUE_NULL STD { int linux_timer_gettime64(void); } 409 AUE_NULL STD { int linux_timer_settime64(void); } 410 AUE_NULL STD { int linux_timerfd_gettime64(void); } 411 AUE_NULL STD { int linux_timerfd_settime64(void); } 412 AUE_NULL STD { int linux_utimensat_time64(void); } 413 AUE_NULL STD { int linux_pselect6_time64(void); } 414 AUE_NULL STD { int linux_ppoll_time64(void); } 415 AUE_NULL UNIMPL nosys 416 AUE_NULL STD { int linux_io_pgetevents_time64(void); } 417 AUE_NULL STD { int linux_recvmmsg_time64(void); } 418 AUE_NULL STD { int linux_mq_timedsend_time64(void); } 419 AUE_NULL STD { int linux_mq_timedreceive_time64(void); } 420 AUE_NULL STD { int linux_semtimedop_time64(void); } 421 AUE_NULL STD { int linux_rt_sigtimedwait_time64(void); } 422 AUE_NULL STD { int linux_futex_time64(void); } 423 AUE_NULL STD { int linux_sched_rr_get_interval_time64(void); } 424 AUE_NULL STD { int linux_pidfd_send_signal( l_int pidfd, l_int sig, l_siginfo_t *info, l_uint flags ); } 425 AUE_NULL STD { int linux_io_uring_setup(void); } 426 AUE_NULL STD { int linux_io_uring_enter(void); } 427 AUE_NULL STD { int linux_io_uring_register(void); } ; please, keep this line at the end. 428 AUE_NULL UNIMPL nosys ; vim: syntax=off Index: head/sys/kern/vfs_syscalls.c =================================================================== --- head/sys/kern/vfs_syscalls.c (revision 367772) +++ head/sys/kern/vfs_syscalls.c (revision 367773) @@ -1,4953 +1,4961 @@ /*- * SPDX-License-Identifier: BSD-3-Clause * * Copyright (c) 1989, 1993 * The Regents of the University of California. All rights reserved. * (c) UNIX System Laboratories, Inc. * All or some portions of this file are derived from material licensed * to the University of California by American Telephone and Telegraph * Co. or Unix System Laboratories, Inc. and are reproduced herein with * the permission of UNIX System Laboratories, Inc. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * * @(#)vfs_syscalls.c 8.13 (Berkeley) 4/15/94 */ #include __FBSDID("$FreeBSD$"); #include "opt_capsicum.h" #include "opt_ktrace.h" #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #ifdef KTRACE #include #endif #include #include #include #include #include #include #include #include #include MALLOC_DEFINE(M_FADVISE, "fadvise", "posix_fadvise(2) information"); static int kern_chflagsat(struct thread *td, int fd, const char *path, enum uio_seg pathseg, u_long flags, int atflag); static int setfflags(struct thread *td, struct vnode *, u_long); static int getutimes(const struct timeval *, enum uio_seg, struct timespec *); static int getutimens(const struct timespec *, enum uio_seg, struct timespec *, int *); static int setutimes(struct thread *td, struct vnode *, const struct timespec *, int, int); static int vn_access(struct vnode *vp, int user_flags, struct ucred *cred, struct thread *td); static int kern_fhlinkat(struct thread *td, int fd, const char *path, enum uio_seg pathseg, fhandle_t *fhp); -static int kern_getfhat(struct thread *td, int flags, int fd, - const char *path, enum uio_seg pathseg, fhandle_t *fhp); static int kern_readlink_vp(struct vnode *vp, char *buf, enum uio_seg bufseg, size_t count, struct thread *td); static int kern_linkat_vp(struct thread *td, struct vnode *vp, int fd, const char *path, enum uio_seg segflag); static uint64_t at2cnpflags(u_int at_flags, u_int mask) { u_int64_t res; MPASS((at_flags & (AT_SYMLINK_FOLLOW | AT_SYMLINK_NOFOLLOW)) != (AT_SYMLINK_FOLLOW | AT_SYMLINK_NOFOLLOW)); res = 0; at_flags &= mask; if ((at_flags & AT_BENEATH) != 0) res |= BENEATH; if ((at_flags & AT_RESOLVE_BENEATH) != 0) res |= RBENEATH; if ((at_flags & AT_SYMLINK_FOLLOW) != 0) res |= FOLLOW; /* NOFOLLOW is pseudo flag */ if ((mask & AT_SYMLINK_NOFOLLOW) != 0) { res |= (at_flags & AT_SYMLINK_NOFOLLOW) != 0 ? NOFOLLOW : FOLLOW; } return (res); } int kern_sync(struct thread *td) { struct mount *mp, *nmp; int save; mtx_lock(&mountlist_mtx); for (mp = TAILQ_FIRST(&mountlist); mp != NULL; mp = nmp) { if (vfs_busy(mp, MBF_NOWAIT | MBF_MNTLSTLOCK)) { nmp = TAILQ_NEXT(mp, mnt_list); continue; } if ((mp->mnt_flag & MNT_RDONLY) == 0 && vn_start_write(NULL, &mp, V_NOWAIT) == 0) { save = curthread_pflags_set(TDP_SYNCIO); vfs_periodic(mp, MNT_NOWAIT); VFS_SYNC(mp, MNT_NOWAIT); curthread_pflags_restore(save); vn_finished_write(mp); } mtx_lock(&mountlist_mtx); nmp = TAILQ_NEXT(mp, mnt_list); vfs_unbusy(mp); } mtx_unlock(&mountlist_mtx); return (0); } /* * Sync each mounted filesystem. */ #ifndef _SYS_SYSPROTO_H_ struct sync_args { int dummy; }; #endif /* ARGSUSED */ int sys_sync(struct thread *td, struct sync_args *uap) { return (kern_sync(td)); } /* * Change filesystem quotas. */ #ifndef _SYS_SYSPROTO_H_ struct quotactl_args { char *path; int cmd; int uid; caddr_t arg; }; #endif int sys_quotactl(struct thread *td, struct quotactl_args *uap) { struct mount *mp; struct nameidata nd; int error; AUDIT_ARG_CMD(uap->cmd); AUDIT_ARG_UID(uap->uid); if (!prison_allow(td->td_ucred, PR_ALLOW_QUOTAS)) return (EPERM); NDINIT(&nd, LOOKUP, FOLLOW | LOCKLEAF | AUDITVNODE1, UIO_USERSPACE, uap->path, td); if ((error = namei(&nd)) != 0) return (error); NDFREE(&nd, NDF_ONLY_PNBUF); mp = nd.ni_vp->v_mount; vfs_ref(mp); vput(nd.ni_vp); error = vfs_busy(mp, 0); if (error != 0) { vfs_rel(mp); return (error); } error = VFS_QUOTACTL(mp, uap->cmd, uap->uid, uap->arg); /* * Since quota on operation typically needs to open quota * file, the Q_QUOTAON handler needs to unbusy the mount point * before calling into namei. Otherwise, unmount might be * started between two vfs_busy() invocations (first is our, * second is from mount point cross-walk code in lookup()), * causing deadlock. * * Require that Q_QUOTAON handles the vfs_busy() reference on * its own, always returning with ubusied mount point. */ if ((uap->cmd >> SUBCMDSHIFT) != Q_QUOTAON && (uap->cmd >> SUBCMDSHIFT) != Q_QUOTAOFF) vfs_unbusy(mp); vfs_rel(mp); return (error); } /* * Used by statfs conversion routines to scale the block size up if * necessary so that all of the block counts are <= 'max_size'. Note * that 'max_size' should be a bitmask, i.e. 2^n - 1 for some non-zero * value of 'n'. */ void statfs_scale_blocks(struct statfs *sf, long max_size) { uint64_t count; int shift; KASSERT(powerof2(max_size + 1), ("%s: invalid max_size", __func__)); /* * Attempt to scale the block counts to give a more accurate * overview to userland of the ratio of free space to used * space. To do this, find the largest block count and compute * a divisor that lets it fit into a signed integer <= max_size. */ if (sf->f_bavail < 0) count = -sf->f_bavail; else count = sf->f_bavail; count = MAX(sf->f_blocks, MAX(sf->f_bfree, count)); if (count <= max_size) return; count >>= flsl(max_size); shift = 0; while (count > 0) { shift++; count >>=1; } sf->f_bsize <<= shift; sf->f_blocks >>= shift; sf->f_bfree >>= shift; sf->f_bavail >>= shift; } static int kern_do_statfs(struct thread *td, struct mount *mp, struct statfs *buf) { int error; if (mp == NULL) return (EBADF); error = vfs_busy(mp, 0); vfs_rel(mp); if (error != 0) return (error); #ifdef MAC error = mac_mount_check_stat(td->td_ucred, mp); if (error != 0) goto out; #endif error = VFS_STATFS(mp, buf); if (error != 0) goto out; if (priv_check_cred_vfs_generation(td->td_ucred)) { buf->f_fsid.val[0] = buf->f_fsid.val[1] = 0; prison_enforce_statfs(td->td_ucred, mp, buf); } out: vfs_unbusy(mp); return (error); } /* * Get filesystem statistics. */ #ifndef _SYS_SYSPROTO_H_ struct statfs_args { char *path; struct statfs *buf; }; #endif int sys_statfs(struct thread *td, struct statfs_args *uap) { struct statfs *sfp; int error; sfp = malloc(sizeof(struct statfs), M_STATFS, M_WAITOK); error = kern_statfs(td, uap->path, UIO_USERSPACE, sfp); if (error == 0) error = copyout(sfp, uap->buf, sizeof(struct statfs)); free(sfp, M_STATFS); return (error); } int kern_statfs(struct thread *td, const char *path, enum uio_seg pathseg, struct statfs *buf) { struct mount *mp; struct nameidata nd; int error; NDINIT(&nd, LOOKUP, FOLLOW | LOCKSHARED | LOCKLEAF | AUDITVNODE1, pathseg, path, td); error = namei(&nd); if (error != 0) return (error); mp = nd.ni_vp->v_mount; vfs_ref(mp); NDFREE(&nd, NDF_ONLY_PNBUF); vput(nd.ni_vp); return (kern_do_statfs(td, mp, buf)); } /* * Get filesystem statistics. */ #ifndef _SYS_SYSPROTO_H_ struct fstatfs_args { int fd; struct statfs *buf; }; #endif int sys_fstatfs(struct thread *td, struct fstatfs_args *uap) { struct statfs *sfp; int error; sfp = malloc(sizeof(struct statfs), M_STATFS, M_WAITOK); error = kern_fstatfs(td, uap->fd, sfp); if (error == 0) error = copyout(sfp, uap->buf, sizeof(struct statfs)); free(sfp, M_STATFS); return (error); } int kern_fstatfs(struct thread *td, int fd, struct statfs *buf) { struct file *fp; struct mount *mp; struct vnode *vp; int error; AUDIT_ARG_FD(fd); error = getvnode(td, fd, &cap_fstatfs_rights, &fp); if (error != 0) return (error); vp = fp->f_vnode; vn_lock(vp, LK_SHARED | LK_RETRY); #ifdef AUDIT AUDIT_ARG_VNODE1(vp); #endif mp = vp->v_mount; if (mp != NULL) vfs_ref(mp); VOP_UNLOCK(vp); fdrop(fp, td); return (kern_do_statfs(td, mp, buf)); } /* * Get statistics on all filesystems. */ #ifndef _SYS_SYSPROTO_H_ struct getfsstat_args { struct statfs *buf; long bufsize; int mode; }; #endif int sys_getfsstat(struct thread *td, struct getfsstat_args *uap) { size_t count; int error; if (uap->bufsize < 0 || uap->bufsize > SIZE_MAX) return (EINVAL); error = kern_getfsstat(td, &uap->buf, uap->bufsize, &count, UIO_USERSPACE, uap->mode); if (error == 0) td->td_retval[0] = count; return (error); } /* * If (bufsize > 0 && bufseg == UIO_SYSSPACE) * The caller is responsible for freeing memory which will be allocated * in '*buf'. */ int kern_getfsstat(struct thread *td, struct statfs **buf, size_t bufsize, size_t *countp, enum uio_seg bufseg, int mode) { struct mount *mp, *nmp; struct statfs *sfsp, *sp, *sptmp, *tofree; size_t count, maxcount; int error; switch (mode) { case MNT_WAIT: case MNT_NOWAIT: break; default: if (bufseg == UIO_SYSSPACE) *buf = NULL; return (EINVAL); } restart: maxcount = bufsize / sizeof(struct statfs); if (bufsize == 0) { sfsp = NULL; tofree = NULL; } else if (bufseg == UIO_USERSPACE) { sfsp = *buf; tofree = NULL; } else /* if (bufseg == UIO_SYSSPACE) */ { count = 0; mtx_lock(&mountlist_mtx); TAILQ_FOREACH(mp, &mountlist, mnt_list) { count++; } mtx_unlock(&mountlist_mtx); if (maxcount > count) maxcount = count; tofree = sfsp = *buf = malloc(maxcount * sizeof(struct statfs), M_STATFS, M_WAITOK); } count = 0; /* * If there is no target buffer they only want the count. * * This could be TAILQ_FOREACH but it is open-coded to match the original * code below. */ if (sfsp == NULL) { mtx_lock(&mountlist_mtx); for (mp = TAILQ_FIRST(&mountlist); mp != NULL; mp = nmp) { if (prison_canseemount(td->td_ucred, mp) != 0) { nmp = TAILQ_NEXT(mp, mnt_list); continue; } #ifdef MAC if (mac_mount_check_stat(td->td_ucred, mp) != 0) { nmp = TAILQ_NEXT(mp, mnt_list); continue; } #endif count++; nmp = TAILQ_NEXT(mp, mnt_list); } mtx_unlock(&mountlist_mtx); *countp = count; return (0); } /* * They want the entire thing. * * Short-circuit the corner case of no room for anything, avoids * relocking below. */ if (maxcount < 1) { goto out; } mtx_lock(&mountlist_mtx); for (mp = TAILQ_FIRST(&mountlist); mp != NULL; mp = nmp) { if (prison_canseemount(td->td_ucred, mp) != 0) { nmp = TAILQ_NEXT(mp, mnt_list); continue; } #ifdef MAC if (mac_mount_check_stat(td->td_ucred, mp) != 0) { nmp = TAILQ_NEXT(mp, mnt_list); continue; } #endif if (mode == MNT_WAIT) { if (vfs_busy(mp, MBF_MNTLSTLOCK) != 0) { /* * If vfs_busy() failed, and MBF_NOWAIT * wasn't passed, then the mp is gone. * Furthermore, because of MBF_MNTLSTLOCK, * the mountlist_mtx was dropped. We have * no other choice than to start over. */ mtx_unlock(&mountlist_mtx); free(tofree, M_STATFS); goto restart; } } else { if (vfs_busy(mp, MBF_NOWAIT | MBF_MNTLSTLOCK) != 0) { nmp = TAILQ_NEXT(mp, mnt_list); continue; } } sp = &mp->mnt_stat; /* * If MNT_NOWAIT is specified, do not refresh * the fsstat cache. */ if (mode != MNT_NOWAIT) { error = VFS_STATFS(mp, sp); if (error != 0) { mtx_lock(&mountlist_mtx); nmp = TAILQ_NEXT(mp, mnt_list); vfs_unbusy(mp); continue; } } if (priv_check_cred_vfs_generation(td->td_ucred)) { sptmp = malloc(sizeof(struct statfs), M_STATFS, M_WAITOK); *sptmp = *sp; sptmp->f_fsid.val[0] = sptmp->f_fsid.val[1] = 0; prison_enforce_statfs(td->td_ucred, mp, sptmp); sp = sptmp; } else sptmp = NULL; if (bufseg == UIO_SYSSPACE) { bcopy(sp, sfsp, sizeof(*sp)); free(sptmp, M_STATFS); } else /* if (bufseg == UIO_USERSPACE) */ { error = copyout(sp, sfsp, sizeof(*sp)); free(sptmp, M_STATFS); if (error != 0) { vfs_unbusy(mp); return (error); } } sfsp++; count++; if (count == maxcount) { vfs_unbusy(mp); goto out; } mtx_lock(&mountlist_mtx); nmp = TAILQ_NEXT(mp, mnt_list); vfs_unbusy(mp); } mtx_unlock(&mountlist_mtx); out: *countp = count; return (0); } #ifdef COMPAT_FREEBSD4 /* * Get old format filesystem statistics. */ static void freebsd4_cvtstatfs(struct statfs *, struct ostatfs *); #ifndef _SYS_SYSPROTO_H_ struct freebsd4_statfs_args { char *path; struct ostatfs *buf; }; #endif int freebsd4_statfs(struct thread *td, struct freebsd4_statfs_args *uap) { struct ostatfs osb; struct statfs *sfp; int error; sfp = malloc(sizeof(struct statfs), M_STATFS, M_WAITOK); error = kern_statfs(td, uap->path, UIO_USERSPACE, sfp); if (error == 0) { freebsd4_cvtstatfs(sfp, &osb); error = copyout(&osb, uap->buf, sizeof(osb)); } free(sfp, M_STATFS); return (error); } /* * Get filesystem statistics. */ #ifndef _SYS_SYSPROTO_H_ struct freebsd4_fstatfs_args { int fd; struct ostatfs *buf; }; #endif int freebsd4_fstatfs(struct thread *td, struct freebsd4_fstatfs_args *uap) { struct ostatfs osb; struct statfs *sfp; int error; sfp = malloc(sizeof(struct statfs), M_STATFS, M_WAITOK); error = kern_fstatfs(td, uap->fd, sfp); if (error == 0) { freebsd4_cvtstatfs(sfp, &osb); error = copyout(&osb, uap->buf, sizeof(osb)); } free(sfp, M_STATFS); return (error); } /* * Get statistics on all filesystems. */ #ifndef _SYS_SYSPROTO_H_ struct freebsd4_getfsstat_args { struct ostatfs *buf; long bufsize; int mode; }; #endif int freebsd4_getfsstat(struct thread *td, struct freebsd4_getfsstat_args *uap) { struct statfs *buf, *sp; struct ostatfs osb; size_t count, size; int error; if (uap->bufsize < 0) return (EINVAL); count = uap->bufsize / sizeof(struct ostatfs); if (count > SIZE_MAX / sizeof(struct statfs)) return (EINVAL); size = count * sizeof(struct statfs); error = kern_getfsstat(td, &buf, size, &count, UIO_SYSSPACE, uap->mode); if (error == 0) td->td_retval[0] = count; if (size != 0) { sp = buf; while (count != 0 && error == 0) { freebsd4_cvtstatfs(sp, &osb); error = copyout(&osb, uap->buf, sizeof(osb)); sp++; uap->buf++; count--; } free(buf, M_STATFS); } return (error); } /* * Implement fstatfs() for (NFS) file handles. */ #ifndef _SYS_SYSPROTO_H_ struct freebsd4_fhstatfs_args { struct fhandle *u_fhp; struct ostatfs *buf; }; #endif int freebsd4_fhstatfs(struct thread *td, struct freebsd4_fhstatfs_args *uap) { struct ostatfs osb; struct statfs *sfp; fhandle_t fh; int error; error = copyin(uap->u_fhp, &fh, sizeof(fhandle_t)); if (error != 0) return (error); sfp = malloc(sizeof(struct statfs), M_STATFS, M_WAITOK); error = kern_fhstatfs(td, fh, sfp); if (error == 0) { freebsd4_cvtstatfs(sfp, &osb); error = copyout(&osb, uap->buf, sizeof(osb)); } free(sfp, M_STATFS); return (error); } /* * Convert a new format statfs structure to an old format statfs structure. */ static void freebsd4_cvtstatfs(struct statfs *nsp, struct ostatfs *osp) { statfs_scale_blocks(nsp, LONG_MAX); bzero(osp, sizeof(*osp)); osp->f_bsize = nsp->f_bsize; osp->f_iosize = MIN(nsp->f_iosize, LONG_MAX); osp->f_blocks = nsp->f_blocks; osp->f_bfree = nsp->f_bfree; osp->f_bavail = nsp->f_bavail; osp->f_files = MIN(nsp->f_files, LONG_MAX); osp->f_ffree = MIN(nsp->f_ffree, LONG_MAX); osp->f_owner = nsp->f_owner; osp->f_type = nsp->f_type; osp->f_flags = nsp->f_flags; osp->f_syncwrites = MIN(nsp->f_syncwrites, LONG_MAX); osp->f_asyncwrites = MIN(nsp->f_asyncwrites, LONG_MAX); osp->f_syncreads = MIN(nsp->f_syncreads, LONG_MAX); osp->f_asyncreads = MIN(nsp->f_asyncreads, LONG_MAX); strlcpy(osp->f_fstypename, nsp->f_fstypename, MIN(MFSNAMELEN, OMFSNAMELEN)); strlcpy(osp->f_mntonname, nsp->f_mntonname, MIN(MNAMELEN, OMNAMELEN)); strlcpy(osp->f_mntfromname, nsp->f_mntfromname, MIN(MNAMELEN, OMNAMELEN)); osp->f_fsid = nsp->f_fsid; } #endif /* COMPAT_FREEBSD4 */ #if defined(COMPAT_FREEBSD11) /* * Get old format filesystem statistics. */ static void freebsd11_cvtstatfs(struct statfs *, struct freebsd11_statfs *); int freebsd11_statfs(struct thread *td, struct freebsd11_statfs_args *uap) { struct freebsd11_statfs osb; struct statfs *sfp; int error; sfp = malloc(sizeof(struct statfs), M_STATFS, M_WAITOK); error = kern_statfs(td, uap->path, UIO_USERSPACE, sfp); if (error == 0) { freebsd11_cvtstatfs(sfp, &osb); error = copyout(&osb, uap->buf, sizeof(osb)); } free(sfp, M_STATFS); return (error); } /* * Get filesystem statistics. */ int freebsd11_fstatfs(struct thread *td, struct freebsd11_fstatfs_args *uap) { struct freebsd11_statfs osb; struct statfs *sfp; int error; sfp = malloc(sizeof(struct statfs), M_STATFS, M_WAITOK); error = kern_fstatfs(td, uap->fd, sfp); if (error == 0) { freebsd11_cvtstatfs(sfp, &osb); error = copyout(&osb, uap->buf, sizeof(osb)); } free(sfp, M_STATFS); return (error); } /* * Get statistics on all filesystems. */ int freebsd11_getfsstat(struct thread *td, struct freebsd11_getfsstat_args *uap) { struct freebsd11_statfs osb; struct statfs *buf, *sp; size_t count, size; int error; count = uap->bufsize / sizeof(struct ostatfs); size = count * sizeof(struct statfs); error = kern_getfsstat(td, &buf, size, &count, UIO_SYSSPACE, uap->mode); if (error == 0) td->td_retval[0] = count; if (size > 0) { sp = buf; while (count > 0 && error == 0) { freebsd11_cvtstatfs(sp, &osb); error = copyout(&osb, uap->buf, sizeof(osb)); sp++; uap->buf++; count--; } free(buf, M_STATFS); } return (error); } /* * Implement fstatfs() for (NFS) file handles. */ int freebsd11_fhstatfs(struct thread *td, struct freebsd11_fhstatfs_args *uap) { struct freebsd11_statfs osb; struct statfs *sfp; fhandle_t fh; int error; error = copyin(uap->u_fhp, &fh, sizeof(fhandle_t)); if (error) return (error); sfp = malloc(sizeof(struct statfs), M_STATFS, M_WAITOK); error = kern_fhstatfs(td, fh, sfp); if (error == 0) { freebsd11_cvtstatfs(sfp, &osb); error = copyout(&osb, uap->buf, sizeof(osb)); } free(sfp, M_STATFS); return (error); } /* * Convert a new format statfs structure to an old format statfs structure. */ static void freebsd11_cvtstatfs(struct statfs *nsp, struct freebsd11_statfs *osp) { bzero(osp, sizeof(*osp)); osp->f_version = FREEBSD11_STATFS_VERSION; osp->f_type = nsp->f_type; osp->f_flags = nsp->f_flags; osp->f_bsize = nsp->f_bsize; osp->f_iosize = nsp->f_iosize; osp->f_blocks = nsp->f_blocks; osp->f_bfree = nsp->f_bfree; osp->f_bavail = nsp->f_bavail; osp->f_files = nsp->f_files; osp->f_ffree = nsp->f_ffree; osp->f_syncwrites = nsp->f_syncwrites; osp->f_asyncwrites = nsp->f_asyncwrites; osp->f_syncreads = nsp->f_syncreads; osp->f_asyncreads = nsp->f_asyncreads; osp->f_namemax = nsp->f_namemax; osp->f_owner = nsp->f_owner; osp->f_fsid = nsp->f_fsid; strlcpy(osp->f_fstypename, nsp->f_fstypename, MIN(MFSNAMELEN, sizeof(osp->f_fstypename))); strlcpy(osp->f_mntonname, nsp->f_mntonname, MIN(MNAMELEN, sizeof(osp->f_mntonname))); strlcpy(osp->f_mntfromname, nsp->f_mntfromname, MIN(MNAMELEN, sizeof(osp->f_mntfromname))); } #endif /* COMPAT_FREEBSD11 */ /* * Change current working directory to a given file descriptor. */ #ifndef _SYS_SYSPROTO_H_ struct fchdir_args { int fd; }; #endif int sys_fchdir(struct thread *td, struct fchdir_args *uap) { struct vnode *vp, *tdp; struct mount *mp; struct file *fp; int error; AUDIT_ARG_FD(uap->fd); error = getvnode(td, uap->fd, &cap_fchdir_rights, &fp); if (error != 0) return (error); vp = fp->f_vnode; vrefact(vp); fdrop(fp, td); vn_lock(vp, LK_SHARED | LK_RETRY); AUDIT_ARG_VNODE1(vp); error = change_dir(vp, td); while (!error && (mp = vp->v_mountedhere) != NULL) { if (vfs_busy(mp, 0)) continue; error = VFS_ROOT(mp, LK_SHARED, &tdp); vfs_unbusy(mp); if (error != 0) break; vput(vp); vp = tdp; } if (error != 0) { vput(vp); return (error); } VOP_UNLOCK(vp); pwd_chdir(td, vp); return (0); } /* * Change current working directory (``.''). */ #ifndef _SYS_SYSPROTO_H_ struct chdir_args { char *path; }; #endif int sys_chdir(struct thread *td, struct chdir_args *uap) { return (kern_chdir(td, uap->path, UIO_USERSPACE)); } int kern_chdir(struct thread *td, const char *path, enum uio_seg pathseg) { struct nameidata nd; int error; NDINIT(&nd, LOOKUP, FOLLOW | LOCKSHARED | LOCKLEAF | AUDITVNODE1, pathseg, path, td); if ((error = namei(&nd)) != 0) return (error); if ((error = change_dir(nd.ni_vp, td)) != 0) { vput(nd.ni_vp); NDFREE(&nd, NDF_ONLY_PNBUF); return (error); } VOP_UNLOCK(nd.ni_vp); NDFREE(&nd, NDF_ONLY_PNBUF); pwd_chdir(td, nd.ni_vp); return (0); } /* * Change notion of root (``/'') directory. */ #ifndef _SYS_SYSPROTO_H_ struct chroot_args { char *path; }; #endif int sys_chroot(struct thread *td, struct chroot_args *uap) { struct nameidata nd; int error; error = priv_check(td, PRIV_VFS_CHROOT); if (error != 0) return (error); NDINIT(&nd, LOOKUP, FOLLOW | LOCKSHARED | LOCKLEAF | AUDITVNODE1, UIO_USERSPACE, uap->path, td); error = namei(&nd); if (error != 0) goto error; error = change_dir(nd.ni_vp, td); if (error != 0) goto e_vunlock; #ifdef MAC error = mac_vnode_check_chroot(td->td_ucred, nd.ni_vp); if (error != 0) goto e_vunlock; #endif VOP_UNLOCK(nd.ni_vp); error = pwd_chroot(td, nd.ni_vp); vrele(nd.ni_vp); NDFREE(&nd, NDF_ONLY_PNBUF); return (error); e_vunlock: vput(nd.ni_vp); error: NDFREE(&nd, NDF_ONLY_PNBUF); return (error); } /* * Common routine for chroot and chdir. Callers must provide a locked vnode * instance. */ int change_dir(struct vnode *vp, struct thread *td) { #ifdef MAC int error; #endif ASSERT_VOP_LOCKED(vp, "change_dir(): vp not locked"); if (vp->v_type != VDIR) return (ENOTDIR); #ifdef MAC error = mac_vnode_check_chdir(td->td_ucred, vp); if (error != 0) return (error); #endif return (VOP_ACCESS(vp, VEXEC, td->td_ucred, td)); } static __inline void flags_to_rights(int flags, cap_rights_t *rightsp) { if (flags & O_EXEC) { cap_rights_set_one(rightsp, CAP_FEXECVE); } else { switch ((flags & O_ACCMODE)) { case O_RDONLY: cap_rights_set_one(rightsp, CAP_READ); break; case O_RDWR: cap_rights_set_one(rightsp, CAP_READ); /* FALLTHROUGH */ case O_WRONLY: cap_rights_set_one(rightsp, CAP_WRITE); if (!(flags & (O_APPEND | O_TRUNC))) cap_rights_set_one(rightsp, CAP_SEEK); break; } } if (flags & O_CREAT) cap_rights_set_one(rightsp, CAP_CREATE); if (flags & O_TRUNC) cap_rights_set_one(rightsp, CAP_FTRUNCATE); if (flags & (O_SYNC | O_FSYNC)) cap_rights_set_one(rightsp, CAP_FSYNC); if (flags & (O_EXLOCK | O_SHLOCK)) cap_rights_set_one(rightsp, CAP_FLOCK); } /* * Check permissions, allocate an open file structure, and call the device * open routine if any. */ #ifndef _SYS_SYSPROTO_H_ struct open_args { char *path; int flags; int mode; }; #endif int sys_open(struct thread *td, struct open_args *uap) { return (kern_openat(td, AT_FDCWD, uap->path, UIO_USERSPACE, uap->flags, uap->mode)); } #ifndef _SYS_SYSPROTO_H_ struct openat_args { int fd; char *path; int flag; int mode; }; #endif int sys_openat(struct thread *td, struct openat_args *uap) { AUDIT_ARG_FD(uap->fd); return (kern_openat(td, uap->fd, uap->path, UIO_USERSPACE, uap->flag, uap->mode)); } int kern_openat(struct thread *td, int fd, const char *path, enum uio_seg pathseg, int flags, int mode) { struct proc *p = td->td_proc; struct filedesc *fdp = p->p_fd; struct file *fp; struct vnode *vp; struct nameidata nd; cap_rights_t rights; int cmode, error, indx; indx = -1; AUDIT_ARG_FFLAGS(flags); AUDIT_ARG_MODE(mode); cap_rights_init_one(&rights, CAP_LOOKUP); flags_to_rights(flags, &rights); /* * Only one of the O_EXEC, O_RDONLY, O_WRONLY and O_RDWR flags * may be specified. */ if (flags & O_EXEC) { if (flags & O_ACCMODE) return (EINVAL); } else if ((flags & O_ACCMODE) == O_ACCMODE) { return (EINVAL); } else { flags = FFLAGS(flags); } /* * Allocate a file structure. The descriptor to reference it * is allocated and set by finstall() below. */ error = falloc_noinstall(td, &fp); if (error != 0) return (error); /* * An extra reference on `fp' has been held for us by * falloc_noinstall(). */ /* Set the flags early so the finit in devfs can pick them up. */ fp->f_flag = flags & FMASK; cmode = ((mode & ~fdp->fd_cmask) & ALLPERMS) & ~S_ISTXT; NDINIT_ATRIGHTS(&nd, LOOKUP, FOLLOW | AUDITVNODE1, pathseg, path, fd, &rights, td); td->td_dupfd = -1; /* XXX check for fdopen */ error = vn_open(&nd, &flags, cmode, fp); if (error != 0) { /* * If the vn_open replaced the method vector, something * wonderous happened deep below and we just pass it up * pretending we know what we do. */ if (error == ENXIO && fp->f_ops != &badfileops) goto success; /* * Handle special fdopen() case. bleh. * * Don't do this for relative (capability) lookups; we don't * understand exactly what would happen, and we don't think * that it ever should. */ if ((nd.ni_resflags & NIRES_STRICTREL) == 0 && (error == ENODEV || error == ENXIO) && td->td_dupfd >= 0) { error = dupfdopen(td, fdp, td->td_dupfd, flags, error, &indx); if (error == 0) goto success; } goto bad; } td->td_dupfd = 0; NDFREE(&nd, NDF_ONLY_PNBUF); vp = nd.ni_vp; /* * Store the vnode, for any f_type. Typically, the vnode use * count is decremented by direct call to vn_closefile() for * files that switched type in the cdevsw fdopen() method. */ fp->f_vnode = vp; /* * If the file wasn't claimed by devfs bind it to the normal * vnode operations here. */ if (fp->f_ops == &badfileops) { KASSERT(vp->v_type != VFIFO, ("Unexpected fifo.")); finit_vnode(fp, flags, NULL, &vnops); } VOP_UNLOCK(vp); if (flags & O_TRUNC) { error = fo_truncate(fp, 0, td->td_ucred, td); if (error != 0) goto bad; } success: /* * If we haven't already installed the FD (for dupfdopen), do so now. */ if (indx == -1) { struct filecaps *fcaps; #ifdef CAPABILITIES if ((nd.ni_resflags & NIRES_STRICTREL) != 0) fcaps = &nd.ni_filecaps; else #endif fcaps = NULL; error = finstall(td, fp, &indx, flags, fcaps); /* On success finstall() consumes fcaps. */ if (error != 0) { filecaps_free(&nd.ni_filecaps); goto bad; } } else { filecaps_free(&nd.ni_filecaps); } /* * Release our private reference, leaving the one associated with * the descriptor table intact. */ fdrop(fp, td); td->td_retval[0] = indx; return (0); bad: KASSERT(indx == -1, ("indx=%d, should be -1", indx)); fdrop(fp, td); return (error); } #ifdef COMPAT_43 /* * Create a file. */ #ifndef _SYS_SYSPROTO_H_ struct ocreat_args { char *path; int mode; }; #endif int ocreat(struct thread *td, struct ocreat_args *uap) { return (kern_openat(td, AT_FDCWD, uap->path, UIO_USERSPACE, O_WRONLY | O_CREAT | O_TRUNC, uap->mode)); } #endif /* COMPAT_43 */ /* * Create a special file. */ #ifndef _SYS_SYSPROTO_H_ struct mknodat_args { int fd; char *path; mode_t mode; dev_t dev; }; #endif int sys_mknodat(struct thread *td, struct mknodat_args *uap) { return (kern_mknodat(td, uap->fd, uap->path, UIO_USERSPACE, uap->mode, uap->dev)); } #if defined(COMPAT_FREEBSD11) int freebsd11_mknod(struct thread *td, struct freebsd11_mknod_args *uap) { return (kern_mknodat(td, AT_FDCWD, uap->path, UIO_USERSPACE, uap->mode, uap->dev)); } int freebsd11_mknodat(struct thread *td, struct freebsd11_mknodat_args *uap) { return (kern_mknodat(td, uap->fd, uap->path, UIO_USERSPACE, uap->mode, uap->dev)); } #endif /* COMPAT_FREEBSD11 */ int kern_mknodat(struct thread *td, int fd, const char *path, enum uio_seg pathseg, int mode, dev_t dev) { struct vnode *vp; struct mount *mp; struct vattr vattr; struct nameidata nd; int error, whiteout = 0; AUDIT_ARG_MODE(mode); AUDIT_ARG_DEV(dev); switch (mode & S_IFMT) { case S_IFCHR: case S_IFBLK: error = priv_check(td, PRIV_VFS_MKNOD_DEV); if (error == 0 && dev == VNOVAL) error = EINVAL; break; case S_IFWHT: error = priv_check(td, PRIV_VFS_MKNOD_WHT); break; case S_IFIFO: if (dev == 0) return (kern_mkfifoat(td, fd, path, pathseg, mode)); /* FALLTHROUGH */ default: error = EINVAL; break; } if (error != 0) return (error); restart: bwillwrite(); NDINIT_ATRIGHTS(&nd, CREATE, LOCKPARENT | SAVENAME | AUDITVNODE1 | NOCACHE, pathseg, path, fd, &cap_mknodat_rights, td); if ((error = namei(&nd)) != 0) return (error); vp = nd.ni_vp; if (vp != NULL) { NDFREE(&nd, NDF_ONLY_PNBUF); if (vp == nd.ni_dvp) vrele(nd.ni_dvp); else vput(nd.ni_dvp); vrele(vp); return (EEXIST); } else { VATTR_NULL(&vattr); vattr.va_mode = (mode & ALLPERMS) & ~td->td_proc->p_fd->fd_cmask; vattr.va_rdev = dev; whiteout = 0; switch (mode & S_IFMT) { case S_IFCHR: vattr.va_type = VCHR; break; case S_IFBLK: vattr.va_type = VBLK; break; case S_IFWHT: whiteout = 1; break; default: panic("kern_mknod: invalid mode"); } } if (vn_start_write(nd.ni_dvp, &mp, V_NOWAIT) != 0) { NDFREE(&nd, NDF_ONLY_PNBUF); vput(nd.ni_dvp); if ((error = vn_start_write(NULL, &mp, V_XSLEEP | PCATCH)) != 0) return (error); goto restart; } #ifdef MAC if (error == 0 && !whiteout) error = mac_vnode_check_create(td->td_ucred, nd.ni_dvp, &nd.ni_cnd, &vattr); #endif if (error == 0) { if (whiteout) error = VOP_WHITEOUT(nd.ni_dvp, &nd.ni_cnd, CREATE); else { error = VOP_MKNOD(nd.ni_dvp, &nd.ni_vp, &nd.ni_cnd, &vattr); if (error == 0) vput(nd.ni_vp); } } NDFREE(&nd, NDF_ONLY_PNBUF); vput(nd.ni_dvp); vn_finished_write(mp); if (error == ERELOOKUP) goto restart; return (error); } /* * Create a named pipe. */ #ifndef _SYS_SYSPROTO_H_ struct mkfifo_args { char *path; int mode; }; #endif int sys_mkfifo(struct thread *td, struct mkfifo_args *uap) { return (kern_mkfifoat(td, AT_FDCWD, uap->path, UIO_USERSPACE, uap->mode)); } #ifndef _SYS_SYSPROTO_H_ struct mkfifoat_args { int fd; char *path; mode_t mode; }; #endif int sys_mkfifoat(struct thread *td, struct mkfifoat_args *uap) { return (kern_mkfifoat(td, uap->fd, uap->path, UIO_USERSPACE, uap->mode)); } int kern_mkfifoat(struct thread *td, int fd, const char *path, enum uio_seg pathseg, int mode) { struct mount *mp; struct vattr vattr; struct nameidata nd; int error; AUDIT_ARG_MODE(mode); restart: bwillwrite(); NDINIT_ATRIGHTS(&nd, CREATE, LOCKPARENT | SAVENAME | AUDITVNODE1 | NOCACHE, pathseg, path, fd, &cap_mkfifoat_rights, td); if ((error = namei(&nd)) != 0) return (error); if (nd.ni_vp != NULL) { NDFREE(&nd, NDF_ONLY_PNBUF); if (nd.ni_vp == nd.ni_dvp) vrele(nd.ni_dvp); else vput(nd.ni_dvp); vrele(nd.ni_vp); return (EEXIST); } if (vn_start_write(nd.ni_dvp, &mp, V_NOWAIT) != 0) { NDFREE(&nd, NDF_ONLY_PNBUF); vput(nd.ni_dvp); if ((error = vn_start_write(NULL, &mp, V_XSLEEP | PCATCH)) != 0) return (error); goto restart; } VATTR_NULL(&vattr); vattr.va_type = VFIFO; vattr.va_mode = (mode & ALLPERMS) & ~td->td_proc->p_fd->fd_cmask; #ifdef MAC error = mac_vnode_check_create(td->td_ucred, nd.ni_dvp, &nd.ni_cnd, &vattr); if (error != 0) goto out; #endif error = VOP_MKNOD(nd.ni_dvp, &nd.ni_vp, &nd.ni_cnd, &vattr); if (error == 0) vput(nd.ni_vp); #ifdef MAC out: #endif vput(nd.ni_dvp); vn_finished_write(mp); NDFREE(&nd, NDF_ONLY_PNBUF); if (error == ERELOOKUP) goto restart; return (error); } /* * Make a hard file link. */ #ifndef _SYS_SYSPROTO_H_ struct link_args { char *path; char *link; }; #endif int sys_link(struct thread *td, struct link_args *uap) { return (kern_linkat(td, AT_FDCWD, AT_FDCWD, uap->path, uap->link, UIO_USERSPACE, FOLLOW)); } #ifndef _SYS_SYSPROTO_H_ struct linkat_args { int fd1; char *path1; int fd2; char *path2; int flag; }; #endif int sys_linkat(struct thread *td, struct linkat_args *uap) { int flag; flag = uap->flag; if ((flag & ~(AT_SYMLINK_FOLLOW | AT_BENEATH | AT_RESOLVE_BENEATH)) != 0) return (EINVAL); return (kern_linkat(td, uap->fd1, uap->fd2, uap->path1, uap->path2, UIO_USERSPACE, at2cnpflags(flag, AT_SYMLINK_FOLLOW | AT_BENEATH | AT_RESOLVE_BENEATH))); } int hardlink_check_uid = 0; SYSCTL_INT(_security_bsd, OID_AUTO, hardlink_check_uid, CTLFLAG_RW, &hardlink_check_uid, 0, "Unprivileged processes cannot create hard links to files owned by other " "users"); static int hardlink_check_gid = 0; SYSCTL_INT(_security_bsd, OID_AUTO, hardlink_check_gid, CTLFLAG_RW, &hardlink_check_gid, 0, "Unprivileged processes cannot create hard links to files owned by other " "groups"); static int can_hardlink(struct vnode *vp, struct ucred *cred) { struct vattr va; int error; if (!hardlink_check_uid && !hardlink_check_gid) return (0); error = VOP_GETATTR(vp, &va, cred); if (error != 0) return (error); if (hardlink_check_uid && cred->cr_uid != va.va_uid) { error = priv_check_cred(cred, PRIV_VFS_LINK); if (error != 0) return (error); } if (hardlink_check_gid && !groupmember(va.va_gid, cred)) { error = priv_check_cred(cred, PRIV_VFS_LINK); if (error != 0) return (error); } return (0); } int kern_linkat(struct thread *td, int fd1, int fd2, const char *path1, const char *path2, enum uio_seg segflag, int follow) { struct nameidata nd; int error; do { bwillwrite(); NDINIT_ATRIGHTS(&nd, LOOKUP, follow | AUDITVNODE1, segflag, path1, fd1, &cap_linkat_source_rights, td); if ((error = namei(&nd)) != 0) return (error); NDFREE(&nd, NDF_ONLY_PNBUF); error = kern_linkat_vp(td, nd.ni_vp, fd2, path2, segflag); } while (error == EAGAIN || error == ERELOOKUP); return (error); } static int kern_linkat_vp(struct thread *td, struct vnode *vp, int fd, const char *path, enum uio_seg segflag) { struct nameidata nd; struct mount *mp; int error; if (vp->v_type == VDIR) { vrele(vp); return (EPERM); /* POSIX */ } NDINIT_ATRIGHTS(&nd, CREATE, LOCKPARENT | SAVENAME | AUDITVNODE2 | NOCACHE, segflag, path, fd, &cap_linkat_target_rights, td); if ((error = namei(&nd)) == 0) { if (nd.ni_vp != NULL) { NDFREE(&nd, NDF_ONLY_PNBUF); if (nd.ni_dvp == nd.ni_vp) vrele(nd.ni_dvp); else vput(nd.ni_dvp); vrele(nd.ni_vp); vrele(vp); return (EEXIST); } else if (nd.ni_dvp->v_mount != vp->v_mount) { /* * Cross-device link. No need to recheck * vp->v_type, since it cannot change, except * to VBAD. */ NDFREE(&nd, NDF_ONLY_PNBUF); vput(nd.ni_dvp); vrele(vp); return (EXDEV); } else if ((error = vn_lock(vp, LK_EXCLUSIVE)) == 0) { error = can_hardlink(vp, td->td_ucred); #ifdef MAC if (error == 0) error = mac_vnode_check_link(td->td_ucred, nd.ni_dvp, vp, &nd.ni_cnd); #endif if (error != 0) { vput(vp); vput(nd.ni_dvp); NDFREE(&nd, NDF_ONLY_PNBUF); return (error); } error = vn_start_write(vp, &mp, V_NOWAIT); if (error != 0) { vput(vp); vput(nd.ni_dvp); NDFREE(&nd, NDF_ONLY_PNBUF); error = vn_start_write(NULL, &mp, V_XSLEEP | PCATCH); if (error != 0) return (error); return (EAGAIN); } error = VOP_LINK(nd.ni_dvp, vp, &nd.ni_cnd); VOP_UNLOCK(vp); vput(nd.ni_dvp); vn_finished_write(mp); NDFREE(&nd, NDF_ONLY_PNBUF); } else { vput(nd.ni_dvp); NDFREE(&nd, NDF_ONLY_PNBUF); vrele(vp); return (EAGAIN); } } vrele(vp); return (error); } /* * Make a symbolic link. */ #ifndef _SYS_SYSPROTO_H_ struct symlink_args { char *path; char *link; }; #endif int sys_symlink(struct thread *td, struct symlink_args *uap) { return (kern_symlinkat(td, uap->path, AT_FDCWD, uap->link, UIO_USERSPACE)); } #ifndef _SYS_SYSPROTO_H_ struct symlinkat_args { char *path; int fd; char *path2; }; #endif int sys_symlinkat(struct thread *td, struct symlinkat_args *uap) { return (kern_symlinkat(td, uap->path1, uap->fd, uap->path2, UIO_USERSPACE)); } int kern_symlinkat(struct thread *td, const char *path1, int fd, const char *path2, enum uio_seg segflg) { struct mount *mp; struct vattr vattr; const char *syspath; char *tmppath; struct nameidata nd; int error; if (segflg == UIO_SYSSPACE) { syspath = path1; } else { tmppath = uma_zalloc(namei_zone, M_WAITOK); if ((error = copyinstr(path1, tmppath, MAXPATHLEN, NULL)) != 0) goto out; syspath = tmppath; } AUDIT_ARG_TEXT(syspath); restart: bwillwrite(); NDINIT_ATRIGHTS(&nd, CREATE, LOCKPARENT | SAVENAME | AUDITVNODE1 | NOCACHE, segflg, path2, fd, &cap_symlinkat_rights, td); if ((error = namei(&nd)) != 0) goto out; if (nd.ni_vp) { NDFREE(&nd, NDF_ONLY_PNBUF); if (nd.ni_vp == nd.ni_dvp) vrele(nd.ni_dvp); else vput(nd.ni_dvp); vrele(nd.ni_vp); error = EEXIST; goto out; } if (vn_start_write(nd.ni_dvp, &mp, V_NOWAIT) != 0) { NDFREE(&nd, NDF_ONLY_PNBUF); vput(nd.ni_dvp); if ((error = vn_start_write(NULL, &mp, V_XSLEEP | PCATCH)) != 0) goto out; goto restart; } VATTR_NULL(&vattr); vattr.va_mode = ACCESSPERMS &~ td->td_proc->p_fd->fd_cmask; #ifdef MAC vattr.va_type = VLNK; error = mac_vnode_check_create(td->td_ucred, nd.ni_dvp, &nd.ni_cnd, &vattr); if (error != 0) goto out2; #endif error = VOP_SYMLINK(nd.ni_dvp, &nd.ni_vp, &nd.ni_cnd, &vattr, syspath); if (error == 0) vput(nd.ni_vp); #ifdef MAC out2: #endif NDFREE(&nd, NDF_ONLY_PNBUF); vput(nd.ni_dvp); vn_finished_write(mp); if (error == ERELOOKUP) goto restart; out: if (segflg != UIO_SYSSPACE) uma_zfree(namei_zone, tmppath); return (error); } /* * Delete a whiteout from the filesystem. */ #ifndef _SYS_SYSPROTO_H_ struct undelete_args { char *path; }; #endif int sys_undelete(struct thread *td, struct undelete_args *uap) { struct mount *mp; struct nameidata nd; int error; restart: bwillwrite(); NDINIT(&nd, DELETE, LOCKPARENT | DOWHITEOUT | AUDITVNODE1, UIO_USERSPACE, uap->path, td); error = namei(&nd); if (error != 0) return (error); if (nd.ni_vp != NULLVP || !(nd.ni_cnd.cn_flags & ISWHITEOUT)) { NDFREE(&nd, NDF_ONLY_PNBUF); if (nd.ni_vp == nd.ni_dvp) vrele(nd.ni_dvp); else vput(nd.ni_dvp); if (nd.ni_vp) vrele(nd.ni_vp); return (EEXIST); } if (vn_start_write(nd.ni_dvp, &mp, V_NOWAIT) != 0) { NDFREE(&nd, NDF_ONLY_PNBUF); vput(nd.ni_dvp); if ((error = vn_start_write(NULL, &mp, V_XSLEEP | PCATCH)) != 0) return (error); goto restart; } error = VOP_WHITEOUT(nd.ni_dvp, &nd.ni_cnd, DELETE); NDFREE(&nd, NDF_ONLY_PNBUF); vput(nd.ni_dvp); vn_finished_write(mp); if (error == ERELOOKUP) goto restart; return (error); } /* * Delete a name from the filesystem. */ #ifndef _SYS_SYSPROTO_H_ struct unlink_args { char *path; }; #endif int sys_unlink(struct thread *td, struct unlink_args *uap) { return (kern_funlinkat(td, AT_FDCWD, uap->path, FD_NONE, UIO_USERSPACE, 0, 0)); } static int kern_funlinkat_ex(struct thread *td, int dfd, const char *path, int fd, int flag, enum uio_seg pathseg, ino_t oldinum) { if ((flag & ~AT_REMOVEDIR) != 0) return (EINVAL); if ((flag & AT_REMOVEDIR) != 0) return (kern_frmdirat(td, dfd, path, fd, UIO_USERSPACE, 0)); return (kern_funlinkat(td, dfd, path, fd, UIO_USERSPACE, 0, 0)); } #ifndef _SYS_SYSPROTO_H_ struct unlinkat_args { int fd; char *path; int flag; }; #endif int sys_unlinkat(struct thread *td, struct unlinkat_args *uap) { return (kern_funlinkat_ex(td, uap->fd, uap->path, FD_NONE, uap->flag, UIO_USERSPACE, 0)); } #ifndef _SYS_SYSPROTO_H_ struct funlinkat_args { int dfd; const char *path; int fd; int flag; }; #endif int sys_funlinkat(struct thread *td, struct funlinkat_args *uap) { return (kern_funlinkat_ex(td, uap->dfd, uap->path, uap->fd, uap->flag, UIO_USERSPACE, 0)); } int kern_funlinkat(struct thread *td, int dfd, const char *path, int fd, enum uio_seg pathseg, int flag, ino_t oldinum) { struct mount *mp; struct file *fp; struct vnode *vp; struct nameidata nd; struct stat sb; int error; fp = NULL; if (fd != FD_NONE) { error = getvnode(td, fd, &cap_no_rights, &fp); if (error != 0) return (error); } restart: bwillwrite(); NDINIT_ATRIGHTS(&nd, DELETE, LOCKPARENT | LOCKLEAF | AUDITVNODE1 | at2cnpflags(flag, AT_BENEATH | AT_RESOLVE_BENEATH), pathseg, path, dfd, &cap_unlinkat_rights, td); if ((error = namei(&nd)) != 0) { if (error == EINVAL) error = EPERM; goto fdout; } vp = nd.ni_vp; if (vp->v_type == VDIR && oldinum == 0) { error = EPERM; /* POSIX */ } else if (oldinum != 0 && ((error = VOP_STAT(vp, &sb, td->td_ucred, NOCRED, td)) == 0) && sb.st_ino != oldinum) { error = EIDRM; /* Identifier removed */ } else if (fp != NULL && fp->f_vnode != vp) { if (VN_IS_DOOMED(fp->f_vnode)) error = EBADF; else error = EDEADLK; } else { /* * The root of a mounted filesystem cannot be deleted. * * XXX: can this only be a VDIR case? */ if (vp->v_vflag & VV_ROOT) error = EBUSY; } if (error == 0) { if (vn_start_write(nd.ni_dvp, &mp, V_NOWAIT) != 0) { NDFREE(&nd, NDF_ONLY_PNBUF); vput(nd.ni_dvp); if (vp == nd.ni_dvp) vrele(vp); else vput(vp); if ((error = vn_start_write(NULL, &mp, V_XSLEEP | PCATCH)) != 0) { goto fdout; } goto restart; } #ifdef MAC error = mac_vnode_check_unlink(td->td_ucred, nd.ni_dvp, vp, &nd.ni_cnd); if (error != 0) goto out; #endif vfs_notify_upper(vp, VFS_NOTIFY_UPPER_UNLINK); error = VOP_REMOVE(nd.ni_dvp, vp, &nd.ni_cnd); #ifdef MAC out: #endif vn_finished_write(mp); } NDFREE(&nd, NDF_ONLY_PNBUF); vput(nd.ni_dvp); if (vp == nd.ni_dvp) vrele(vp); else vput(vp); if (error == ERELOOKUP) goto restart; fdout: if (fp != NULL) fdrop(fp, td); return (error); } /* * Reposition read/write file offset. */ #ifndef _SYS_SYSPROTO_H_ struct lseek_args { int fd; int pad; off_t offset; int whence; }; #endif int sys_lseek(struct thread *td, struct lseek_args *uap) { return (kern_lseek(td, uap->fd, uap->offset, uap->whence)); } int kern_lseek(struct thread *td, int fd, off_t offset, int whence) { struct file *fp; int error; AUDIT_ARG_FD(fd); error = fget(td, fd, &cap_seek_rights, &fp); if (error != 0) return (error); error = (fp->f_ops->fo_flags & DFLAG_SEEKABLE) != 0 ? fo_seek(fp, offset, whence, td) : ESPIPE; fdrop(fp, td); return (error); } #if defined(COMPAT_43) /* * Reposition read/write file offset. */ #ifndef _SYS_SYSPROTO_H_ struct olseek_args { int fd; long offset; int whence; }; #endif int olseek(struct thread *td, struct olseek_args *uap) { return (kern_lseek(td, uap->fd, uap->offset, uap->whence)); } #endif /* COMPAT_43 */ #if defined(COMPAT_FREEBSD6) /* Version with the 'pad' argument */ int freebsd6_lseek(struct thread *td, struct freebsd6_lseek_args *uap) { return (kern_lseek(td, uap->fd, uap->offset, uap->whence)); } #endif /* * Check access permissions using passed credentials. */ static int vn_access(struct vnode *vp, int user_flags, struct ucred *cred, struct thread *td) { accmode_t accmode; int error; /* Flags == 0 means only check for existence. */ if (user_flags == 0) return (0); accmode = 0; if (user_flags & R_OK) accmode |= VREAD; if (user_flags & W_OK) accmode |= VWRITE; if (user_flags & X_OK) accmode |= VEXEC; #ifdef MAC error = mac_vnode_check_access(cred, vp, accmode); if (error != 0) return (error); #endif if ((accmode & VWRITE) == 0 || (error = vn_writechk(vp)) == 0) error = VOP_ACCESS(vp, accmode, cred, td); return (error); } /* * Check access permissions using "real" credentials. */ #ifndef _SYS_SYSPROTO_H_ struct access_args { char *path; int amode; }; #endif int sys_access(struct thread *td, struct access_args *uap) { return (kern_accessat(td, AT_FDCWD, uap->path, UIO_USERSPACE, 0, uap->amode)); } #ifndef _SYS_SYSPROTO_H_ struct faccessat_args { int dirfd; char *path; int amode; int flag; } #endif int sys_faccessat(struct thread *td, struct faccessat_args *uap) { return (kern_accessat(td, uap->fd, uap->path, UIO_USERSPACE, uap->flag, uap->amode)); } int kern_accessat(struct thread *td, int fd, const char *path, enum uio_seg pathseg, int flag, int amode) { struct ucred *cred, *usecred; struct vnode *vp; struct nameidata nd; int error; if ((flag & ~(AT_EACCESS | AT_BENEATH | AT_RESOLVE_BENEATH)) != 0) return (EINVAL); if (amode != F_OK && (amode & ~(R_OK | W_OK | X_OK)) != 0) return (EINVAL); /* * Create and modify a temporary credential instead of one that * is potentially shared (if we need one). */ cred = td->td_ucred; if ((flag & AT_EACCESS) == 0 && ((cred->cr_uid != cred->cr_ruid || cred->cr_rgid != cred->cr_groups[0]))) { usecred = crdup(cred); usecred->cr_uid = cred->cr_ruid; usecred->cr_groups[0] = cred->cr_rgid; td->td_ucred = usecred; } else usecred = cred; AUDIT_ARG_VALUE(amode); NDINIT_ATRIGHTS(&nd, LOOKUP, FOLLOW | LOCKSHARED | LOCKLEAF | AUDITVNODE1 | at2cnpflags(flag, AT_BENEATH | AT_RESOLVE_BENEATH), pathseg, path, fd, &cap_fstat_rights, td); if ((error = namei(&nd)) != 0) goto out; vp = nd.ni_vp; error = vn_access(vp, amode, usecred, td); NDFREE(&nd, NDF_ONLY_PNBUF); vput(vp); out: if (usecred != cred) { td->td_ucred = cred; crfree(usecred); } return (error); } /* * Check access permissions using "effective" credentials. */ #ifndef _SYS_SYSPROTO_H_ struct eaccess_args { char *path; int amode; }; #endif int sys_eaccess(struct thread *td, struct eaccess_args *uap) { return (kern_accessat(td, AT_FDCWD, uap->path, UIO_USERSPACE, AT_EACCESS, uap->amode)); } #if defined(COMPAT_43) /* * Get file status; this version follows links. */ #ifndef _SYS_SYSPROTO_H_ struct ostat_args { char *path; struct ostat *ub; }; #endif int ostat(struct thread *td, struct ostat_args *uap) { struct stat sb; struct ostat osb; int error; error = kern_statat(td, 0, AT_FDCWD, uap->path, UIO_USERSPACE, &sb, NULL); if (error != 0) return (error); cvtstat(&sb, &osb); return (copyout(&osb, uap->ub, sizeof (osb))); } /* * Get file status; this version does not follow links. */ #ifndef _SYS_SYSPROTO_H_ struct olstat_args { char *path; struct ostat *ub; }; #endif int olstat(struct thread *td, struct olstat_args *uap) { struct stat sb; struct ostat osb; int error; error = kern_statat(td, AT_SYMLINK_NOFOLLOW, AT_FDCWD, uap->path, UIO_USERSPACE, &sb, NULL); if (error != 0) return (error); cvtstat(&sb, &osb); return (copyout(&osb, uap->ub, sizeof (osb))); } /* * Convert from an old to a new stat structure. * XXX: many values are blindly truncated. */ void cvtstat(struct stat *st, struct ostat *ost) { bzero(ost, sizeof(*ost)); ost->st_dev = st->st_dev; ost->st_ino = st->st_ino; ost->st_mode = st->st_mode; ost->st_nlink = st->st_nlink; ost->st_uid = st->st_uid; ost->st_gid = st->st_gid; ost->st_rdev = st->st_rdev; ost->st_size = MIN(st->st_size, INT32_MAX); ost->st_atim = st->st_atim; ost->st_mtim = st->st_mtim; ost->st_ctim = st->st_ctim; ost->st_blksize = st->st_blksize; ost->st_blocks = st->st_blocks; ost->st_flags = st->st_flags; ost->st_gen = st->st_gen; } #endif /* COMPAT_43 */ #if defined(COMPAT_43) || defined(COMPAT_FREEBSD11) int ino64_trunc_error; SYSCTL_INT(_vfs, OID_AUTO, ino64_trunc_error, CTLFLAG_RW, &ino64_trunc_error, 0, "Error on truncation of device, file or inode number, or link count"); int freebsd11_cvtstat(struct stat *st, struct freebsd11_stat *ost) { ost->st_dev = st->st_dev; if (ost->st_dev != st->st_dev) { switch (ino64_trunc_error) { default: /* * Since dev_t is almost raw, don't clamp to the * maximum for case 2, but ignore the error. */ break; case 1: return (EOVERFLOW); } } ost->st_ino = st->st_ino; if (ost->st_ino != st->st_ino) { switch (ino64_trunc_error) { default: case 0: break; case 1: return (EOVERFLOW); case 2: ost->st_ino = UINT32_MAX; break; } } ost->st_mode = st->st_mode; ost->st_nlink = st->st_nlink; if (ost->st_nlink != st->st_nlink) { switch (ino64_trunc_error) { default: case 0: break; case 1: return (EOVERFLOW); case 2: ost->st_nlink = UINT16_MAX; break; } } ost->st_uid = st->st_uid; ost->st_gid = st->st_gid; ost->st_rdev = st->st_rdev; if (ost->st_rdev != st->st_rdev) { switch (ino64_trunc_error) { default: break; case 1: return (EOVERFLOW); } } ost->st_atim = st->st_atim; ost->st_mtim = st->st_mtim; ost->st_ctim = st->st_ctim; ost->st_size = st->st_size; ost->st_blocks = st->st_blocks; ost->st_blksize = st->st_blksize; ost->st_flags = st->st_flags; ost->st_gen = st->st_gen; ost->st_lspare = 0; ost->st_birthtim = st->st_birthtim; bzero((char *)&ost->st_birthtim + sizeof(ost->st_birthtim), sizeof(*ost) - offsetof(struct freebsd11_stat, st_birthtim) - sizeof(ost->st_birthtim)); return (0); } int freebsd11_stat(struct thread *td, struct freebsd11_stat_args* uap) { struct stat sb; struct freebsd11_stat osb; int error; error = kern_statat(td, 0, AT_FDCWD, uap->path, UIO_USERSPACE, &sb, NULL); if (error != 0) return (error); error = freebsd11_cvtstat(&sb, &osb); if (error == 0) error = copyout(&osb, uap->ub, sizeof(osb)); return (error); } int freebsd11_lstat(struct thread *td, struct freebsd11_lstat_args* uap) { struct stat sb; struct freebsd11_stat osb; int error; error = kern_statat(td, AT_SYMLINK_NOFOLLOW, AT_FDCWD, uap->path, UIO_USERSPACE, &sb, NULL); if (error != 0) return (error); error = freebsd11_cvtstat(&sb, &osb); if (error == 0) error = copyout(&osb, uap->ub, sizeof(osb)); return (error); } int freebsd11_fhstat(struct thread *td, struct freebsd11_fhstat_args* uap) { struct fhandle fh; struct stat sb; struct freebsd11_stat osb; int error; error = copyin(uap->u_fhp, &fh, sizeof(fhandle_t)); if (error != 0) return (error); error = kern_fhstat(td, fh, &sb); if (error != 0) return (error); error = freebsd11_cvtstat(&sb, &osb); if (error == 0) error = copyout(&osb, uap->sb, sizeof(osb)); return (error); } int freebsd11_fstatat(struct thread *td, struct freebsd11_fstatat_args* uap) { struct stat sb; struct freebsd11_stat osb; int error; error = kern_statat(td, uap->flag, uap->fd, uap->path, UIO_USERSPACE, &sb, NULL); if (error != 0) return (error); error = freebsd11_cvtstat(&sb, &osb); if (error == 0) error = copyout(&osb, uap->buf, sizeof(osb)); return (error); } #endif /* COMPAT_FREEBSD11 */ /* * Get file status */ #ifndef _SYS_SYSPROTO_H_ struct fstatat_args { int fd; char *path; struct stat *buf; int flag; } #endif int sys_fstatat(struct thread *td, struct fstatat_args *uap) { struct stat sb; int error; error = kern_statat(td, uap->flag, uap->fd, uap->path, UIO_USERSPACE, &sb, NULL); if (error == 0) error = copyout(&sb, uap->buf, sizeof (sb)); return (error); } int kern_statat(struct thread *td, int flag, int fd, const char *path, enum uio_seg pathseg, struct stat *sbp, void (*hook)(struct vnode *vp, struct stat *sbp)) { struct nameidata nd; int error; if ((flag & ~(AT_SYMLINK_NOFOLLOW | AT_BENEATH | AT_RESOLVE_BENEATH)) != 0) return (EINVAL); NDINIT_ATRIGHTS(&nd, LOOKUP, at2cnpflags(flag, AT_BENEATH | AT_RESOLVE_BENEATH | AT_SYMLINK_NOFOLLOW) | LOCKSHARED | LOCKLEAF | AUDITVNODE1, pathseg, path, fd, &cap_fstat_rights, td); if ((error = namei(&nd)) != 0) return (error); error = VOP_STAT(nd.ni_vp, sbp, td->td_ucred, NOCRED, td); if (error == 0) { if (__predict_false(hook != NULL)) hook(nd.ni_vp, sbp); } NDFREE(&nd, NDF_ONLY_PNBUF); vput(nd.ni_vp); #ifdef __STAT_TIME_T_EXT sbp->st_atim_ext = 0; sbp->st_mtim_ext = 0; sbp->st_ctim_ext = 0; sbp->st_btim_ext = 0; #endif #ifdef KTRACE if (KTRPOINT(td, KTR_STRUCT)) ktrstat_error(sbp, error); #endif return (error); } #if defined(COMPAT_FREEBSD11) /* * Implementation of the NetBSD [l]stat() functions. */ void freebsd11_cvtnstat(struct stat *sb, struct nstat *nsb) { bzero(nsb, sizeof(*nsb)); nsb->st_dev = sb->st_dev; nsb->st_ino = sb->st_ino; nsb->st_mode = sb->st_mode; nsb->st_nlink = sb->st_nlink; nsb->st_uid = sb->st_uid; nsb->st_gid = sb->st_gid; nsb->st_rdev = sb->st_rdev; nsb->st_atim = sb->st_atim; nsb->st_mtim = sb->st_mtim; nsb->st_ctim = sb->st_ctim; nsb->st_size = sb->st_size; nsb->st_blocks = sb->st_blocks; nsb->st_blksize = sb->st_blksize; nsb->st_flags = sb->st_flags; nsb->st_gen = sb->st_gen; nsb->st_birthtim = sb->st_birthtim; } #ifndef _SYS_SYSPROTO_H_ struct freebsd11_nstat_args { char *path; struct nstat *ub; }; #endif int freebsd11_nstat(struct thread *td, struct freebsd11_nstat_args *uap) { struct stat sb; struct nstat nsb; int error; error = kern_statat(td, 0, AT_FDCWD, uap->path, UIO_USERSPACE, &sb, NULL); if (error != 0) return (error); freebsd11_cvtnstat(&sb, &nsb); return (copyout(&nsb, uap->ub, sizeof (nsb))); } /* * NetBSD lstat. Get file status; this version does not follow links. */ #ifndef _SYS_SYSPROTO_H_ struct freebsd11_nlstat_args { char *path; struct nstat *ub; }; #endif int freebsd11_nlstat(struct thread *td, struct freebsd11_nlstat_args *uap) { struct stat sb; struct nstat nsb; int error; error = kern_statat(td, AT_SYMLINK_NOFOLLOW, AT_FDCWD, uap->path, UIO_USERSPACE, &sb, NULL); if (error != 0) return (error); freebsd11_cvtnstat(&sb, &nsb); return (copyout(&nsb, uap->ub, sizeof (nsb))); } #endif /* COMPAT_FREEBSD11 */ /* * Get configurable pathname variables. */ #ifndef _SYS_SYSPROTO_H_ struct pathconf_args { char *path; int name; }; #endif int sys_pathconf(struct thread *td, struct pathconf_args *uap) { long value; int error; error = kern_pathconf(td, uap->path, UIO_USERSPACE, uap->name, FOLLOW, &value); if (error == 0) td->td_retval[0] = value; return (error); } #ifndef _SYS_SYSPROTO_H_ struct lpathconf_args { char *path; int name; }; #endif int sys_lpathconf(struct thread *td, struct lpathconf_args *uap) { long value; int error; error = kern_pathconf(td, uap->path, UIO_USERSPACE, uap->name, NOFOLLOW, &value); if (error == 0) td->td_retval[0] = value; return (error); } int kern_pathconf(struct thread *td, const char *path, enum uio_seg pathseg, int name, u_long flags, long *valuep) { struct nameidata nd; int error; NDINIT(&nd, LOOKUP, LOCKSHARED | LOCKLEAF | AUDITVNODE1 | flags, pathseg, path, td); if ((error = namei(&nd)) != 0) return (error); NDFREE(&nd, NDF_ONLY_PNBUF); error = VOP_PATHCONF(nd.ni_vp, name, valuep); vput(nd.ni_vp); return (error); } /* * Return target name of a symbolic link. */ #ifndef _SYS_SYSPROTO_H_ struct readlink_args { char *path; char *buf; size_t count; }; #endif int sys_readlink(struct thread *td, struct readlink_args *uap) { return (kern_readlinkat(td, AT_FDCWD, uap->path, UIO_USERSPACE, uap->buf, UIO_USERSPACE, uap->count)); } #ifndef _SYS_SYSPROTO_H_ struct readlinkat_args { int fd; char *path; char *buf; size_t bufsize; }; #endif int sys_readlinkat(struct thread *td, struct readlinkat_args *uap) { return (kern_readlinkat(td, uap->fd, uap->path, UIO_USERSPACE, uap->buf, UIO_USERSPACE, uap->bufsize)); } int kern_readlinkat(struct thread *td, int fd, const char *path, enum uio_seg pathseg, char *buf, enum uio_seg bufseg, size_t count) { struct vnode *vp; struct nameidata nd; int error; if (count > IOSIZE_MAX) return (EINVAL); NDINIT_AT(&nd, LOOKUP, NOFOLLOW | LOCKSHARED | LOCKLEAF | AUDITVNODE1, pathseg, path, fd, td); if ((error = namei(&nd)) != 0) return (error); NDFREE(&nd, NDF_ONLY_PNBUF); vp = nd.ni_vp; error = kern_readlink_vp(vp, buf, bufseg, count, td); vput(vp); return (error); } /* * Helper function to readlink from a vnode */ static int kern_readlink_vp(struct vnode *vp, char *buf, enum uio_seg bufseg, size_t count, struct thread *td) { struct iovec aiov; struct uio auio; int error; ASSERT_VOP_LOCKED(vp, "kern_readlink_vp(): vp not locked"); #ifdef MAC error = mac_vnode_check_readlink(td->td_ucred, vp); if (error != 0) return (error); #endif if (vp->v_type != VLNK && (vp->v_vflag & VV_READLINK) == 0) return (EINVAL); aiov.iov_base = buf; aiov.iov_len = count; auio.uio_iov = &aiov; auio.uio_iovcnt = 1; auio.uio_offset = 0; auio.uio_rw = UIO_READ; auio.uio_segflg = bufseg; auio.uio_td = td; auio.uio_resid = count; error = VOP_READLINK(vp, &auio, td->td_ucred); td->td_retval[0] = count - auio.uio_resid; return (error); } /* * Common implementation code for chflags() and fchflags(). */ static int setfflags(struct thread *td, struct vnode *vp, u_long flags) { struct mount *mp; struct vattr vattr; int error; /* We can't support the value matching VNOVAL. */ if (flags == VNOVAL) return (EOPNOTSUPP); /* * Prevent non-root users from setting flags on devices. When * a device is reused, users can retain ownership of the device * if they are allowed to set flags and programs assume that * chown can't fail when done as root. */ if (vp->v_type == VCHR || vp->v_type == VBLK) { error = priv_check(td, PRIV_VFS_CHFLAGS_DEV); if (error != 0) return (error); } if ((error = vn_start_write(vp, &mp, V_WAIT | PCATCH)) != 0) return (error); VATTR_NULL(&vattr); vattr.va_flags = flags; vn_lock(vp, LK_EXCLUSIVE | LK_RETRY); #ifdef MAC error = mac_vnode_check_setflags(td->td_ucred, vp, vattr.va_flags); if (error == 0) #endif error = VOP_SETATTR(vp, &vattr, td->td_ucred); VOP_UNLOCK(vp); vn_finished_write(mp); return (error); } /* * Change flags of a file given a path name. */ #ifndef _SYS_SYSPROTO_H_ struct chflags_args { const char *path; u_long flags; }; #endif int sys_chflags(struct thread *td, struct chflags_args *uap) { return (kern_chflagsat(td, AT_FDCWD, uap->path, UIO_USERSPACE, uap->flags, 0)); } #ifndef _SYS_SYSPROTO_H_ struct chflagsat_args { int fd; const char *path; u_long flags; int atflag; } #endif int sys_chflagsat(struct thread *td, struct chflagsat_args *uap) { if ((uap->atflag & ~(AT_SYMLINK_NOFOLLOW | AT_BENEATH | AT_RESOLVE_BENEATH)) != 0) return (EINVAL); return (kern_chflagsat(td, uap->fd, uap->path, UIO_USERSPACE, uap->flags, uap->atflag)); } /* * Same as chflags() but doesn't follow symlinks. */ #ifndef _SYS_SYSPROTO_H_ struct lchflags_args { const char *path; u_long flags; }; #endif int sys_lchflags(struct thread *td, struct lchflags_args *uap) { return (kern_chflagsat(td, AT_FDCWD, uap->path, UIO_USERSPACE, uap->flags, AT_SYMLINK_NOFOLLOW)); } static int kern_chflagsat(struct thread *td, int fd, const char *path, enum uio_seg pathseg, u_long flags, int atflag) { struct nameidata nd; int error; AUDIT_ARG_FFLAGS(flags); NDINIT_ATRIGHTS(&nd, LOOKUP, at2cnpflags(atflag, AT_SYMLINK_NOFOLLOW | AT_BENEATH | AT_RESOLVE_BENEATH) | AUDITVNODE1, pathseg, path, fd, &cap_fchflags_rights, td); if ((error = namei(&nd)) != 0) return (error); NDFREE(&nd, NDF_ONLY_PNBUF); error = setfflags(td, nd.ni_vp, flags); vrele(nd.ni_vp); return (error); } /* * Change flags of a file given a file descriptor. */ #ifndef _SYS_SYSPROTO_H_ struct fchflags_args { int fd; u_long flags; }; #endif int sys_fchflags(struct thread *td, struct fchflags_args *uap) { struct file *fp; int error; AUDIT_ARG_FD(uap->fd); AUDIT_ARG_FFLAGS(uap->flags); error = getvnode(td, uap->fd, &cap_fchflags_rights, &fp); if (error != 0) return (error); #ifdef AUDIT vn_lock(fp->f_vnode, LK_SHARED | LK_RETRY); AUDIT_ARG_VNODE1(fp->f_vnode); VOP_UNLOCK(fp->f_vnode); #endif error = setfflags(td, fp->f_vnode, uap->flags); fdrop(fp, td); return (error); } /* * Common implementation code for chmod(), lchmod() and fchmod(). */ int setfmode(struct thread *td, struct ucred *cred, struct vnode *vp, int mode) { struct mount *mp; struct vattr vattr; int error; if ((error = vn_start_write(vp, &mp, V_WAIT | PCATCH)) != 0) return (error); vn_lock(vp, LK_EXCLUSIVE | LK_RETRY); VATTR_NULL(&vattr); vattr.va_mode = mode & ALLPERMS; #ifdef MAC error = mac_vnode_check_setmode(cred, vp, vattr.va_mode); if (error == 0) #endif error = VOP_SETATTR(vp, &vattr, cred); VOP_UNLOCK(vp); vn_finished_write(mp); return (error); } /* * Change mode of a file given path name. */ #ifndef _SYS_SYSPROTO_H_ struct chmod_args { char *path; int mode; }; #endif int sys_chmod(struct thread *td, struct chmod_args *uap) { return (kern_fchmodat(td, AT_FDCWD, uap->path, UIO_USERSPACE, uap->mode, 0)); } #ifndef _SYS_SYSPROTO_H_ struct fchmodat_args { int dirfd; char *path; mode_t mode; int flag; } #endif int sys_fchmodat(struct thread *td, struct fchmodat_args *uap) { if ((uap->flag & ~(AT_SYMLINK_NOFOLLOW | AT_BENEATH | AT_RESOLVE_BENEATH)) != 0) return (EINVAL); return (kern_fchmodat(td, uap->fd, uap->path, UIO_USERSPACE, uap->mode, uap->flag)); } /* * Change mode of a file given path name (don't follow links.) */ #ifndef _SYS_SYSPROTO_H_ struct lchmod_args { char *path; int mode; }; #endif int sys_lchmod(struct thread *td, struct lchmod_args *uap) { return (kern_fchmodat(td, AT_FDCWD, uap->path, UIO_USERSPACE, uap->mode, AT_SYMLINK_NOFOLLOW)); } int kern_fchmodat(struct thread *td, int fd, const char *path, enum uio_seg pathseg, mode_t mode, int flag) { struct nameidata nd; int error; AUDIT_ARG_MODE(mode); NDINIT_ATRIGHTS(&nd, LOOKUP, at2cnpflags(flag, AT_SYMLINK_NOFOLLOW | AT_BENEATH | AT_RESOLVE_BENEATH) | AUDITVNODE1, pathseg, path, fd, &cap_fchmod_rights, td); if ((error = namei(&nd)) != 0) return (error); NDFREE(&nd, NDF_ONLY_PNBUF); error = setfmode(td, td->td_ucred, nd.ni_vp, mode); vrele(nd.ni_vp); return (error); } /* * Change mode of a file given a file descriptor. */ #ifndef _SYS_SYSPROTO_H_ struct fchmod_args { int fd; int mode; }; #endif int sys_fchmod(struct thread *td, struct fchmod_args *uap) { struct file *fp; int error; AUDIT_ARG_FD(uap->fd); AUDIT_ARG_MODE(uap->mode); error = fget(td, uap->fd, &cap_fchmod_rights, &fp); if (error != 0) return (error); error = fo_chmod(fp, uap->mode, td->td_ucred, td); fdrop(fp, td); return (error); } /* * Common implementation for chown(), lchown(), and fchown() */ int setfown(struct thread *td, struct ucred *cred, struct vnode *vp, uid_t uid, gid_t gid) { struct mount *mp; struct vattr vattr; int error; if ((error = vn_start_write(vp, &mp, V_WAIT | PCATCH)) != 0) return (error); vn_lock(vp, LK_EXCLUSIVE | LK_RETRY); VATTR_NULL(&vattr); vattr.va_uid = uid; vattr.va_gid = gid; #ifdef MAC error = mac_vnode_check_setowner(cred, vp, vattr.va_uid, vattr.va_gid); if (error == 0) #endif error = VOP_SETATTR(vp, &vattr, cred); VOP_UNLOCK(vp); vn_finished_write(mp); return (error); } /* * Set ownership given a path name. */ #ifndef _SYS_SYSPROTO_H_ struct chown_args { char *path; int uid; int gid; }; #endif int sys_chown(struct thread *td, struct chown_args *uap) { return (kern_fchownat(td, AT_FDCWD, uap->path, UIO_USERSPACE, uap->uid, uap->gid, 0)); } #ifndef _SYS_SYSPROTO_H_ struct fchownat_args { int fd; const char * path; uid_t uid; gid_t gid; int flag; }; #endif int sys_fchownat(struct thread *td, struct fchownat_args *uap) { if ((uap->flag & ~(AT_SYMLINK_NOFOLLOW | AT_BENEATH | AT_RESOLVE_BENEATH)) != 0) return (EINVAL); return (kern_fchownat(td, uap->fd, uap->path, UIO_USERSPACE, uap->uid, uap->gid, uap->flag)); } int kern_fchownat(struct thread *td, int fd, const char *path, enum uio_seg pathseg, int uid, int gid, int flag) { struct nameidata nd; int error; AUDIT_ARG_OWNER(uid, gid); NDINIT_ATRIGHTS(&nd, LOOKUP, at2cnpflags(flag, AT_SYMLINK_NOFOLLOW | AT_BENEATH | AT_RESOLVE_BENEATH) | AUDITVNODE1, pathseg, path, fd, &cap_fchown_rights, td); if ((error = namei(&nd)) != 0) return (error); NDFREE(&nd, NDF_ONLY_PNBUF); error = setfown(td, td->td_ucred, nd.ni_vp, uid, gid); vrele(nd.ni_vp); return (error); } /* * Set ownership given a path name, do not cross symlinks. */ #ifndef _SYS_SYSPROTO_H_ struct lchown_args { char *path; int uid; int gid; }; #endif int sys_lchown(struct thread *td, struct lchown_args *uap) { return (kern_fchownat(td, AT_FDCWD, uap->path, UIO_USERSPACE, uap->uid, uap->gid, AT_SYMLINK_NOFOLLOW)); } /* * Set ownership given a file descriptor. */ #ifndef _SYS_SYSPROTO_H_ struct fchown_args { int fd; int uid; int gid; }; #endif int sys_fchown(struct thread *td, struct fchown_args *uap) { struct file *fp; int error; AUDIT_ARG_FD(uap->fd); AUDIT_ARG_OWNER(uap->uid, uap->gid); error = fget(td, uap->fd, &cap_fchown_rights, &fp); if (error != 0) return (error); error = fo_chown(fp, uap->uid, uap->gid, td->td_ucred, td); fdrop(fp, td); return (error); } /* * Common implementation code for utimes(), lutimes(), and futimes(). */ static int getutimes(const struct timeval *usrtvp, enum uio_seg tvpseg, struct timespec *tsp) { struct timeval tv[2]; const struct timeval *tvp; int error; if (usrtvp == NULL) { vfs_timestamp(&tsp[0]); tsp[1] = tsp[0]; } else { if (tvpseg == UIO_SYSSPACE) { tvp = usrtvp; } else { if ((error = copyin(usrtvp, tv, sizeof(tv))) != 0) return (error); tvp = tv; } if (tvp[0].tv_usec < 0 || tvp[0].tv_usec >= 1000000 || tvp[1].tv_usec < 0 || tvp[1].tv_usec >= 1000000) return (EINVAL); TIMEVAL_TO_TIMESPEC(&tvp[0], &tsp[0]); TIMEVAL_TO_TIMESPEC(&tvp[1], &tsp[1]); } return (0); } /* * Common implementation code for futimens(), utimensat(). */ #define UTIMENS_NULL 0x1 #define UTIMENS_EXIT 0x2 static int getutimens(const struct timespec *usrtsp, enum uio_seg tspseg, struct timespec *tsp, int *retflags) { struct timespec tsnow; int error; vfs_timestamp(&tsnow); *retflags = 0; if (usrtsp == NULL) { tsp[0] = tsnow; tsp[1] = tsnow; *retflags |= UTIMENS_NULL; return (0); } if (tspseg == UIO_SYSSPACE) { tsp[0] = usrtsp[0]; tsp[1] = usrtsp[1]; } else if ((error = copyin(usrtsp, tsp, sizeof(*tsp) * 2)) != 0) return (error); if (tsp[0].tv_nsec == UTIME_OMIT && tsp[1].tv_nsec == UTIME_OMIT) *retflags |= UTIMENS_EXIT; if (tsp[0].tv_nsec == UTIME_NOW && tsp[1].tv_nsec == UTIME_NOW) *retflags |= UTIMENS_NULL; if (tsp[0].tv_nsec == UTIME_OMIT) tsp[0].tv_sec = VNOVAL; else if (tsp[0].tv_nsec == UTIME_NOW) tsp[0] = tsnow; else if (tsp[0].tv_nsec < 0 || tsp[0].tv_nsec >= 1000000000L) return (EINVAL); if (tsp[1].tv_nsec == UTIME_OMIT) tsp[1].tv_sec = VNOVAL; else if (tsp[1].tv_nsec == UTIME_NOW) tsp[1] = tsnow; else if (tsp[1].tv_nsec < 0 || tsp[1].tv_nsec >= 1000000000L) return (EINVAL); return (0); } /* * Common implementation code for utimes(), lutimes(), futimes(), futimens(), * and utimensat(). */ static int setutimes(struct thread *td, struct vnode *vp, const struct timespec *ts, int numtimes, int nullflag) { struct mount *mp; struct vattr vattr; int error, setbirthtime; if ((error = vn_start_write(vp, &mp, V_WAIT | PCATCH)) != 0) return (error); vn_lock(vp, LK_EXCLUSIVE | LK_RETRY); setbirthtime = 0; if (numtimes < 3 && !VOP_GETATTR(vp, &vattr, td->td_ucred) && timespeccmp(&ts[1], &vattr.va_birthtime, < )) setbirthtime = 1; VATTR_NULL(&vattr); vattr.va_atime = ts[0]; vattr.va_mtime = ts[1]; if (setbirthtime) vattr.va_birthtime = ts[1]; if (numtimes > 2) vattr.va_birthtime = ts[2]; if (nullflag) vattr.va_vaflags |= VA_UTIMES_NULL; #ifdef MAC error = mac_vnode_check_setutimes(td->td_ucred, vp, vattr.va_atime, vattr.va_mtime); #endif if (error == 0) error = VOP_SETATTR(vp, &vattr, td->td_ucred); VOP_UNLOCK(vp); vn_finished_write(mp); return (error); } /* * Set the access and modification times of a file. */ #ifndef _SYS_SYSPROTO_H_ struct utimes_args { char *path; struct timeval *tptr; }; #endif int sys_utimes(struct thread *td, struct utimes_args *uap) { return (kern_utimesat(td, AT_FDCWD, uap->path, UIO_USERSPACE, uap->tptr, UIO_USERSPACE)); } #ifndef _SYS_SYSPROTO_H_ struct futimesat_args { int fd; const char * path; const struct timeval * times; }; #endif int sys_futimesat(struct thread *td, struct futimesat_args *uap) { return (kern_utimesat(td, uap->fd, uap->path, UIO_USERSPACE, uap->times, UIO_USERSPACE)); } int kern_utimesat(struct thread *td, int fd, const char *path, enum uio_seg pathseg, struct timeval *tptr, enum uio_seg tptrseg) { struct nameidata nd; struct timespec ts[2]; int error; if ((error = getutimes(tptr, tptrseg, ts)) != 0) return (error); NDINIT_ATRIGHTS(&nd, LOOKUP, FOLLOW | AUDITVNODE1, pathseg, path, fd, &cap_futimes_rights, td); if ((error = namei(&nd)) != 0) return (error); NDFREE(&nd, NDF_ONLY_PNBUF); error = setutimes(td, nd.ni_vp, ts, 2, tptr == NULL); vrele(nd.ni_vp); return (error); } /* * Set the access and modification times of a file. */ #ifndef _SYS_SYSPROTO_H_ struct lutimes_args { char *path; struct timeval *tptr; }; #endif int sys_lutimes(struct thread *td, struct lutimes_args *uap) { return (kern_lutimes(td, uap->path, UIO_USERSPACE, uap->tptr, UIO_USERSPACE)); } int kern_lutimes(struct thread *td, const char *path, enum uio_seg pathseg, struct timeval *tptr, enum uio_seg tptrseg) { struct timespec ts[2]; struct nameidata nd; int error; if ((error = getutimes(tptr, tptrseg, ts)) != 0) return (error); NDINIT(&nd, LOOKUP, NOFOLLOW | AUDITVNODE1, pathseg, path, td); if ((error = namei(&nd)) != 0) return (error); NDFREE(&nd, NDF_ONLY_PNBUF); error = setutimes(td, nd.ni_vp, ts, 2, tptr == NULL); vrele(nd.ni_vp); return (error); } /* * Set the access and modification times of a file. */ #ifndef _SYS_SYSPROTO_H_ struct futimes_args { int fd; struct timeval *tptr; }; #endif int sys_futimes(struct thread *td, struct futimes_args *uap) { return (kern_futimes(td, uap->fd, uap->tptr, UIO_USERSPACE)); } int kern_futimes(struct thread *td, int fd, struct timeval *tptr, enum uio_seg tptrseg) { struct timespec ts[2]; struct file *fp; int error; AUDIT_ARG_FD(fd); error = getutimes(tptr, tptrseg, ts); if (error != 0) return (error); error = getvnode(td, fd, &cap_futimes_rights, &fp); if (error != 0) return (error); #ifdef AUDIT vn_lock(fp->f_vnode, LK_SHARED | LK_RETRY); AUDIT_ARG_VNODE1(fp->f_vnode); VOP_UNLOCK(fp->f_vnode); #endif error = setutimes(td, fp->f_vnode, ts, 2, tptr == NULL); fdrop(fp, td); return (error); } int sys_futimens(struct thread *td, struct futimens_args *uap) { return (kern_futimens(td, uap->fd, uap->times, UIO_USERSPACE)); } int kern_futimens(struct thread *td, int fd, struct timespec *tptr, enum uio_seg tptrseg) { struct timespec ts[2]; struct file *fp; int error, flags; AUDIT_ARG_FD(fd); error = getutimens(tptr, tptrseg, ts, &flags); if (error != 0) return (error); if (flags & UTIMENS_EXIT) return (0); error = getvnode(td, fd, &cap_futimes_rights, &fp); if (error != 0) return (error); #ifdef AUDIT vn_lock(fp->f_vnode, LK_SHARED | LK_RETRY); AUDIT_ARG_VNODE1(fp->f_vnode); VOP_UNLOCK(fp->f_vnode); #endif error = setutimes(td, fp->f_vnode, ts, 2, flags & UTIMENS_NULL); fdrop(fp, td); return (error); } int sys_utimensat(struct thread *td, struct utimensat_args *uap) { return (kern_utimensat(td, uap->fd, uap->path, UIO_USERSPACE, uap->times, UIO_USERSPACE, uap->flag)); } int kern_utimensat(struct thread *td, int fd, const char *path, enum uio_seg pathseg, struct timespec *tptr, enum uio_seg tptrseg, int flag) { struct nameidata nd; struct timespec ts[2]; int error, flags; if ((flag & ~(AT_SYMLINK_NOFOLLOW | AT_BENEATH | AT_RESOLVE_BENEATH)) != 0) return (EINVAL); if ((error = getutimens(tptr, tptrseg, ts, &flags)) != 0) return (error); NDINIT_ATRIGHTS(&nd, LOOKUP, at2cnpflags(flag, AT_SYMLINK_NOFOLLOW | AT_BENEATH | AT_RESOLVE_BENEATH) | AUDITVNODE1, pathseg, path, fd, &cap_futimes_rights, td); if ((error = namei(&nd)) != 0) return (error); /* * We are allowed to call namei() regardless of 2xUTIME_OMIT. * POSIX states: * "If both tv_nsec fields are UTIME_OMIT... EACCESS may be detected." * "Search permission is denied by a component of the path prefix." */ NDFREE(&nd, NDF_ONLY_PNBUF); if ((flags & UTIMENS_EXIT) == 0) error = setutimes(td, nd.ni_vp, ts, 2, flags & UTIMENS_NULL); vrele(nd.ni_vp); return (error); } /* * Truncate a file given its path name. */ #ifndef _SYS_SYSPROTO_H_ struct truncate_args { char *path; int pad; off_t length; }; #endif int sys_truncate(struct thread *td, struct truncate_args *uap) { return (kern_truncate(td, uap->path, UIO_USERSPACE, uap->length)); } int kern_truncate(struct thread *td, const char *path, enum uio_seg pathseg, off_t length) { struct mount *mp; struct vnode *vp; void *rl_cookie; struct vattr vattr; struct nameidata nd; int error; if (length < 0) return (EINVAL); retry: NDINIT(&nd, LOOKUP, FOLLOW | AUDITVNODE1, pathseg, path, td); if ((error = namei(&nd)) != 0) return (error); vp = nd.ni_vp; rl_cookie = vn_rangelock_wlock(vp, 0, OFF_MAX); if ((error = vn_start_write(vp, &mp, V_WAIT | PCATCH)) != 0) { vn_rangelock_unlock(vp, rl_cookie); vrele(vp); return (error); } NDFREE(&nd, NDF_ONLY_PNBUF); vn_lock(vp, LK_EXCLUSIVE | LK_RETRY); if (vp->v_type == VDIR) error = EISDIR; #ifdef MAC else if ((error = mac_vnode_check_write(td->td_ucred, NOCRED, vp))) { } #endif else if ((error = vn_writechk(vp)) == 0 && (error = VOP_ACCESS(vp, VWRITE, td->td_ucred, td)) == 0) { VATTR_NULL(&vattr); vattr.va_size = length; error = VOP_SETATTR(vp, &vattr, td->td_ucred); } VOP_UNLOCK(vp); vn_finished_write(mp); vn_rangelock_unlock(vp, rl_cookie); vrele(vp); if (error == ERELOOKUP) goto retry; return (error); } #if defined(COMPAT_43) /* * Truncate a file given its path name. */ #ifndef _SYS_SYSPROTO_H_ struct otruncate_args { char *path; long length; }; #endif int otruncate(struct thread *td, struct otruncate_args *uap) { return (kern_truncate(td, uap->path, UIO_USERSPACE, uap->length)); } #endif /* COMPAT_43 */ #if defined(COMPAT_FREEBSD6) /* Versions with the pad argument */ int freebsd6_truncate(struct thread *td, struct freebsd6_truncate_args *uap) { return (kern_truncate(td, uap->path, UIO_USERSPACE, uap->length)); } int freebsd6_ftruncate(struct thread *td, struct freebsd6_ftruncate_args *uap) { return (kern_ftruncate(td, uap->fd, uap->length)); } #endif int kern_fsync(struct thread *td, int fd, bool fullsync) { struct vnode *vp; struct mount *mp; struct file *fp; int error, lock_flags; AUDIT_ARG_FD(fd); error = getvnode(td, fd, &cap_fsync_rights, &fp); if (error != 0) return (error); vp = fp->f_vnode; #if 0 if (!fullsync) /* XXXKIB: compete outstanding aio writes */; #endif retry: error = vn_start_write(vp, &mp, V_WAIT | PCATCH); if (error != 0) goto drop; if (MNT_SHARED_WRITES(mp) || ((mp == NULL) && MNT_SHARED_WRITES(vp->v_mount))) { lock_flags = LK_SHARED; } else { lock_flags = LK_EXCLUSIVE; } vn_lock(vp, lock_flags | LK_RETRY); AUDIT_ARG_VNODE1(vp); if (vp->v_object != NULL) { VM_OBJECT_WLOCK(vp->v_object); vm_object_page_clean(vp->v_object, 0, 0, 0); VM_OBJECT_WUNLOCK(vp->v_object); } error = fullsync ? VOP_FSYNC(vp, MNT_WAIT, td) : VOP_FDATASYNC(vp, td); VOP_UNLOCK(vp); vn_finished_write(mp); if (error == ERELOOKUP) goto retry; drop: fdrop(fp, td); return (error); } /* * Sync an open file. */ #ifndef _SYS_SYSPROTO_H_ struct fsync_args { int fd; }; #endif int sys_fsync(struct thread *td, struct fsync_args *uap) { return (kern_fsync(td, uap->fd, true)); } int sys_fdatasync(struct thread *td, struct fdatasync_args *uap) { return (kern_fsync(td, uap->fd, false)); } /* * Rename files. Source and destination must either both be directories, or * both not be directories. If target is a directory, it must be empty. */ #ifndef _SYS_SYSPROTO_H_ struct rename_args { char *from; char *to; }; #endif int sys_rename(struct thread *td, struct rename_args *uap) { return (kern_renameat(td, AT_FDCWD, uap->from, AT_FDCWD, uap->to, UIO_USERSPACE)); } #ifndef _SYS_SYSPROTO_H_ struct renameat_args { int oldfd; char *old; int newfd; char *new; }; #endif int sys_renameat(struct thread *td, struct renameat_args *uap) { return (kern_renameat(td, uap->oldfd, uap->old, uap->newfd, uap->new, UIO_USERSPACE)); } #ifdef MAC static int kern_renameat_mac(struct thread *td, int oldfd, const char *old, int newfd, const char *new, enum uio_seg pathseg, struct nameidata *fromnd) { int error; NDINIT_ATRIGHTS(fromnd, DELETE, LOCKPARENT | LOCKLEAF | SAVESTART | AUDITVNODE1, pathseg, old, oldfd, &cap_renameat_source_rights, td); if ((error = namei(fromnd)) != 0) return (error); error = mac_vnode_check_rename_from(td->td_ucred, fromnd->ni_dvp, fromnd->ni_vp, &fromnd->ni_cnd); VOP_UNLOCK(fromnd->ni_dvp); if (fromnd->ni_dvp != fromnd->ni_vp) VOP_UNLOCK(fromnd->ni_vp); if (error != 0) { NDFREE(fromnd, NDF_ONLY_PNBUF); vrele(fromnd->ni_dvp); vrele(fromnd->ni_vp); if (fromnd->ni_startdir) vrele(fromnd->ni_startdir); } return (error); } #endif int kern_renameat(struct thread *td, int oldfd, const char *old, int newfd, const char *new, enum uio_seg pathseg) { struct mount *mp = NULL; struct vnode *tvp, *fvp, *tdvp; struct nameidata fromnd, tond; int error; again: bwillwrite(); #ifdef MAC if (mac_vnode_check_rename_from_enabled()) { error = kern_renameat_mac(td, oldfd, old, newfd, new, pathseg, &fromnd); if (error != 0) return (error); } else { #endif NDINIT_ATRIGHTS(&fromnd, DELETE, WANTPARENT | SAVESTART | AUDITVNODE1, pathseg, old, oldfd, &cap_renameat_source_rights, td); if ((error = namei(&fromnd)) != 0) return (error); #ifdef MAC } #endif fvp = fromnd.ni_vp; NDINIT_ATRIGHTS(&tond, RENAME, LOCKPARENT | LOCKLEAF | NOCACHE | SAVESTART | AUDITVNODE2, pathseg, new, newfd, &cap_renameat_target_rights, td); if (fromnd.ni_vp->v_type == VDIR) tond.ni_cnd.cn_flags |= WILLBEDIR; if ((error = namei(&tond)) != 0) { /* Translate error code for rename("dir1", "dir2/."). */ if (error == EISDIR && fvp->v_type == VDIR) error = EINVAL; NDFREE(&fromnd, NDF_ONLY_PNBUF); vrele(fromnd.ni_dvp); vrele(fvp); goto out1; } tdvp = tond.ni_dvp; tvp = tond.ni_vp; error = vn_start_write(fvp, &mp, V_NOWAIT); if (error != 0) { NDFREE(&fromnd, NDF_ONLY_PNBUF); NDFREE(&tond, NDF_ONLY_PNBUF); if (tvp != NULL) vput(tvp); if (tdvp == tvp) vrele(tdvp); else vput(tdvp); vrele(fromnd.ni_dvp); vrele(fvp); vrele(tond.ni_startdir); if (fromnd.ni_startdir != NULL) vrele(fromnd.ni_startdir); error = vn_start_write(NULL, &mp, V_XSLEEP | PCATCH); if (error != 0) return (error); goto again; } if (tvp != NULL) { if (fvp->v_type == VDIR && tvp->v_type != VDIR) { error = ENOTDIR; goto out; } else if (fvp->v_type != VDIR && tvp->v_type == VDIR) { error = EISDIR; goto out; } #ifdef CAPABILITIES if (newfd != AT_FDCWD && (tond.ni_resflags & NIRES_ABS) == 0) { /* * If the target already exists we require CAP_UNLINKAT * from 'newfd', when newfd was used for the lookup. */ error = cap_check(&tond.ni_filecaps.fc_rights, &cap_unlinkat_rights); if (error != 0) goto out; } #endif } if (fvp == tdvp) { error = EINVAL; goto out; } /* * If the source is the same as the destination (that is, if they * are links to the same vnode), then there is nothing to do. */ if (fvp == tvp) error = ERESTART; #ifdef MAC else error = mac_vnode_check_rename_to(td->td_ucred, tdvp, tond.ni_vp, fromnd.ni_dvp == tdvp, &tond.ni_cnd); #endif out: if (error == 0) { error = VOP_RENAME(fromnd.ni_dvp, fromnd.ni_vp, &fromnd.ni_cnd, tond.ni_dvp, tond.ni_vp, &tond.ni_cnd); NDFREE(&fromnd, NDF_ONLY_PNBUF); NDFREE(&tond, NDF_ONLY_PNBUF); } else { NDFREE(&fromnd, NDF_ONLY_PNBUF); NDFREE(&tond, NDF_ONLY_PNBUF); if (tvp != NULL) vput(tvp); if (tdvp == tvp) vrele(tdvp); else vput(tdvp); vrele(fromnd.ni_dvp); vrele(fvp); } vrele(tond.ni_startdir); vn_finished_write(mp); out1: if (fromnd.ni_startdir) vrele(fromnd.ni_startdir); if (error == ERESTART) return (0); if (error == ERELOOKUP) goto again; return (error); } /* * Make a directory file. */ #ifndef _SYS_SYSPROTO_H_ struct mkdir_args { char *path; int mode; }; #endif int sys_mkdir(struct thread *td, struct mkdir_args *uap) { return (kern_mkdirat(td, AT_FDCWD, uap->path, UIO_USERSPACE, uap->mode)); } #ifndef _SYS_SYSPROTO_H_ struct mkdirat_args { int fd; char *path; mode_t mode; }; #endif int sys_mkdirat(struct thread *td, struct mkdirat_args *uap) { return (kern_mkdirat(td, uap->fd, uap->path, UIO_USERSPACE, uap->mode)); } int kern_mkdirat(struct thread *td, int fd, const char *path, enum uio_seg segflg, int mode) { struct mount *mp; struct vnode *vp; struct vattr vattr; struct nameidata nd; int error; AUDIT_ARG_MODE(mode); restart: bwillwrite(); NDINIT_ATRIGHTS(&nd, CREATE, LOCKPARENT | SAVENAME | AUDITVNODE1 | NC_NOMAKEENTRY | NC_KEEPPOSENTRY, segflg, path, fd, &cap_mkdirat_rights, td); nd.ni_cnd.cn_flags |= WILLBEDIR; if ((error = namei(&nd)) != 0) return (error); vp = nd.ni_vp; if (vp != NULL) { NDFREE(&nd, NDF_ONLY_PNBUF); /* * XXX namei called with LOCKPARENT but not LOCKLEAF has * the strange behaviour of leaving the vnode unlocked * if the target is the same vnode as the parent. */ if (vp == nd.ni_dvp) vrele(nd.ni_dvp); else vput(nd.ni_dvp); vrele(vp); return (EEXIST); } if (vn_start_write(nd.ni_dvp, &mp, V_NOWAIT) != 0) { NDFREE(&nd, NDF_ONLY_PNBUF); vput(nd.ni_dvp); if ((error = vn_start_write(NULL, &mp, V_XSLEEP | PCATCH)) != 0) return (error); goto restart; } VATTR_NULL(&vattr); vattr.va_type = VDIR; vattr.va_mode = (mode & ACCESSPERMS) &~ td->td_proc->p_fd->fd_cmask; #ifdef MAC error = mac_vnode_check_create(td->td_ucred, nd.ni_dvp, &nd.ni_cnd, &vattr); if (error != 0) goto out; #endif error = VOP_MKDIR(nd.ni_dvp, &nd.ni_vp, &nd.ni_cnd, &vattr); #ifdef MAC out: #endif NDFREE(&nd, NDF_ONLY_PNBUF); vput(nd.ni_dvp); if (error == 0) vput(nd.ni_vp); vn_finished_write(mp); if (error == ERELOOKUP) goto restart; return (error); } /* * Remove a directory file. */ #ifndef _SYS_SYSPROTO_H_ struct rmdir_args { char *path; }; #endif int sys_rmdir(struct thread *td, struct rmdir_args *uap) { return (kern_frmdirat(td, AT_FDCWD, uap->path, FD_NONE, UIO_USERSPACE, 0)); } int kern_frmdirat(struct thread *td, int dfd, const char *path, int fd, enum uio_seg pathseg, int flag) { struct mount *mp; struct vnode *vp; struct file *fp; struct nameidata nd; cap_rights_t rights; int error; fp = NULL; if (fd != FD_NONE) { error = getvnode(td, fd, cap_rights_init_one(&rights, CAP_LOOKUP), &fp); if (error != 0) return (error); } restart: bwillwrite(); NDINIT_ATRIGHTS(&nd, DELETE, LOCKPARENT | LOCKLEAF | AUDITVNODE1 | at2cnpflags(flag, AT_BENEATH | AT_RESOLVE_BENEATH), pathseg, path, dfd, &cap_unlinkat_rights, td); if ((error = namei(&nd)) != 0) goto fdout; vp = nd.ni_vp; if (vp->v_type != VDIR) { error = ENOTDIR; goto out; } /* * No rmdir "." please. */ if (nd.ni_dvp == vp) { error = EINVAL; goto out; } /* * The root of a mounted filesystem cannot be deleted. */ if (vp->v_vflag & VV_ROOT) { error = EBUSY; goto out; } if (fp != NULL && fp->f_vnode != vp) { if (VN_IS_DOOMED(fp->f_vnode)) error = EBADF; else error = EDEADLK; goto out; } #ifdef MAC error = mac_vnode_check_unlink(td->td_ucred, nd.ni_dvp, vp, &nd.ni_cnd); if (error != 0) goto out; #endif if (vn_start_write(nd.ni_dvp, &mp, V_NOWAIT) != 0) { NDFREE(&nd, NDF_ONLY_PNBUF); vput(vp); if (nd.ni_dvp == vp) vrele(nd.ni_dvp); else vput(nd.ni_dvp); if ((error = vn_start_write(NULL, &mp, V_XSLEEP | PCATCH)) != 0) goto fdout; goto restart; } vfs_notify_upper(vp, VFS_NOTIFY_UPPER_UNLINK); error = VOP_RMDIR(nd.ni_dvp, nd.ni_vp, &nd.ni_cnd); vn_finished_write(mp); out: NDFREE(&nd, NDF_ONLY_PNBUF); vput(vp); if (nd.ni_dvp == vp) vrele(nd.ni_dvp); else vput(nd.ni_dvp); if (error == ERELOOKUP) goto restart; fdout: if (fp != NULL) fdrop(fp, td); return (error); } #if defined(COMPAT_43) || defined(COMPAT_FREEBSD11) int freebsd11_kern_getdirentries(struct thread *td, int fd, char *ubuf, u_int count, long *basep, void (*func)(struct freebsd11_dirent *)) { struct freebsd11_dirent dstdp; struct dirent *dp, *edp; char *dirbuf; off_t base; ssize_t resid, ucount; int error; /* XXX arbitrary sanity limit on `count'. */ count = min(count, 64 * 1024); dirbuf = malloc(count, M_TEMP, M_WAITOK); error = kern_getdirentries(td, fd, dirbuf, count, &base, &resid, UIO_SYSSPACE); if (error != 0) goto done; if (basep != NULL) *basep = base; ucount = 0; for (dp = (struct dirent *)dirbuf, edp = (struct dirent *)&dirbuf[count - resid]; ucount < count && dp < edp; ) { if (dp->d_reclen == 0) break; MPASS(dp->d_reclen >= _GENERIC_DIRLEN(0)); if (dp->d_namlen >= sizeof(dstdp.d_name)) continue; dstdp.d_type = dp->d_type; dstdp.d_namlen = dp->d_namlen; dstdp.d_fileno = dp->d_fileno; /* truncate */ if (dstdp.d_fileno != dp->d_fileno) { switch (ino64_trunc_error) { default: case 0: break; case 1: error = EOVERFLOW; goto done; case 2: dstdp.d_fileno = UINT32_MAX; break; } } dstdp.d_reclen = sizeof(dstdp) - sizeof(dstdp.d_name) + ((dp->d_namlen + 1 + 3) &~ 3); bcopy(dp->d_name, dstdp.d_name, dstdp.d_namlen); bzero(dstdp.d_name + dstdp.d_namlen, dstdp.d_reclen - offsetof(struct freebsd11_dirent, d_name) - dstdp.d_namlen); MPASS(dstdp.d_reclen <= dp->d_reclen); MPASS(ucount + dstdp.d_reclen <= count); if (func != NULL) func(&dstdp); error = copyout(&dstdp, ubuf + ucount, dstdp.d_reclen); if (error != 0) break; dp = (struct dirent *)((char *)dp + dp->d_reclen); ucount += dstdp.d_reclen; } done: free(dirbuf, M_TEMP); if (error == 0) td->td_retval[0] = ucount; return (error); } #endif /* COMPAT */ #ifdef COMPAT_43 static void ogetdirentries_cvt(struct freebsd11_dirent *dp) { #if (BYTE_ORDER == LITTLE_ENDIAN) /* * The expected low byte of dp->d_namlen is our dp->d_type. * The high MBZ byte of dp->d_namlen is our dp->d_namlen. */ dp->d_type = dp->d_namlen; dp->d_namlen = 0; #else /* * The dp->d_type is the high byte of the expected dp->d_namlen, * so must be zero'ed. */ dp->d_type = 0; #endif } /* * Read a block of directory entries in a filesystem independent format. */ #ifndef _SYS_SYSPROTO_H_ struct ogetdirentries_args { int fd; char *buf; u_int count; long *basep; }; #endif int ogetdirentries(struct thread *td, struct ogetdirentries_args *uap) { long loff; int error; error = kern_ogetdirentries(td, uap, &loff); if (error == 0) error = copyout(&loff, uap->basep, sizeof(long)); return (error); } int kern_ogetdirentries(struct thread *td, struct ogetdirentries_args *uap, long *ploff) { long base; int error; /* XXX arbitrary sanity limit on `count'. */ if (uap->count > 64 * 1024) return (EINVAL); error = freebsd11_kern_getdirentries(td, uap->fd, uap->buf, uap->count, &base, ogetdirentries_cvt); if (error == 0 && uap->basep != NULL) error = copyout(&base, uap->basep, sizeof(long)); return (error); } #endif /* COMPAT_43 */ #if defined(COMPAT_FREEBSD11) #ifndef _SYS_SYSPROTO_H_ struct freebsd11_getdirentries_args { int fd; char *buf; u_int count; long *basep; }; #endif int freebsd11_getdirentries(struct thread *td, struct freebsd11_getdirentries_args *uap) { long base; int error; error = freebsd11_kern_getdirentries(td, uap->fd, uap->buf, uap->count, &base, NULL); if (error == 0 && uap->basep != NULL) error = copyout(&base, uap->basep, sizeof(long)); return (error); } int freebsd11_getdents(struct thread *td, struct freebsd11_getdents_args *uap) { struct freebsd11_getdirentries_args ap; ap.fd = uap->fd; ap.buf = uap->buf; ap.count = uap->count; ap.basep = NULL; return (freebsd11_getdirentries(td, &ap)); } #endif /* COMPAT_FREEBSD11 */ /* * Read a block of directory entries in a filesystem independent format. */ int sys_getdirentries(struct thread *td, struct getdirentries_args *uap) { off_t base; int error; error = kern_getdirentries(td, uap->fd, uap->buf, uap->count, &base, NULL, UIO_USERSPACE); if (error != 0) return (error); if (uap->basep != NULL) error = copyout(&base, uap->basep, sizeof(off_t)); return (error); } int kern_getdirentries(struct thread *td, int fd, char *buf, size_t count, off_t *basep, ssize_t *residp, enum uio_seg bufseg) { struct vnode *vp; struct file *fp; struct uio auio; struct iovec aiov; off_t loff; int error, eofflag; off_t foffset; AUDIT_ARG_FD(fd); if (count > IOSIZE_MAX) return (EINVAL); auio.uio_resid = count; error = getvnode(td, fd, &cap_read_rights, &fp); if (error != 0) return (error); if ((fp->f_flag & FREAD) == 0) { fdrop(fp, td); return (EBADF); } vp = fp->f_vnode; foffset = foffset_lock(fp, 0); unionread: if (vp->v_type != VDIR) { error = EINVAL; goto fail; } aiov.iov_base = buf; aiov.iov_len = count; auio.uio_iov = &aiov; auio.uio_iovcnt = 1; auio.uio_rw = UIO_READ; auio.uio_segflg = bufseg; auio.uio_td = td; vn_lock(vp, LK_SHARED | LK_RETRY); AUDIT_ARG_VNODE1(vp); loff = auio.uio_offset = foffset; #ifdef MAC error = mac_vnode_check_readdir(td->td_ucred, vp); if (error == 0) #endif error = VOP_READDIR(vp, &auio, fp->f_cred, &eofflag, NULL, NULL); foffset = auio.uio_offset; if (error != 0) { VOP_UNLOCK(vp); goto fail; } if (count == auio.uio_resid && (vp->v_vflag & VV_ROOT) && (vp->v_mount->mnt_flag & MNT_UNION)) { struct vnode *tvp = vp; vp = vp->v_mount->mnt_vnodecovered; VREF(vp); fp->f_vnode = vp; foffset = 0; vput(tvp); goto unionread; } VOP_UNLOCK(vp); *basep = loff; if (residp != NULL) *residp = auio.uio_resid; td->td_retval[0] = count - auio.uio_resid; fail: foffset_unlock(fp, foffset, 0); fdrop(fp, td); return (error); } /* * Set the mode mask for creation of filesystem nodes. */ #ifndef _SYS_SYSPROTO_H_ struct umask_args { int newmask; }; #endif int sys_umask(struct thread *td, struct umask_args *uap) { struct filedesc *fdp; fdp = td->td_proc->p_fd; FILEDESC_XLOCK(fdp); td->td_retval[0] = fdp->fd_cmask; fdp->fd_cmask = uap->newmask & ALLPERMS; FILEDESC_XUNLOCK(fdp); return (0); } /* * Void all references to file by ripping underlying filesystem away from * vnode. */ #ifndef _SYS_SYSPROTO_H_ struct revoke_args { char *path; }; #endif int sys_revoke(struct thread *td, struct revoke_args *uap) { struct vnode *vp; struct vattr vattr; struct nameidata nd; int error; NDINIT(&nd, LOOKUP, FOLLOW | LOCKLEAF | AUDITVNODE1, UIO_USERSPACE, uap->path, td); if ((error = namei(&nd)) != 0) return (error); vp = nd.ni_vp; NDFREE(&nd, NDF_ONLY_PNBUF); if (vp->v_type != VCHR || vp->v_rdev == NULL) { error = EINVAL; goto out; } #ifdef MAC error = mac_vnode_check_revoke(td->td_ucred, vp); if (error != 0) goto out; #endif error = VOP_GETATTR(vp, &vattr, td->td_ucred); if (error != 0) goto out; if (td->td_ucred->cr_uid != vattr.va_uid) { error = priv_check(td, PRIV_VFS_ADMIN); if (error != 0) goto out; } if (devfs_usecount(vp) > 0) VOP_REVOKE(vp, REVOKEALL); out: vput(vp); return (error); } /* * Convert a user file descriptor to a kernel file entry and check that, if it * is a capability, the correct rights are present. A reference on the file * entry is held upon returning. */ int getvnode(struct thread *td, int fd, cap_rights_t *rightsp, struct file **fpp) { struct file *fp; int error; error = fget_unlocked(td->td_proc->p_fd, fd, rightsp, &fp); if (error != 0) return (error); /* * The file could be not of the vnode type, or it may be not * yet fully initialized, in which case the f_vnode pointer * may be set, but f_ops is still badfileops. E.g., * devfs_open() transiently create such situation to * facilitate csw d_fdopen(). * * Dupfdopen() handling in kern_openat() installs the * half-baked file into the process descriptor table, allowing * other thread to dereference it. Guard against the race by * checking f_ops. */ if (fp->f_vnode == NULL || fp->f_ops == &badfileops) { fdrop(fp, td); return (EINVAL); } *fpp = fp; return (0); } /* * Get an (NFS) file handle. */ #ifndef _SYS_SYSPROTO_H_ struct lgetfh_args { char *fname; fhandle_t *fhp; }; #endif int sys_lgetfh(struct thread *td, struct lgetfh_args *uap) { return (kern_getfhat(td, AT_SYMLINK_NOFOLLOW, AT_FDCWD, uap->fname, - UIO_USERSPACE, uap->fhp)); + UIO_USERSPACE, uap->fhp, UIO_USERSPACE)); } #ifndef _SYS_SYSPROTO_H_ struct getfh_args { char *fname; fhandle_t *fhp; }; #endif int sys_getfh(struct thread *td, struct getfh_args *uap) { return (kern_getfhat(td, 0, AT_FDCWD, uap->fname, UIO_USERSPACE, - uap->fhp)); + uap->fhp, UIO_USERSPACE)); } /* * syscall for the rpc.lockd to use to translate an open descriptor into * a NFS file handle. * * warning: do not remove the priv_check() call or this becomes one giant * security hole. */ #ifndef _SYS_SYSPROTO_H_ struct getfhat_args { int fd; char *path; fhandle_t *fhp; int flags; }; #endif int sys_getfhat(struct thread *td, struct getfhat_args *uap) { if ((uap->flags & ~(AT_SYMLINK_NOFOLLOW | AT_BENEATH | AT_RESOLVE_BENEATH)) != 0) return (EINVAL); return (kern_getfhat(td, uap->flags, uap->fd, uap->path, UIO_USERSPACE, - uap->fhp)); + uap->fhp, UIO_USERSPACE)); } -static int +int kern_getfhat(struct thread *td, int flags, int fd, const char *path, - enum uio_seg pathseg, fhandle_t *fhp) + enum uio_seg pathseg, fhandle_t *fhp, enum uio_seg fhseg) { struct nameidata nd; fhandle_t fh; struct vnode *vp; int error; error = priv_check(td, PRIV_VFS_GETFH); if (error != 0) return (error); NDINIT_AT(&nd, LOOKUP, at2cnpflags(flags, AT_SYMLINK_NOFOLLOW | AT_BENEATH | AT_RESOLVE_BENEATH) | LOCKLEAF | AUDITVNODE1, pathseg, path, fd, td); error = namei(&nd); if (error != 0) return (error); NDFREE(&nd, NDF_ONLY_PNBUF); vp = nd.ni_vp; bzero(&fh, sizeof(fh)); fh.fh_fsid = vp->v_mount->mnt_stat.f_fsid; error = VOP_VPTOFH(vp, &fh.fh_fid); vput(vp); - if (error == 0) - error = copyout(&fh, fhp, sizeof (fh)); + if (error == 0) { + if (fhseg == UIO_USERSPACE) + error = copyout(&fh, fhp, sizeof (fh)); + else + memcpy(fhp, &fh, sizeof(fh)); + } return (error); } #ifndef _SYS_SYSPROTO_H_ struct fhlink_args { fhandle_t *fhp; const char *to; }; #endif int sys_fhlink(struct thread *td, struct fhlink_args *uap) { return (kern_fhlinkat(td, AT_FDCWD, uap->to, UIO_USERSPACE, uap->fhp)); } #ifndef _SYS_SYSPROTO_H_ struct fhlinkat_args { fhandle_t *fhp; int tofd; const char *to; }; #endif int sys_fhlinkat(struct thread *td, struct fhlinkat_args *uap) { return (kern_fhlinkat(td, uap->tofd, uap->to, UIO_USERSPACE, uap->fhp)); } static int kern_fhlinkat(struct thread *td, int fd, const char *path, enum uio_seg pathseg, fhandle_t *fhp) { fhandle_t fh; struct mount *mp; struct vnode *vp; int error; error = priv_check(td, PRIV_VFS_GETFH); if (error != 0) return (error); error = copyin(fhp, &fh, sizeof(fh)); if (error != 0) return (error); do { bwillwrite(); if ((mp = vfs_busyfs(&fh.fh_fsid)) == NULL) return (ESTALE); error = VFS_FHTOVP(mp, &fh.fh_fid, LK_SHARED, &vp); vfs_unbusy(mp); if (error != 0) return (error); VOP_UNLOCK(vp); error = kern_linkat_vp(td, vp, fd, path, pathseg); } while (error == EAGAIN || error == ERELOOKUP); return (error); } #ifndef _SYS_SYSPROTO_H_ struct fhreadlink_args { fhandle_t *fhp; char *buf; size_t bufsize; }; #endif int sys_fhreadlink(struct thread *td, struct fhreadlink_args *uap) { fhandle_t fh; struct mount *mp; struct vnode *vp; int error; error = priv_check(td, PRIV_VFS_GETFH); if (error != 0) return (error); if (uap->bufsize > IOSIZE_MAX) return (EINVAL); error = copyin(uap->fhp, &fh, sizeof(fh)); if (error != 0) return (error); if ((mp = vfs_busyfs(&fh.fh_fsid)) == NULL) return (ESTALE); error = VFS_FHTOVP(mp, &fh.fh_fid, LK_SHARED, &vp); vfs_unbusy(mp); if (error != 0) return (error); error = kern_readlink_vp(vp, uap->buf, UIO_USERSPACE, uap->bufsize, td); vput(vp); return (error); } /* * syscall for the rpc.lockd to use to translate a NFS file handle into an * open descriptor. * * warning: do not remove the priv_check() call or this becomes one giant * security hole. */ #ifndef _SYS_SYSPROTO_H_ struct fhopen_args { const struct fhandle *u_fhp; int flags; }; #endif int sys_fhopen(struct thread *td, struct fhopen_args *uap) { + return (kern_fhopen(td, uap->u_fhp, uap->flags)); +} + +int +kern_fhopen(struct thread *td, const struct fhandle *u_fhp, int flags) +{ struct mount *mp; struct vnode *vp; struct fhandle fhp; struct file *fp; int fmode, error; int indx; error = priv_check(td, PRIV_VFS_FHOPEN); if (error != 0) return (error); indx = -1; - fmode = FFLAGS(uap->flags); + fmode = FFLAGS(flags); /* why not allow a non-read/write open for our lockd? */ if (((fmode & (FREAD | FWRITE)) == 0) || (fmode & O_CREAT)) return (EINVAL); - error = copyin(uap->u_fhp, &fhp, sizeof(fhp)); + error = copyin(u_fhp, &fhp, sizeof(fhp)); if (error != 0) return(error); /* find the mount point */ mp = vfs_busyfs(&fhp.fh_fsid); if (mp == NULL) return (ESTALE); /* now give me my vnode, it gets returned to me locked */ error = VFS_FHTOVP(mp, &fhp.fh_fid, LK_EXCLUSIVE, &vp); vfs_unbusy(mp); if (error != 0) return (error); error = falloc_noinstall(td, &fp); if (error != 0) { vput(vp); return (error); } /* * An extra reference on `fp' has been held for us by * falloc_noinstall(). */ #ifdef INVARIANTS td->td_dupfd = -1; #endif error = vn_open_vnode(vp, fmode, td->td_ucred, td, fp); if (error != 0) { KASSERT(fp->f_ops == &badfileops, ("VOP_OPEN in fhopen() set f_ops")); KASSERT(td->td_dupfd < 0, ("fhopen() encountered fdopen()")); vput(vp); goto bad; } #ifdef INVARIANTS td->td_dupfd = 0; #endif fp->f_vnode = vp; finit_vnode(fp, fmode, NULL, &vnops); VOP_UNLOCK(vp); if ((fmode & O_TRUNC) != 0) { error = fo_truncate(fp, 0, td->td_ucred, td); if (error != 0) goto bad; } error = finstall(td, fp, &indx, fmode, NULL); bad: fdrop(fp, td); td->td_retval[0] = indx; return (error); } /* * Stat an (NFS) file handle. */ #ifndef _SYS_SYSPROTO_H_ struct fhstat_args { struct fhandle *u_fhp; struct stat *sb; }; #endif int sys_fhstat(struct thread *td, struct fhstat_args *uap) { struct stat sb; struct fhandle fh; int error; error = copyin(uap->u_fhp, &fh, sizeof(fh)); if (error != 0) return (error); error = kern_fhstat(td, fh, &sb); if (error == 0) error = copyout(&sb, uap->sb, sizeof(sb)); return (error); } int kern_fhstat(struct thread *td, struct fhandle fh, struct stat *sb) { struct mount *mp; struct vnode *vp; int error; error = priv_check(td, PRIV_VFS_FHSTAT); if (error != 0) return (error); if ((mp = vfs_busyfs(&fh.fh_fsid)) == NULL) return (ESTALE); error = VFS_FHTOVP(mp, &fh.fh_fid, LK_EXCLUSIVE, &vp); vfs_unbusy(mp); if (error != 0) return (error); error = VOP_STAT(vp, sb, td->td_ucred, NOCRED, td); vput(vp); return (error); } /* * Implement fstatfs() for (NFS) file handles. */ #ifndef _SYS_SYSPROTO_H_ struct fhstatfs_args { struct fhandle *u_fhp; struct statfs *buf; }; #endif int sys_fhstatfs(struct thread *td, struct fhstatfs_args *uap) { struct statfs *sfp; fhandle_t fh; int error; error = copyin(uap->u_fhp, &fh, sizeof(fhandle_t)); if (error != 0) return (error); sfp = malloc(sizeof(struct statfs), M_STATFS, M_WAITOK); error = kern_fhstatfs(td, fh, sfp); if (error == 0) error = copyout(sfp, uap->buf, sizeof(*sfp)); free(sfp, M_STATFS); return (error); } int kern_fhstatfs(struct thread *td, fhandle_t fh, struct statfs *buf) { struct mount *mp; struct vnode *vp; int error; error = priv_check(td, PRIV_VFS_FHSTATFS); if (error != 0) return (error); if ((mp = vfs_busyfs(&fh.fh_fsid)) == NULL) return (ESTALE); error = VFS_FHTOVP(mp, &fh.fh_fid, LK_EXCLUSIVE, &vp); if (error != 0) { vfs_unbusy(mp); return (error); } vput(vp); error = prison_canseemount(td->td_ucred, mp); if (error != 0) goto out; #ifdef MAC error = mac_mount_check_stat(td->td_ucred, mp); if (error != 0) goto out; #endif error = VFS_STATFS(mp, buf); out: vfs_unbusy(mp); return (error); } /* * Unlike madvise(2), we do not make a best effort to remember every * possible caching hint. Instead, we remember the last setting with * the exception that we will allow POSIX_FADV_NORMAL to adjust the * region of any current setting. */ int kern_posix_fadvise(struct thread *td, int fd, off_t offset, off_t len, int advice) { struct fadvise_info *fa, *new; struct file *fp; struct vnode *vp; off_t end; int error; if (offset < 0 || len < 0 || offset > OFF_MAX - len) return (EINVAL); AUDIT_ARG_VALUE(advice); switch (advice) { case POSIX_FADV_SEQUENTIAL: case POSIX_FADV_RANDOM: case POSIX_FADV_NOREUSE: new = malloc(sizeof(*fa), M_FADVISE, M_WAITOK); break; case POSIX_FADV_NORMAL: case POSIX_FADV_WILLNEED: case POSIX_FADV_DONTNEED: new = NULL; break; default: return (EINVAL); } /* XXX: CAP_POSIX_FADVISE? */ AUDIT_ARG_FD(fd); error = fget(td, fd, &cap_no_rights, &fp); if (error != 0) goto out; AUDIT_ARG_FILE(td->td_proc, fp); if ((fp->f_ops->fo_flags & DFLAG_SEEKABLE) == 0) { error = ESPIPE; goto out; } if (fp->f_type != DTYPE_VNODE) { error = ENODEV; goto out; } vp = fp->f_vnode; if (vp->v_type != VREG) { error = ENODEV; goto out; } if (len == 0) end = OFF_MAX; else end = offset + len - 1; switch (advice) { case POSIX_FADV_SEQUENTIAL: case POSIX_FADV_RANDOM: case POSIX_FADV_NOREUSE: /* * Try to merge any existing non-standard region with * this new region if possible, otherwise create a new * non-standard region for this request. */ mtx_pool_lock(mtxpool_sleep, fp); fa = fp->f_advice; if (fa != NULL && fa->fa_advice == advice && ((fa->fa_start <= end && fa->fa_end >= offset) || (end != OFF_MAX && fa->fa_start == end + 1) || (fa->fa_end != OFF_MAX && fa->fa_end + 1 == offset))) { if (offset < fa->fa_start) fa->fa_start = offset; if (end > fa->fa_end) fa->fa_end = end; } else { new->fa_advice = advice; new->fa_start = offset; new->fa_end = end; fp->f_advice = new; new = fa; } mtx_pool_unlock(mtxpool_sleep, fp); break; case POSIX_FADV_NORMAL: /* * If a the "normal" region overlaps with an existing * non-standard region, trim or remove the * non-standard region. */ mtx_pool_lock(mtxpool_sleep, fp); fa = fp->f_advice; if (fa != NULL) { if (offset <= fa->fa_start && end >= fa->fa_end) { new = fa; fp->f_advice = NULL; } else if (offset <= fa->fa_start && end >= fa->fa_start) fa->fa_start = end + 1; else if (offset <= fa->fa_end && end >= fa->fa_end) fa->fa_end = offset - 1; else if (offset >= fa->fa_start && end <= fa->fa_end) { /* * If the "normal" region is a middle * portion of the existing * non-standard region, just remove * the whole thing rather than picking * one side or the other to * preserve. */ new = fa; fp->f_advice = NULL; } } mtx_pool_unlock(mtxpool_sleep, fp); break; case POSIX_FADV_WILLNEED: case POSIX_FADV_DONTNEED: error = VOP_ADVISE(vp, offset, end, advice); break; } out: if (fp != NULL) fdrop(fp, td); free(new, M_FADVISE); return (error); } int sys_posix_fadvise(struct thread *td, struct posix_fadvise_args *uap) { int error; error = kern_posix_fadvise(td, uap->fd, uap->offset, uap->len, uap->advice); return (kern_posix_error(td, error)); } int kern_copy_file_range(struct thread *td, int infd, off_t *inoffp, int outfd, off_t *outoffp, size_t len, unsigned int flags) { struct file *infp, *outfp; struct vnode *invp, *outvp; int error; size_t retlen; void *rl_rcookie, *rl_wcookie; off_t savinoff, savoutoff; infp = outfp = NULL; rl_rcookie = rl_wcookie = NULL; savinoff = -1; error = 0; retlen = 0; if (flags != 0) { error = EINVAL; goto out; } if (len > SSIZE_MAX) /* * Although the len argument is size_t, the return argument * is ssize_t (which is signed). Therefore a size that won't * fit in ssize_t can't be returned. */ len = SSIZE_MAX; /* Get the file structures for the file descriptors. */ error = fget_read(td, infd, &cap_read_rights, &infp); if (error != 0) goto out; if (infp->f_ops == &badfileops) { error = EBADF; goto out; } if (infp->f_vnode == NULL) { error = EINVAL; goto out; } error = fget_write(td, outfd, &cap_write_rights, &outfp); if (error != 0) goto out; if (outfp->f_ops == &badfileops) { error = EBADF; goto out; } if (outfp->f_vnode == NULL) { error = EINVAL; goto out; } /* Set the offset pointers to the correct place. */ if (inoffp == NULL) inoffp = &infp->f_offset; if (outoffp == NULL) outoffp = &outfp->f_offset; savinoff = *inoffp; savoutoff = *outoffp; invp = infp->f_vnode; outvp = outfp->f_vnode; /* Sanity check the f_flag bits. */ if ((outfp->f_flag & (FWRITE | FAPPEND)) != FWRITE || (infp->f_flag & FREAD) == 0) { error = EBADF; goto out; } /* If len == 0, just return 0. */ if (len == 0) goto out; /* * If infp and outfp refer to the same file, the byte ranges cannot * overlap. */ if (invp == outvp && ((savinoff <= savoutoff && savinoff + len > savoutoff) || (savinoff > savoutoff && savoutoff + len > savinoff))) { error = EINVAL; goto out; } /* Range lock the byte ranges for both invp and outvp. */ for (;;) { rl_wcookie = vn_rangelock_wlock(outvp, *outoffp, *outoffp + len); rl_rcookie = vn_rangelock_tryrlock(invp, *inoffp, *inoffp + len); if (rl_rcookie != NULL) break; vn_rangelock_unlock(outvp, rl_wcookie); rl_rcookie = vn_rangelock_rlock(invp, *inoffp, *inoffp + len); vn_rangelock_unlock(invp, rl_rcookie); } retlen = len; error = vn_copy_file_range(invp, inoffp, outvp, outoffp, &retlen, flags, infp->f_cred, outfp->f_cred, td); out: if (rl_rcookie != NULL) vn_rangelock_unlock(invp, rl_rcookie); if (rl_wcookie != NULL) vn_rangelock_unlock(outvp, rl_wcookie); if (savinoff != -1 && (error == EINTR || error == ERESTART)) { *inoffp = savinoff; *outoffp = savoutoff; } if (outfp != NULL) fdrop(outfp, td); if (infp != NULL) fdrop(infp, td); td->td_retval[0] = retlen; return (error); } int sys_copy_file_range(struct thread *td, struct copy_file_range_args *uap) { off_t inoff, outoff, *inoffp, *outoffp; int error; inoffp = outoffp = NULL; if (uap->inoffp != NULL) { error = copyin(uap->inoffp, &inoff, sizeof(off_t)); if (error != 0) return (error); inoffp = &inoff; } if (uap->outoffp != NULL) { error = copyin(uap->outoffp, &outoff, sizeof(off_t)); if (error != 0) return (error); outoffp = &outoff; } error = kern_copy_file_range(td, uap->infd, inoffp, uap->outfd, outoffp, uap->len, uap->flags); if (error == 0 && uap->inoffp != NULL) error = copyout(inoffp, uap->inoffp, sizeof(off_t)); if (error == 0 && uap->outoffp != NULL) error = copyout(outoffp, uap->outoffp, sizeof(off_t)); return (error); } Index: head/sys/sys/syscallsubr.h =================================================================== --- head/sys/sys/syscallsubr.h (revision 367772) +++ head/sys/sys/syscallsubr.h (revision 367773) @@ -1,349 +1,352 @@ /*- * SPDX-License-Identifier: BSD-2-Clause-FreeBSD * * Copyright (c) 2002 Ian Dowse. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * * $FreeBSD$ */ #ifndef _SYS_SYSCALLSUBR_H_ #define _SYS_SYSCALLSUBR_H_ #include #include #include #include #include #include #include struct __wrusage; struct file; struct filecaps; enum idtype; struct itimerval; struct image_args; struct jail; struct kevent; struct kevent_copyops; struct kld_file_stat; struct ksiginfo; struct mbuf; struct msghdr; struct msqid_ds; struct pollfd; struct ogetdirentries_args; struct rlimit; struct rusage; struct sched_param; union semun; struct sockaddr; struct stat; struct thr_param; struct uio; struct umtx_copyops; struct vm_map; struct vmspace; typedef int (*mmap_check_fp_fn)(struct file *, int, int, int); struct mmap_req { vm_offset_t mr_hint; vm_size_t mr_len; int mr_prot; int mr_flags; int mr_fd; off_t mr_pos; mmap_check_fp_fn mr_check_fp_fn; }; int kern___getcwd(struct thread *td, char *buf, enum uio_seg bufseg, size_t buflen, size_t path_max); int kern__umtx_op(struct thread *td, void *obj, int op, unsigned long val, void *uaddr1, void *uaddr2, const struct umtx_copyops *ops); int kern_accept(struct thread *td, int s, struct sockaddr **name, socklen_t *namelen, struct file **fp); int kern_accept4(struct thread *td, int s, struct sockaddr **name, socklen_t *namelen, int flags, struct file **fp); int kern_accessat(struct thread *td, int fd, const char *path, enum uio_seg pathseg, int flags, int mode); int kern_adjtime(struct thread *td, struct timeval *delta, struct timeval *olddelta); int kern_alternate_path(struct thread *td, const char *prefix, const char *path, enum uio_seg pathseg, char **pathbuf, int create, int dirfd); int kern_bindat(struct thread *td, int dirfd, int fd, struct sockaddr *sa); int kern_break(struct thread *td, uintptr_t *addr); int kern_cap_ioctls_limit(struct thread *td, int fd, u_long *cmds, size_t ncmds); int kern_cap_rights_limit(struct thread *td, int fd, cap_rights_t *rights); int kern_chdir(struct thread *td, const char *path, enum uio_seg pathseg); int kern_clock_getcpuclockid2(struct thread *td, id_t id, int which, clockid_t *clk_id); int kern_clock_getres(struct thread *td, clockid_t clock_id, struct timespec *ts); int kern_clock_gettime(struct thread *td, clockid_t clock_id, struct timespec *ats); int kern_clock_nanosleep(struct thread *td, clockid_t clock_id, int flags, const struct timespec *rqtp, struct timespec *rmtp); int kern_clock_settime(struct thread *td, clockid_t clock_id, struct timespec *ats); void kern_thread_cputime(struct thread *targettd, struct timespec *ats); void kern_process_cputime(struct proc *targetp, struct timespec *ats); int kern_close_range(struct thread *td, u_int lowfd, u_int highfd); int kern_close(struct thread *td, int fd); int kern_connectat(struct thread *td, int dirfd, int fd, struct sockaddr *sa); int kern_copy_file_range(struct thread *td, int infd, off_t *inoffp, int outfd, off_t *outoffp, size_t len, unsigned int flags); int kern_cpuset_getaffinity(struct thread *td, cpulevel_t level, cpuwhich_t which, id_t id, size_t cpusetsize, cpuset_t *maskp); int kern_cpuset_setaffinity(struct thread *td, cpulevel_t level, cpuwhich_t which, id_t id, size_t cpusetsize, const cpuset_t *maskp); int kern_cpuset_getdomain(struct thread *td, cpulevel_t level, cpuwhich_t which, id_t id, size_t domainsetsize, domainset_t *maskp, int *policyp); int kern_cpuset_setdomain(struct thread *td, cpulevel_t level, cpuwhich_t which, id_t id, size_t domainsetsize, const domainset_t *maskp, int policy); int kern_cpuset_getid(struct thread *td, cpulevel_t level, cpuwhich_t which, id_t id, cpusetid_t *setid); int kern_cpuset_setid(struct thread *td, cpuwhich_t which, id_t id, cpusetid_t setid); int kern_dup(struct thread *td, u_int mode, int flags, int old, int new); int kern_execve(struct thread *td, struct image_args *args, struct mac *mac_p, struct vmspace *oldvmspace); int kern_fchmodat(struct thread *td, int fd, const char *path, enum uio_seg pathseg, mode_t mode, int flag); int kern_fchownat(struct thread *td, int fd, const char *path, enum uio_seg pathseg, int uid, int gid, int flag); int kern_fcntl(struct thread *td, int fd, int cmd, intptr_t arg); int kern_fcntl_freebsd(struct thread *td, int fd, int cmd, long arg); +int kern_fhopen(struct thread *td, const struct fhandle *u_fhp, int flags); int kern_fhstat(struct thread *td, fhandle_t fh, struct stat *buf); int kern_fhstatfs(struct thread *td, fhandle_t fh, struct statfs *buf); int kern_fpathconf(struct thread *td, int fd, int name, long *valuep); int kern_fstat(struct thread *td, int fd, struct stat *sbp); int kern_fstatfs(struct thread *td, int fd, struct statfs *buf); int kern_fsync(struct thread *td, int fd, bool fullsync); int kern_ftruncate(struct thread *td, int fd, off_t length); int kern_futimes(struct thread *td, int fd, struct timeval *tptr, enum uio_seg tptrseg); int kern_futimens(struct thread *td, int fd, struct timespec *tptr, enum uio_seg tptrseg); int kern_getdirentries(struct thread *td, int fd, char *buf, size_t count, off_t *basep, ssize_t *residp, enum uio_seg bufseg); +int kern_getfhat(struct thread *td, int flags, int fd, const char *path, + enum uio_seg pathseg, fhandle_t *fhp, enum uio_seg fhseg); int kern_getfsstat(struct thread *td, struct statfs **buf, size_t bufsize, size_t *countp, enum uio_seg bufseg, int mode); int kern_getitimer(struct thread *, u_int, struct itimerval *); int kern_getppid(struct thread *); int kern_getpeername(struct thread *td, int fd, struct sockaddr **sa, socklen_t *alen); int kern_getpriority(struct thread *td, int which, int who); int kern_getrusage(struct thread *td, int who, struct rusage *rup); int kern_getsid(struct thread *td, pid_t pid); int kern_getsockname(struct thread *td, int fd, struct sockaddr **sa, socklen_t *alen); int kern_getsockopt(struct thread *td, int s, int level, int name, void *optval, enum uio_seg valseg, socklen_t *valsize); int kern_ioctl(struct thread *td, int fd, u_long com, caddr_t data); int kern_jail(struct thread *td, struct jail *j); int kern_jail_get(struct thread *td, struct uio *options, int flags); int kern_jail_set(struct thread *td, struct uio *options, int flags); int kern_kevent(struct thread *td, int fd, int nchanges, int nevents, struct kevent_copyops *k_ops, const struct timespec *timeout); int kern_kevent_anonymous(struct thread *td, int nevents, struct kevent_copyops *k_ops); int kern_kevent_fp(struct thread *td, struct file *fp, int nchanges, int nevents, struct kevent_copyops *k_ops, const struct timespec *timeout); int kern_kill(struct thread *td, pid_t pid, int signum); int kern_kqueue(struct thread *td, int flags, struct filecaps *fcaps); int kern_kldload(struct thread *td, const char *file, int *fileid); int kern_kldstat(struct thread *td, int fileid, struct kld_file_stat *stat); int kern_kldunload(struct thread *td, int fileid, int flags); int kern_linkat(struct thread *td, int fd1, int fd2, const char *path1, const char *path2, enum uio_seg segflg, int follow); int kern_listen(struct thread *td, int s, int backlog); int kern_lseek(struct thread *td, int fd, off_t offset, int whence); int kern_lutimes(struct thread *td, const char *path, enum uio_seg pathseg, struct timeval *tptr, enum uio_seg tptrseg); int kern_madvise(struct thread *td, uintptr_t addr, size_t len, int behav); int kern_mincore(struct thread *td, uintptr_t addr, size_t len, char *vec); int kern_minherit(struct thread *td, uintptr_t addr, size_t len, int inherit); int kern_mkdirat(struct thread *td, int fd, const char *path, enum uio_seg segflg, int mode); int kern_mkfifoat(struct thread *td, int fd, const char *path, enum uio_seg pathseg, int mode); int kern_mknodat(struct thread *td, int fd, const char *path, enum uio_seg pathseg, int mode, dev_t dev); int kern_mlock(struct proc *proc, struct ucred *cred, uintptr_t addr, size_t len); int kern_mmap(struct thread *td, uintptr_t addr, size_t len, int prot, int flags, int fd, off_t pos); int kern_mmap_racct_check(struct thread *td, struct vm_map *map, vm_size_t size); int kern_mmap_maxprot(struct proc *p, int prot); int kern_mmap_req(struct thread *td, const struct mmap_req *mrp); int kern_mprotect(struct thread *td, uintptr_t addr, size_t size, int prot); int kern_msgctl(struct thread *, int, int, struct msqid_ds *); int kern_msgrcv(struct thread *, int, void *, size_t, long, int, long *); int kern_msgsnd(struct thread *, int, const void *, size_t, int, long); int kern_msync(struct thread *td, uintptr_t addr, size_t size, int flags); int kern_munlock(struct thread *td, uintptr_t addr, size_t size); int kern_munmap(struct thread *td, uintptr_t addr, size_t size); int kern_nanosleep(struct thread *td, struct timespec *rqt, struct timespec *rmt); int kern_ogetdirentries(struct thread *td, struct ogetdirentries_args *uap, long *ploff); int kern_openat(struct thread *td, int fd, const char *path, enum uio_seg pathseg, int flags, int mode); int kern_pathconf(struct thread *td, const char *path, enum uio_seg pathseg, int name, u_long flags, long *valuep); int kern_pipe(struct thread *td, int fildes[2], int flags, struct filecaps *fcaps1, struct filecaps *fcaps2); int kern_poll(struct thread *td, struct pollfd *fds, u_int nfds, struct timespec *tsp, sigset_t *uset); int kern_posix_error(struct thread *td, int error); int kern_posix_fadvise(struct thread *td, int fd, off_t offset, off_t len, int advice); int kern_posix_fallocate(struct thread *td, int fd, off_t offset, off_t len); int kern_procctl(struct thread *td, enum idtype idtype, id_t id, int com, void *data); int kern_pread(struct thread *td, int fd, void *buf, size_t nbyte, off_t offset); int kern_preadv(struct thread *td, int fd, struct uio *auio, off_t offset); int kern_pselect(struct thread *td, int nd, fd_set *in, fd_set *ou, fd_set *ex, struct timeval *tvp, sigset_t *uset, int abi_nfdbits); int kern_ptrace(struct thread *td, int req, pid_t pid, void *addr, int data); int kern_pwrite(struct thread *td, int fd, const void *buf, size_t nbyte, off_t offset); int kern_pwritev(struct thread *td, int fd, struct uio *auio, off_t offset); int kern_readlinkat(struct thread *td, int fd, const char *path, enum uio_seg pathseg, char *buf, enum uio_seg bufseg, size_t count); int kern_readv(struct thread *td, int fd, struct uio *auio); int kern_recvit(struct thread *td, int s, struct msghdr *mp, enum uio_seg fromseg, struct mbuf **controlp); int kern_renameat(struct thread *td, int oldfd, const char *old, int newfd, const char *new, enum uio_seg pathseg); int kern_frmdirat(struct thread *td, int dfd, const char *path, int fd, enum uio_seg pathseg, int flag); int kern_sched_getparam(struct thread *td, struct thread *targettd, struct sched_param *param); int kern_sched_getscheduler(struct thread *td, struct thread *targettd, int *policy); int kern_sched_setparam(struct thread *td, struct thread *targettd, struct sched_param *param); int kern_sched_setscheduler(struct thread *td, struct thread *targettd, int policy, struct sched_param *param); int kern_sched_rr_get_interval(struct thread *td, pid_t pid, struct timespec *ts); int kern_sched_rr_get_interval_td(struct thread *td, struct thread *targettd, struct timespec *ts); int kern_semctl(struct thread *td, int semid, int semnum, int cmd, union semun *arg, register_t *rval); int kern_select(struct thread *td, int nd, fd_set *fd_in, fd_set *fd_ou, fd_set *fd_ex, struct timeval *tvp, int abi_nfdbits); int kern_sendit(struct thread *td, int s, struct msghdr *mp, int flags, struct mbuf *control, enum uio_seg segflg); int kern_setgroups(struct thread *td, u_int ngrp, gid_t *groups); int kern_setitimer(struct thread *, u_int, struct itimerval *, struct itimerval *); int kern_setpriority(struct thread *td, int which, int who, int prio); int kern_setrlimit(struct thread *, u_int, struct rlimit *); int kern_setsockopt(struct thread *td, int s, int level, int name, const void *optval, enum uio_seg valseg, socklen_t valsize); int kern_settimeofday(struct thread *td, struct timeval *tv, struct timezone *tzp); int kern_shm_open(struct thread *td, const char *userpath, int flags, mode_t mode, struct filecaps *fcaps); int kern_shm_open2(struct thread *td, const char *path, int flags, mode_t mode, int shmflags, struct filecaps *fcaps, const char *name); int kern_shmat(struct thread *td, int shmid, const void *shmaddr, int shmflg); int kern_shmctl(struct thread *td, int shmid, int cmd, void *buf, size_t *bufsz); int kern_shutdown(struct thread *td, int s, int how); int kern_sigaction(struct thread *td, int sig, const struct sigaction *act, struct sigaction *oact, int flags); int kern_sigaltstack(struct thread *td, stack_t *ss, stack_t *oss); int kern_sigprocmask(struct thread *td, int how, sigset_t *set, sigset_t *oset, int flags); int kern_sigsuspend(struct thread *td, sigset_t mask); int kern_sigtimedwait(struct thread *td, sigset_t waitset, struct ksiginfo *ksi, struct timespec *timeout); int kern_sigqueue(struct thread *td, pid_t pid, int signum, union sigval *value); int kern_socket(struct thread *td, int domain, int type, int protocol); int kern_statat(struct thread *td, int flag, int fd, const char *path, enum uio_seg pathseg, struct stat *sbp, void (*hook)(struct vnode *vp, struct stat *sbp)); int kern_statfs(struct thread *td, const char *path, enum uio_seg pathseg, struct statfs *buf); int kern_symlinkat(struct thread *td, const char *path1, int fd, const char *path2, enum uio_seg segflg); int kern_sync(struct thread *td); int kern_ktimer_create(struct thread *td, clockid_t clock_id, struct sigevent *evp, int *timerid, int preset_id); int kern_ktimer_delete(struct thread *, int); int kern_ktimer_settime(struct thread *td, int timer_id, int flags, struct itimerspec *val, struct itimerspec *oval); int kern_ktimer_gettime(struct thread *td, int timer_id, struct itimerspec *val); int kern_ktimer_getoverrun(struct thread *td, int timer_id); int kern_thr_alloc(struct proc *, int pages, struct thread **); int kern_thr_exit(struct thread *td); int kern_thr_new(struct thread *td, struct thr_param *param); int kern_thr_suspend(struct thread *td, struct timespec *tsp); int kern_truncate(struct thread *td, const char *path, enum uio_seg pathseg, off_t length); int kern_funlinkat(struct thread *td, int dfd, const char *path, int fd, enum uio_seg pathseg, int flag, ino_t oldinum); int kern_utimesat(struct thread *td, int fd, const char *path, enum uio_seg pathseg, struct timeval *tptr, enum uio_seg tptrseg); int kern_utimensat(struct thread *td, int fd, const char *path, enum uio_seg pathseg, struct timespec *tptr, enum uio_seg tptrseg, int follow); int kern_wait(struct thread *td, pid_t pid, int *status, int options, struct rusage *rup); int kern_wait6(struct thread *td, enum idtype idtype, id_t id, int *status, int options, struct __wrusage *wrup, siginfo_t *sip); int kern_writev(struct thread *td, int fd, struct uio *auio); int kern_socketpair(struct thread *td, int domain, int type, int protocol, int *rsv); int kern_unmount(struct thread *td, const char *path, int flags); /* flags for kern_sigaction */ #define KSA_OSIGSET 0x0001 /* uses osigact_t */ #define KSA_FREEBSD4 0x0002 /* uses ucontext4 */ struct freebsd11_dirent; int freebsd11_kern_getdirentries(struct thread *td, int fd, char *ubuf, u_int count, long *basep, void (*func)(struct freebsd11_dirent *)); #endif /* !_SYS_SYSCALLSUBR_H_ */