1 /*-
2 * SPDX-License-Identifier: BSD-3-Clause
3 *
4 * Copyright (c) 1989, 1993
5 * The Regents of the University of California. All rights reserved.
6 * (c) UNIX System Laboratories, Inc.
7 * All or some portions of this file are derived from material licensed
8 * to the University of California by American Telephone and Telegraph
9 * Co. or Unix System Laboratories, Inc. and are reproduced herein with
10 * the permission of UNIX System Laboratories, Inc.
11 *
12 * Redistribution and use in source and binary forms, with or without
13 * modification, are permitted provided that the following conditions
14 * are met:
15 * 1. Redistributions of source code must retain the above copyright
16 * notice, this list of conditions and the following disclaimer.
17 * 2. Redistributions in binary form must reproduce the above copyright
18 * notice, this list of conditions and the following disclaimer in the
19 * documentation and/or other materials provided with the distribution.
20 * 3. Neither the name of the University nor the names of its contributors
21 * may be used to endorse or promote products derived from this software
22 * without specific prior written permission.
23 *
24 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
25 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
26 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
27 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
28 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
29 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
30 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
31 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
32 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
33 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
34 * SUCH DAMAGE.
35 */
36
37 #include "opt_capsicum.h"
38 #include "opt_ktrace.h"
39
40 #include <sys/systm.h>
41 #ifdef COMPAT_FREEBSD11
42 #include <sys/abi_compat.h>
43 #endif
44 #include <sys/bio.h>
45 #include <sys/buf.h>
46 #include <sys/capsicum.h>
47 #include <sys/disk.h>
48 #include <sys/dirent.h>
49 #include <sys/fcntl.h>
50 #include <sys/file.h>
51 #include <sys/filedesc.h>
52 #include <sys/filio.h>
53 #include <sys/jail.h>
54 #include <sys/kernel.h>
55 #ifdef KTRACE
56 #include <sys/ktrace.h>
57 #endif
58 #include <sys/limits.h>
59 #include <sys/linker.h>
60 #include <sys/malloc.h>
61 #include <sys/mount.h>
62 #include <sys/mutex.h>
63 #include <sys/namei.h>
64 #include <sys/priv.h>
65 #include <sys/proc.h>
66 #include <sys/rwlock.h>
67 #include <sys/sdt.h>
68 #include <sys/stat.h>
69 #include <sys/stdarg.h>
70 #include <sys/sx.h>
71 #include <sys/syscallsubr.h>
72 #include <sys/sysctl.h>
73 #include <sys/sysproto.h>
74 #include <sys/unistd.h>
75 #include <sys/vnode.h>
76
77 #include <security/audit/audit.h>
78 #include <security/mac/mac_framework.h>
79
80 #include <vm/vm.h>
81 #include <vm/vm_object.h>
82 #include <vm/vm_page.h>
83 #include <vm/vnode_pager.h>
84 #include <vm/uma.h>
85
86 #include <fs/devfs/devfs.h>
87
88 MALLOC_DEFINE(M_FADVISE, "fadvise", "posix_fadvise(2) information");
89
90 static int kern_chflagsat(struct thread *td, int fd, const char *path,
91 enum uio_seg pathseg, u_long flags, int atflag);
92 static int setfflags(struct thread *td, struct vnode *, u_long);
93 static int getutimes(const struct timeval *, enum uio_seg, struct timespec *);
94 static int getutimens(const struct timespec *, enum uio_seg,
95 struct timespec *, int *);
96 static int setutimes(struct thread *td, struct vnode *,
97 const struct timespec *, int, int);
98 static int vn_access(struct vnode *vp, int user_flags, struct ucred *cred,
99 struct thread *td);
100 static int kern_fhlinkat(struct thread *td, int fd, const char *path,
101 enum uio_seg pathseg, fhandle_t *fhp);
102 static int kern_readlink_vp(struct vnode *vp, char *buf, enum uio_seg bufseg,
103 size_t count, struct thread *td);
104 static int kern_linkat_vp(struct thread *td, struct vnode *vp, int fd,
105 const char *path, enum uio_seg segflag);
106
107 uint64_t
at2cnpflags(u_int at_flags,u_int mask)108 at2cnpflags(u_int at_flags, u_int mask)
109 {
110 uint64_t res;
111
112 MPASS((at_flags & (AT_SYMLINK_FOLLOW | AT_SYMLINK_NOFOLLOW)) !=
113 (AT_SYMLINK_FOLLOW | AT_SYMLINK_NOFOLLOW));
114
115 res = 0;
116 at_flags &= mask;
117 if ((at_flags & AT_RESOLVE_BENEATH) != 0)
118 res |= RBENEATH;
119 if ((at_flags & AT_SYMLINK_FOLLOW) != 0)
120 res |= FOLLOW;
121 /* NOFOLLOW is pseudo flag */
122 if ((mask & AT_SYMLINK_NOFOLLOW) != 0) {
123 res |= (at_flags & AT_SYMLINK_NOFOLLOW) != 0 ? NOFOLLOW :
124 FOLLOW;
125 }
126 if ((mask & AT_EMPTY_PATH) != 0 && (at_flags & AT_EMPTY_PATH) != 0)
127 res |= EMPTYPATH;
128 return (res);
129 }
130
131 int
kern_sync(struct thread * td)132 kern_sync(struct thread *td)
133 {
134 struct mount *mp, *nmp;
135 int save;
136
137 mtx_lock(&mountlist_mtx);
138 for (mp = TAILQ_FIRST(&mountlist); mp != NULL; mp = nmp) {
139 if (vfs_busy(mp, MBF_NOWAIT | MBF_MNTLSTLOCK)) {
140 nmp = TAILQ_NEXT(mp, mnt_list);
141 continue;
142 }
143 if ((mp->mnt_flag & MNT_RDONLY) == 0 &&
144 vn_start_write(NULL, &mp, V_NOWAIT) == 0) {
145 save = curthread_pflags_set(TDP_SYNCIO);
146 vfs_periodic(mp, MNT_NOWAIT);
147 VFS_SYNC(mp, MNT_NOWAIT);
148 curthread_pflags_restore(save);
149 vn_finished_write(mp);
150 }
151 mtx_lock(&mountlist_mtx);
152 nmp = TAILQ_NEXT(mp, mnt_list);
153 vfs_unbusy(mp);
154 }
155 mtx_unlock(&mountlist_mtx);
156 return (0);
157 }
158
159 /*
160 * Sync each mounted filesystem.
161 */
162 #ifndef _SYS_SYSPROTO_H_
163 struct sync_args {
164 int dummy;
165 };
166 #endif
167 /* ARGSUSED */
168 int
sys_sync(struct thread * td,struct sync_args * uap)169 sys_sync(struct thread *td, struct sync_args *uap)
170 {
171
172 return (kern_sync(td));
173 }
174
175 /*
176 * Change filesystem quotas.
177 */
178 #ifndef _SYS_SYSPROTO_H_
179 struct quotactl_args {
180 char *path;
181 int cmd;
182 int uid;
183 caddr_t arg;
184 };
185 #endif
186 int
sys_quotactl(struct thread * td,struct quotactl_args * uap)187 sys_quotactl(struct thread *td, struct quotactl_args *uap)
188 {
189 struct mount *mp;
190 struct nameidata nd;
191 int error;
192 bool mp_busy;
193
194 AUDIT_ARG_CMD(uap->cmd);
195 AUDIT_ARG_UID(uap->uid);
196 if (!prison_allow(td->td_ucred, PR_ALLOW_QUOTAS))
197 return (EPERM);
198 NDINIT(&nd, LOOKUP, FOLLOW | LOCKLEAF | AUDITVNODE1, UIO_USERSPACE,
199 uap->path);
200 if ((error = namei(&nd)) != 0)
201 return (error);
202 NDFREE_PNBUF(&nd);
203 mp = nd.ni_vp->v_mount;
204 vfs_ref(mp);
205 vput(nd.ni_vp);
206 error = vfs_busy(mp, 0);
207 if (error != 0) {
208 vfs_rel(mp);
209 return (error);
210 }
211 mp_busy = true;
212 error = VFS_QUOTACTL(mp, uap->cmd, uap->uid, uap->arg, &mp_busy);
213
214 /*
215 * Since quota on/off operations typically need to open quota
216 * files, the implementation may need to unbusy the mount point
217 * before calling into namei. Otherwise, unmount might be
218 * started between two vfs_busy() invocations (first is ours,
219 * second is from mount point cross-walk code in lookup()),
220 * causing deadlock.
221 *
222 * Avoid unbusying mp if the implementation indicates it has
223 * already done so.
224 */
225 if (mp_busy)
226 vfs_unbusy(mp);
227 vfs_rel(mp);
228 return (error);
229 }
230
231 /*
232 * Used by statfs conversion routines to scale the block size up if
233 * necessary so that all of the block counts are <= 'max_size'. Note
234 * that 'max_size' should be a bitmask, i.e. 2^n - 1 for some non-zero
235 * value of 'n'.
236 */
237 void
statfs_scale_blocks(struct statfs * sf,long max_size)238 statfs_scale_blocks(struct statfs *sf, long max_size)
239 {
240 uint64_t count;
241 int shift;
242
243 KASSERT(powerof2(max_size + 1), ("%s: invalid max_size", __func__));
244
245 /*
246 * Attempt to scale the block counts to give a more accurate
247 * overview to userland of the ratio of free space to used
248 * space. To do this, find the largest block count and compute
249 * a divisor that lets it fit into a signed integer <= max_size.
250 */
251 if (sf->f_bavail < 0)
252 count = -sf->f_bavail;
253 else
254 count = sf->f_bavail;
255 count = MAX(sf->f_blocks, MAX(sf->f_bfree, count));
256 if (count <= max_size)
257 return;
258
259 count >>= flsl(max_size);
260 shift = 0;
261 while (count > 0) {
262 shift++;
263 count >>=1;
264 }
265
266 sf->f_bsize <<= shift;
267 sf->f_blocks >>= shift;
268 sf->f_bfree >>= shift;
269 sf->f_bavail >>= shift;
270 }
271
272 static int
kern_do_statfs(struct thread * td,struct mount * mp,struct statfs * buf)273 kern_do_statfs(struct thread *td, struct mount *mp, struct statfs *buf)
274 {
275 int error;
276
277 if (mp == NULL)
278 return (EBADF);
279 error = vfs_busy(mp, 0);
280 vfs_rel(mp);
281 if (error != 0)
282 return (error);
283 #ifdef MAC
284 error = mac_mount_check_stat(td->td_ucred, mp);
285 if (error != 0)
286 goto out;
287 #endif
288 error = VFS_STATFS(mp, buf);
289 if (error != 0)
290 goto out;
291 if (priv_check_cred_vfs_generation(td->td_ucred)) {
292 buf->f_fsid.val[0] = buf->f_fsid.val[1] = 0;
293 prison_enforce_statfs(td->td_ucred, mp, buf);
294 }
295 out:
296 vfs_unbusy(mp);
297 return (error);
298 }
299
300 /*
301 * Get filesystem statistics.
302 */
303 #ifndef _SYS_SYSPROTO_H_
304 struct statfs_args {
305 char *path;
306 struct statfs *buf;
307 };
308 #endif
309 int
sys_statfs(struct thread * td,struct statfs_args * uap)310 sys_statfs(struct thread *td, struct statfs_args *uap)
311 {
312 struct statfs *sfp;
313 int error;
314
315 sfp = malloc(sizeof(struct statfs), M_STATFS, M_WAITOK);
316 error = kern_statfs(td, uap->path, UIO_USERSPACE, sfp);
317 if (error == 0)
318 error = copyout(sfp, uap->buf, sizeof(struct statfs));
319 free(sfp, M_STATFS);
320 return (error);
321 }
322
323 int
kern_statfs(struct thread * td,const char * path,enum uio_seg pathseg,struct statfs * buf)324 kern_statfs(struct thread *td, const char *path, enum uio_seg pathseg,
325 struct statfs *buf)
326 {
327 struct mount *mp;
328 struct nameidata nd;
329 int error;
330
331 NDINIT(&nd, LOOKUP, FOLLOW | AUDITVNODE1, pathseg, path);
332 error = namei(&nd);
333 if (error != 0)
334 return (error);
335 NDFREE_PNBUF(&nd);
336 mp = vfs_ref_from_vp(nd.ni_vp);
337 vrele(nd.ni_vp);
338 return (kern_do_statfs(td, mp, buf));
339 }
340
341 /*
342 * Get filesystem statistics.
343 */
344 #ifndef _SYS_SYSPROTO_H_
345 struct fstatfs_args {
346 int fd;
347 struct statfs *buf;
348 };
349 #endif
350 int
sys_fstatfs(struct thread * td,struct fstatfs_args * uap)351 sys_fstatfs(struct thread *td, struct fstatfs_args *uap)
352 {
353 struct statfs *sfp;
354 int error;
355
356 sfp = malloc(sizeof(struct statfs), M_STATFS, M_WAITOK);
357 error = kern_fstatfs(td, uap->fd, sfp);
358 if (error == 0)
359 error = copyout(sfp, uap->buf, sizeof(struct statfs));
360 free(sfp, M_STATFS);
361 return (error);
362 }
363
364 int
kern_fstatfs(struct thread * td,int fd,struct statfs * buf)365 kern_fstatfs(struct thread *td, int fd, struct statfs *buf)
366 {
367 struct file *fp;
368 struct mount *mp;
369 struct vnode *vp;
370 int error;
371
372 AUDIT_ARG_FD(fd);
373 error = getvnode_path(td, fd, &cap_fstatfs_rights, NULL, &fp);
374 if (error != 0)
375 return (error);
376 vp = fp->f_vnode;
377 #ifdef AUDIT
378 if (AUDITING_TD(td)) {
379 vn_lock(vp, LK_SHARED | LK_RETRY);
380 AUDIT_ARG_VNODE1(vp);
381 VOP_UNLOCK(vp);
382 }
383 #endif
384 mp = vfs_ref_from_vp(vp);
385 fdrop(fp, td);
386 return (kern_do_statfs(td, mp, buf));
387 }
388
389 /*
390 * Get statistics on all filesystems.
391 */
392 #ifndef _SYS_SYSPROTO_H_
393 struct getfsstat_args {
394 struct statfs *buf;
395 long bufsize;
396 int mode;
397 };
398 #endif
399 int
sys_getfsstat(struct thread * td,struct getfsstat_args * uap)400 sys_getfsstat(struct thread *td, struct getfsstat_args *uap)
401 {
402 size_t count;
403 int error;
404
405 if (uap->bufsize < 0 || uap->bufsize > SIZE_MAX)
406 return (EINVAL);
407 error = kern_getfsstat(td, &uap->buf, uap->bufsize, &count,
408 UIO_USERSPACE, uap->mode);
409 if (error == 0)
410 td->td_retval[0] = count;
411 return (error);
412 }
413
414 /*
415 * If (bufsize > 0 && bufseg == UIO_SYSSPACE)
416 * The caller is responsible for freeing memory which will be allocated
417 * in '*buf'.
418 */
419 int
kern_getfsstat(struct thread * td,struct statfs ** buf,size_t bufsize,size_t * countp,enum uio_seg bufseg,int mode)420 kern_getfsstat(struct thread *td, struct statfs **buf, size_t bufsize,
421 size_t *countp, enum uio_seg bufseg, int mode)
422 {
423 struct mount *mp, *nmp;
424 struct statfs *sfsp, *sp, *sptmp, *tofree;
425 size_t count, maxcount;
426 int error;
427
428 switch (mode) {
429 case MNT_WAIT:
430 case MNT_NOWAIT:
431 break;
432 default:
433 if (bufseg == UIO_SYSSPACE)
434 *buf = NULL;
435 return (EINVAL);
436 }
437 restart:
438 maxcount = bufsize / sizeof(struct statfs);
439 if (bufsize == 0) {
440 sfsp = NULL;
441 tofree = NULL;
442 } else if (bufseg == UIO_USERSPACE) {
443 sfsp = *buf;
444 tofree = NULL;
445 } else /* if (bufseg == UIO_SYSSPACE) */ {
446 count = 0;
447 mtx_lock(&mountlist_mtx);
448 TAILQ_FOREACH(mp, &mountlist, mnt_list) {
449 count++;
450 }
451 mtx_unlock(&mountlist_mtx);
452 if (maxcount > count)
453 maxcount = count;
454 tofree = sfsp = *buf = malloc(maxcount * sizeof(struct statfs),
455 M_STATFS, M_WAITOK);
456 }
457
458 count = 0;
459
460 /*
461 * If there is no target buffer they only want the count.
462 *
463 * This could be TAILQ_FOREACH but it is open-coded to match the original
464 * code below.
465 */
466 if (sfsp == NULL) {
467 mtx_lock(&mountlist_mtx);
468 for (mp = TAILQ_FIRST(&mountlist); mp != NULL; mp = nmp) {
469 if (prison_canseemount(td->td_ucred, mp) != 0) {
470 nmp = TAILQ_NEXT(mp, mnt_list);
471 continue;
472 }
473 #ifdef MAC
474 if (mac_mount_check_stat(td->td_ucred, mp) != 0) {
475 nmp = TAILQ_NEXT(mp, mnt_list);
476 continue;
477 }
478 #endif
479 count++;
480 nmp = TAILQ_NEXT(mp, mnt_list);
481 }
482 mtx_unlock(&mountlist_mtx);
483 *countp = count;
484 return (0);
485 }
486
487 /*
488 * They want the entire thing.
489 *
490 * Short-circuit the corner case of no room for anything, avoids
491 * relocking below.
492 */
493 if (maxcount < 1) {
494 goto out;
495 }
496
497 mtx_lock(&mountlist_mtx);
498 for (mp = TAILQ_FIRST(&mountlist); mp != NULL; mp = nmp) {
499 if (prison_canseemount(td->td_ucred, mp) != 0) {
500 nmp = TAILQ_NEXT(mp, mnt_list);
501 continue;
502 }
503 #ifdef MAC
504 if (mac_mount_check_stat(td->td_ucred, mp) != 0) {
505 nmp = TAILQ_NEXT(mp, mnt_list);
506 continue;
507 }
508 #endif
509 if (mode == MNT_WAIT) {
510 if (vfs_busy(mp, MBF_MNTLSTLOCK) != 0) {
511 /*
512 * If vfs_busy() failed, and MBF_NOWAIT
513 * wasn't passed, then the mp is gone.
514 * Furthermore, because of MBF_MNTLSTLOCK,
515 * the mountlist_mtx was dropped. We have
516 * no other choice than to start over.
517 */
518 mtx_unlock(&mountlist_mtx);
519 free(tofree, M_STATFS);
520 goto restart;
521 }
522 } else {
523 if (vfs_busy(mp, MBF_NOWAIT | MBF_MNTLSTLOCK) != 0) {
524 nmp = TAILQ_NEXT(mp, mnt_list);
525 continue;
526 }
527 }
528 sp = &mp->mnt_stat;
529 /*
530 * If MNT_NOWAIT is specified, do not refresh
531 * the fsstat cache.
532 */
533 if (mode != MNT_NOWAIT) {
534 error = VFS_STATFS(mp, sp);
535 if (error != 0) {
536 mtx_lock(&mountlist_mtx);
537 nmp = TAILQ_NEXT(mp, mnt_list);
538 vfs_unbusy(mp);
539 continue;
540 }
541 }
542 if (priv_check_cred_vfs_generation(td->td_ucred)) {
543 sptmp = malloc(sizeof(struct statfs), M_STATFS,
544 M_WAITOK);
545 *sptmp = *sp;
546 sptmp->f_fsid.val[0] = sptmp->f_fsid.val[1] = 0;
547 prison_enforce_statfs(td->td_ucred, mp, sptmp);
548 sp = sptmp;
549 } else
550 sptmp = NULL;
551 if (bufseg == UIO_SYSSPACE) {
552 bcopy(sp, sfsp, sizeof(*sp));
553 free(sptmp, M_STATFS);
554 } else /* if (bufseg == UIO_USERSPACE) */ {
555 error = copyout(sp, sfsp, sizeof(*sp));
556 free(sptmp, M_STATFS);
557 if (error != 0) {
558 vfs_unbusy(mp);
559 return (error);
560 }
561 }
562 sfsp++;
563 count++;
564
565 if (count == maxcount) {
566 vfs_unbusy(mp);
567 goto out;
568 }
569
570 mtx_lock(&mountlist_mtx);
571 nmp = TAILQ_NEXT(mp, mnt_list);
572 vfs_unbusy(mp);
573 }
574 mtx_unlock(&mountlist_mtx);
575 out:
576 *countp = count;
577 return (0);
578 }
579
580 #ifdef COMPAT_FREEBSD4
581 /*
582 * Get old format filesystem statistics.
583 */
584 static void freebsd4_cvtstatfs(struct statfs *, struct ostatfs *);
585
586 #ifndef _SYS_SYSPROTO_H_
587 struct freebsd4_statfs_args {
588 char *path;
589 struct ostatfs *buf;
590 };
591 #endif
592 int
freebsd4_statfs(struct thread * td,struct freebsd4_statfs_args * uap)593 freebsd4_statfs(struct thread *td, struct freebsd4_statfs_args *uap)
594 {
595 struct ostatfs osb;
596 struct statfs *sfp;
597 int error;
598
599 sfp = malloc(sizeof(struct statfs), M_STATFS, M_WAITOK);
600 error = kern_statfs(td, uap->path, UIO_USERSPACE, sfp);
601 if (error == 0) {
602 freebsd4_cvtstatfs(sfp, &osb);
603 error = copyout(&osb, uap->buf, sizeof(osb));
604 }
605 free(sfp, M_STATFS);
606 return (error);
607 }
608
609 /*
610 * Get filesystem statistics.
611 */
612 #ifndef _SYS_SYSPROTO_H_
613 struct freebsd4_fstatfs_args {
614 int fd;
615 struct ostatfs *buf;
616 };
617 #endif
618 int
freebsd4_fstatfs(struct thread * td,struct freebsd4_fstatfs_args * uap)619 freebsd4_fstatfs(struct thread *td, struct freebsd4_fstatfs_args *uap)
620 {
621 struct ostatfs osb;
622 struct statfs *sfp;
623 int error;
624
625 sfp = malloc(sizeof(struct statfs), M_STATFS, M_WAITOK);
626 error = kern_fstatfs(td, uap->fd, sfp);
627 if (error == 0) {
628 freebsd4_cvtstatfs(sfp, &osb);
629 error = copyout(&osb, uap->buf, sizeof(osb));
630 }
631 free(sfp, M_STATFS);
632 return (error);
633 }
634
635 /*
636 * Get statistics on all filesystems.
637 */
638 #ifndef _SYS_SYSPROTO_H_
639 struct freebsd4_getfsstat_args {
640 struct ostatfs *buf;
641 long bufsize;
642 int mode;
643 };
644 #endif
645 int
freebsd4_getfsstat(struct thread * td,struct freebsd4_getfsstat_args * uap)646 freebsd4_getfsstat(struct thread *td, struct freebsd4_getfsstat_args *uap)
647 {
648 struct statfs *buf, *sp;
649 struct ostatfs osb;
650 size_t count, size;
651 int error;
652
653 if (uap->bufsize < 0)
654 return (EINVAL);
655 count = uap->bufsize / sizeof(struct ostatfs);
656 if (count > SIZE_MAX / sizeof(struct statfs))
657 return (EINVAL);
658 size = count * sizeof(struct statfs);
659 error = kern_getfsstat(td, &buf, size, &count, UIO_SYSSPACE,
660 uap->mode);
661 if (error == 0)
662 td->td_retval[0] = count;
663 if (size != 0) {
664 sp = buf;
665 while (count != 0 && error == 0) {
666 freebsd4_cvtstatfs(sp, &osb);
667 error = copyout(&osb, uap->buf, sizeof(osb));
668 sp++;
669 uap->buf++;
670 count--;
671 }
672 free(buf, M_STATFS);
673 }
674 return (error);
675 }
676
677 /*
678 * Implement fstatfs() for (NFS) file handles.
679 */
680 #ifndef _SYS_SYSPROTO_H_
681 struct freebsd4_fhstatfs_args {
682 struct fhandle *u_fhp;
683 struct ostatfs *buf;
684 };
685 #endif
686 int
freebsd4_fhstatfs(struct thread * td,struct freebsd4_fhstatfs_args * uap)687 freebsd4_fhstatfs(struct thread *td, struct freebsd4_fhstatfs_args *uap)
688 {
689 struct ostatfs osb;
690 struct statfs *sfp;
691 fhandle_t fh;
692 int error;
693
694 error = copyin(uap->u_fhp, &fh, sizeof(fhandle_t));
695 if (error != 0)
696 return (error);
697 sfp = malloc(sizeof(struct statfs), M_STATFS, M_WAITOK);
698 error = kern_fhstatfs(td, fh, sfp);
699 if (error == 0) {
700 freebsd4_cvtstatfs(sfp, &osb);
701 error = copyout(&osb, uap->buf, sizeof(osb));
702 }
703 free(sfp, M_STATFS);
704 return (error);
705 }
706
707 /*
708 * Convert a new format statfs structure to an old format statfs structure.
709 */
710 static void
freebsd4_cvtstatfs(struct statfs * nsp,struct ostatfs * osp)711 freebsd4_cvtstatfs(struct statfs *nsp, struct ostatfs *osp)
712 {
713
714 statfs_scale_blocks(nsp, LONG_MAX);
715 bzero(osp, sizeof(*osp));
716 osp->f_bsize = nsp->f_bsize;
717 osp->f_iosize = MIN(nsp->f_iosize, LONG_MAX);
718 osp->f_blocks = nsp->f_blocks;
719 osp->f_bfree = nsp->f_bfree;
720 osp->f_bavail = nsp->f_bavail;
721 osp->f_files = MIN(nsp->f_files, LONG_MAX);
722 osp->f_ffree = MIN(nsp->f_ffree, LONG_MAX);
723 osp->f_owner = nsp->f_owner;
724 osp->f_type = nsp->f_type;
725 osp->f_flags = nsp->f_flags;
726 osp->f_syncwrites = MIN(nsp->f_syncwrites, LONG_MAX);
727 osp->f_asyncwrites = MIN(nsp->f_asyncwrites, LONG_MAX);
728 osp->f_syncreads = MIN(nsp->f_syncreads, LONG_MAX);
729 osp->f_asyncreads = MIN(nsp->f_asyncreads, LONG_MAX);
730 strlcpy(osp->f_fstypename, nsp->f_fstypename,
731 MIN(MFSNAMELEN, OMFSNAMELEN));
732 strlcpy(osp->f_mntonname, nsp->f_mntonname,
733 MIN(MNAMELEN, OMNAMELEN));
734 strlcpy(osp->f_mntfromname, nsp->f_mntfromname,
735 MIN(MNAMELEN, OMNAMELEN));
736 osp->f_fsid = nsp->f_fsid;
737 }
738 #endif /* COMPAT_FREEBSD4 */
739
740 #if defined(COMPAT_FREEBSD11)
741 /*
742 * Get old format filesystem statistics.
743 */
744 static void freebsd11_cvtstatfs(struct statfs *, struct freebsd11_statfs *);
745
746 int
freebsd11_statfs(struct thread * td,struct freebsd11_statfs_args * uap)747 freebsd11_statfs(struct thread *td, struct freebsd11_statfs_args *uap)
748 {
749 struct freebsd11_statfs osb;
750 struct statfs *sfp;
751 int error;
752
753 sfp = malloc(sizeof(struct statfs), M_STATFS, M_WAITOK);
754 error = kern_statfs(td, uap->path, UIO_USERSPACE, sfp);
755 if (error == 0) {
756 freebsd11_cvtstatfs(sfp, &osb);
757 error = copyout(&osb, uap->buf, sizeof(osb));
758 }
759 free(sfp, M_STATFS);
760 return (error);
761 }
762
763 /*
764 * Get filesystem statistics.
765 */
766 int
freebsd11_fstatfs(struct thread * td,struct freebsd11_fstatfs_args * uap)767 freebsd11_fstatfs(struct thread *td, struct freebsd11_fstatfs_args *uap)
768 {
769 struct freebsd11_statfs osb;
770 struct statfs *sfp;
771 int error;
772
773 sfp = malloc(sizeof(struct statfs), M_STATFS, M_WAITOK);
774 error = kern_fstatfs(td, uap->fd, sfp);
775 if (error == 0) {
776 freebsd11_cvtstatfs(sfp, &osb);
777 error = copyout(&osb, uap->buf, sizeof(osb));
778 }
779 free(sfp, M_STATFS);
780 return (error);
781 }
782
783 /*
784 * Get statistics on all filesystems.
785 */
786 int
freebsd11_getfsstat(struct thread * td,struct freebsd11_getfsstat_args * uap)787 freebsd11_getfsstat(struct thread *td, struct freebsd11_getfsstat_args *uap)
788 {
789 return (kern_freebsd11_getfsstat(td, uap->buf, uap->bufsize, uap->mode));
790 }
791
792 int
kern_freebsd11_getfsstat(struct thread * td,struct freebsd11_statfs * ubuf,long bufsize,int mode)793 kern_freebsd11_getfsstat(struct thread *td, struct freebsd11_statfs * ubuf,
794 long bufsize, int mode)
795 {
796 struct freebsd11_statfs osb;
797 struct statfs *buf, *sp;
798 size_t count, size;
799 int error;
800
801 if (bufsize < 0)
802 return (EINVAL);
803
804 count = bufsize / sizeof(struct ostatfs);
805 size = count * sizeof(struct statfs);
806 error = kern_getfsstat(td, &buf, size, &count, UIO_SYSSPACE, mode);
807 if (error == 0)
808 td->td_retval[0] = count;
809 if (size > 0) {
810 sp = buf;
811 while (count > 0 && error == 0) {
812 freebsd11_cvtstatfs(sp, &osb);
813 error = copyout(&osb, ubuf, sizeof(osb));
814 sp++;
815 ubuf++;
816 count--;
817 }
818 free(buf, M_STATFS);
819 }
820 return (error);
821 }
822
823 /*
824 * Implement fstatfs() for (NFS) file handles.
825 */
826 int
freebsd11_fhstatfs(struct thread * td,struct freebsd11_fhstatfs_args * uap)827 freebsd11_fhstatfs(struct thread *td, struct freebsd11_fhstatfs_args *uap)
828 {
829 struct freebsd11_statfs osb;
830 struct statfs *sfp;
831 fhandle_t fh;
832 int error;
833
834 error = copyin(uap->u_fhp, &fh, sizeof(fhandle_t));
835 if (error)
836 return (error);
837 sfp = malloc(sizeof(struct statfs), M_STATFS, M_WAITOK);
838 error = kern_fhstatfs(td, fh, sfp);
839 if (error == 0) {
840 freebsd11_cvtstatfs(sfp, &osb);
841 error = copyout(&osb, uap->buf, sizeof(osb));
842 }
843 free(sfp, M_STATFS);
844 return (error);
845 }
846
847 /*
848 * Convert a new format statfs structure to an old format statfs structure.
849 */
850 static void
freebsd11_cvtstatfs(struct statfs * nsp,struct freebsd11_statfs * osp)851 freebsd11_cvtstatfs(struct statfs *nsp, struct freebsd11_statfs *osp)
852 {
853
854 bzero(osp, sizeof(*osp));
855 osp->f_version = FREEBSD11_STATFS_VERSION;
856 osp->f_type = nsp->f_type;
857 osp->f_flags = nsp->f_flags;
858 osp->f_bsize = nsp->f_bsize;
859 osp->f_iosize = nsp->f_iosize;
860 osp->f_blocks = nsp->f_blocks;
861 osp->f_bfree = nsp->f_bfree;
862 osp->f_bavail = nsp->f_bavail;
863 osp->f_files = nsp->f_files;
864 osp->f_ffree = nsp->f_ffree;
865 osp->f_syncwrites = nsp->f_syncwrites;
866 osp->f_asyncwrites = nsp->f_asyncwrites;
867 osp->f_syncreads = nsp->f_syncreads;
868 osp->f_asyncreads = nsp->f_asyncreads;
869 osp->f_namemax = nsp->f_namemax;
870 osp->f_owner = nsp->f_owner;
871 osp->f_fsid = nsp->f_fsid;
872 strlcpy(osp->f_fstypename, nsp->f_fstypename,
873 MIN(MFSNAMELEN, sizeof(osp->f_fstypename)));
874 strlcpy(osp->f_mntonname, nsp->f_mntonname,
875 MIN(MNAMELEN, sizeof(osp->f_mntonname)));
876 strlcpy(osp->f_mntfromname, nsp->f_mntfromname,
877 MIN(MNAMELEN, sizeof(osp->f_mntfromname)));
878 }
879 #endif /* COMPAT_FREEBSD11 */
880
881 /*
882 * Change current working directory to a given file descriptor.
883 */
884 #ifndef _SYS_SYSPROTO_H_
885 struct fchdir_args {
886 int fd;
887 };
888 #endif
889 int
sys_fchdir(struct thread * td,struct fchdir_args * uap)890 sys_fchdir(struct thread *td, struct fchdir_args *uap)
891 {
892 struct vnode *vp, *tdp;
893 struct mount *mp;
894 struct file *fp;
895 int error;
896 uint8_t fdflags;
897
898 AUDIT_ARG_FD(uap->fd);
899 error = getvnode_path(td, uap->fd, &cap_fchdir_rights, &fdflags,
900 &fp);
901 if (error != 0)
902 return (error);
903 if ((fdflags & UF_RESOLVE_BENEATH) != 0) {
904 fdrop(fp, td);
905 return (ENOTCAPABLE);
906 }
907 vp = fp->f_vnode;
908 vrefact(vp);
909 fdrop(fp, td);
910 vn_lock(vp, LK_SHARED | LK_RETRY);
911 AUDIT_ARG_VNODE1(vp);
912 error = change_dir(vp, td);
913 while (!error && (mp = vp->v_mountedhere) != NULL) {
914 if (vfs_busy(mp, 0))
915 continue;
916 error = VFS_ROOT(mp, LK_SHARED, &tdp);
917 vfs_unbusy(mp);
918 if (error != 0)
919 break;
920 vput(vp);
921 vp = tdp;
922 }
923 if (error != 0) {
924 vput(vp);
925 return (error);
926 }
927 VOP_UNLOCK(vp);
928 pwd_chdir(td, vp);
929 return (0);
930 }
931
932 /*
933 * Change current working directory (``.'').
934 */
935 #ifndef _SYS_SYSPROTO_H_
936 struct chdir_args {
937 char *path;
938 };
939 #endif
940 int
sys_chdir(struct thread * td,struct chdir_args * uap)941 sys_chdir(struct thread *td, struct chdir_args *uap)
942 {
943
944 return (kern_chdir(td, uap->path, UIO_USERSPACE));
945 }
946
947 int
kern_chdir(struct thread * td,const char * path,enum uio_seg pathseg)948 kern_chdir(struct thread *td, const char *path, enum uio_seg pathseg)
949 {
950 struct nameidata nd;
951 int error;
952
953 NDINIT(&nd, LOOKUP, FOLLOW | LOCKSHARED | LOCKLEAF | AUDITVNODE1,
954 pathseg, path);
955 if ((error = namei(&nd)) != 0)
956 return (error);
957 if ((error = change_dir(nd.ni_vp, td)) != 0) {
958 vput(nd.ni_vp);
959 NDFREE_PNBUF(&nd);
960 return (error);
961 }
962 VOP_UNLOCK(nd.ni_vp);
963 NDFREE_PNBUF(&nd);
964 pwd_chdir(td, nd.ni_vp);
965 return (0);
966 }
967
968 static int unprivileged_chroot = 0;
969 SYSCTL_INT(_security_bsd, OID_AUTO, unprivileged_chroot, CTLFLAG_RW,
970 &unprivileged_chroot, 0,
971 "Unprivileged processes can use chroot(2)");
972
973 /*
974 * Takes locked vnode, unlocks it before returning.
975 */
976 static int
kern_chroot(struct thread * td,struct vnode * vp)977 kern_chroot(struct thread *td, struct vnode *vp)
978 {
979 struct proc *p;
980 int error;
981
982 error = priv_check(td, PRIV_VFS_CHROOT);
983 if (error != 0) {
984 p = td->td_proc;
985 PROC_LOCK(p);
986 if (unprivileged_chroot == 0 ||
987 (p->p_flag2 & P2_NO_NEW_PRIVS) == 0) {
988 PROC_UNLOCK(p);
989 goto e_vunlock;
990 }
991 PROC_UNLOCK(p);
992 }
993
994 error = change_dir(vp, td);
995 if (error != 0)
996 goto e_vunlock;
997 #ifdef MAC
998 error = mac_vnode_check_chroot(td->td_ucred, vp);
999 if (error != 0)
1000 goto e_vunlock;
1001 #endif
1002 VOP_UNLOCK(vp);
1003 error = pwd_chroot(td, vp);
1004 vrele(vp);
1005 return (error);
1006 e_vunlock:
1007 vput(vp);
1008 return (error);
1009 }
1010
1011 /*
1012 * Change notion of root (``/'') directory.
1013 */
1014 #ifndef _SYS_SYSPROTO_H_
1015 struct chroot_args {
1016 char *path;
1017 };
1018 #endif
1019 int
sys_chroot(struct thread * td,struct chroot_args * uap)1020 sys_chroot(struct thread *td, struct chroot_args *uap)
1021 {
1022 struct nameidata nd;
1023 int error;
1024
1025 NDINIT(&nd, LOOKUP, FOLLOW | LOCKSHARED | LOCKLEAF | AUDITVNODE1,
1026 UIO_USERSPACE, uap->path);
1027 error = namei(&nd);
1028 if (error != 0)
1029 return (error);
1030 NDFREE_PNBUF(&nd);
1031 error = kern_chroot(td, nd.ni_vp);
1032 return (error);
1033 }
1034
1035 /*
1036 * Change notion of root directory to a given file descriptor.
1037 */
1038 #ifndef _SYS_SYSPROTO_H_
1039 struct fchroot_args {
1040 int fd;
1041 };
1042 #endif
1043 int
sys_fchroot(struct thread * td,struct fchroot_args * uap)1044 sys_fchroot(struct thread *td, struct fchroot_args *uap)
1045 {
1046 struct vnode *vp;
1047 struct file *fp;
1048 int error;
1049 uint8_t fdflags;
1050
1051 error = getvnode_path(td, uap->fd, &cap_fchroot_rights, &fdflags, &fp);
1052 if (error != 0)
1053 return (error);
1054 if ((fdflags & UF_RESOLVE_BENEATH) != 0) {
1055 fdrop(fp, td);
1056 return (ENOTCAPABLE);
1057 }
1058 vp = fp->f_vnode;
1059 vrefact(vp);
1060 fdrop(fp, td);
1061 vn_lock(vp, LK_SHARED | LK_RETRY);
1062 error = kern_chroot(td, vp);
1063 return (error);
1064 }
1065
1066 /*
1067 * Common routine for chroot and chdir. Callers must provide a locked vnode
1068 * instance.
1069 */
1070 int
change_dir(struct vnode * vp,struct thread * td)1071 change_dir(struct vnode *vp, struct thread *td)
1072 {
1073 #ifdef MAC
1074 int error;
1075 #endif
1076
1077 ASSERT_VOP_LOCKED(vp, "change_dir(): vp not locked");
1078 if (vp->v_type != VDIR)
1079 return (ENOTDIR);
1080 #ifdef MAC
1081 error = mac_vnode_check_chdir(td->td_ucred, vp);
1082 if (error != 0)
1083 return (error);
1084 #endif
1085 return (VOP_ACCESS(vp, VEXEC, td->td_ucred, td));
1086 }
1087
1088 static __inline void
flags_to_rights(int flags,cap_rights_t * rightsp)1089 flags_to_rights(int flags, cap_rights_t *rightsp)
1090 {
1091 if (flags & O_EXEC) {
1092 cap_rights_set_one(rightsp, CAP_FEXECVE);
1093 if (flags & O_PATH)
1094 return;
1095 } else {
1096 switch ((flags & O_ACCMODE)) {
1097 case O_RDONLY:
1098 cap_rights_set_one(rightsp, CAP_READ);
1099 break;
1100 case O_RDWR:
1101 cap_rights_set_one(rightsp, CAP_READ);
1102 /* FALLTHROUGH */
1103 case O_WRONLY:
1104 cap_rights_set_one(rightsp, CAP_WRITE);
1105 if (!(flags & (O_APPEND | O_TRUNC)))
1106 cap_rights_set_one(rightsp, CAP_SEEK);
1107 break;
1108 }
1109 }
1110
1111 if (flags & O_CREAT)
1112 cap_rights_set_one(rightsp, CAP_CREATE);
1113
1114 if (flags & O_TRUNC)
1115 cap_rights_set_one(rightsp, CAP_FTRUNCATE);
1116
1117 if (flags & (O_SYNC | O_FSYNC))
1118 cap_rights_set_one(rightsp, CAP_FSYNC);
1119
1120 if (flags & (O_EXLOCK | O_SHLOCK))
1121 cap_rights_set_one(rightsp, CAP_FLOCK);
1122 }
1123
1124 /*
1125 * Check permissions, allocate an open file structure, and call the device
1126 * open routine if any.
1127 */
1128 #ifndef _SYS_SYSPROTO_H_
1129 struct open_args {
1130 char *path;
1131 int flags;
1132 int mode;
1133 };
1134 #endif
1135 int
sys_open(struct thread * td,struct open_args * uap)1136 sys_open(struct thread *td, struct open_args *uap)
1137 {
1138
1139 return (kern_openat(td, AT_FDCWD, uap->path, UIO_USERSPACE,
1140 uap->flags, uap->mode));
1141 }
1142
1143 #ifndef _SYS_SYSPROTO_H_
1144 struct openat_args {
1145 int fd;
1146 char *path;
1147 int flag;
1148 int mode;
1149 };
1150 #endif
1151 int
sys_openat(struct thread * td,struct openat_args * uap)1152 sys_openat(struct thread *td, struct openat_args *uap)
1153 {
1154
1155 AUDIT_ARG_FD(uap->fd);
1156 return (kern_openat(td, uap->fd, uap->path, UIO_USERSPACE, uap->flag,
1157 uap->mode));
1158 }
1159
1160 /*
1161 * Validate open(2) flags and convert access mode flags (O_RDONLY etc.) to their
1162 * in-kernel representations (FREAD etc.).
1163 */
1164 static int
openflags(int * flagsp)1165 openflags(int *flagsp)
1166 {
1167 int flags;
1168
1169 /*
1170 * Only one of the O_EXEC, O_RDONLY, O_WRONLY and O_RDWR flags
1171 * may be specified. On the other hand, for O_PATH any mode
1172 * except O_EXEC is ignored.
1173 */
1174 flags = *flagsp;
1175 if ((flags & O_PATH) != 0) {
1176 flags &= ~O_ACCMODE;
1177 } else if ((flags & O_EXEC) != 0) {
1178 if ((flags & O_ACCMODE) != 0)
1179 return (EINVAL);
1180 } else if ((flags & O_ACCMODE) == O_ACCMODE) {
1181 return (EINVAL);
1182 } else {
1183 flags = FFLAGS(flags);
1184 }
1185 *flagsp = flags;
1186 return (0);
1187 }
1188
1189 static void
finit_open(struct file * fp,struct vnode * vp,int flags)1190 finit_open(struct file *fp, struct vnode *vp, int flags)
1191 {
1192 /*
1193 * Store the vnode, for any f_type. Typically, the vnode use count is
1194 * decremented by a direct call to vnops.fo_close() for files that
1195 * switched type.
1196 */
1197 fp->f_vnode = vp;
1198
1199 /*
1200 * If the file wasn't claimed by devfs or fifofs, bind it to the normal
1201 * vnode operations here.
1202 */
1203 if (fp->f_ops == &badfileops) {
1204 KASSERT(vp->v_type != VFIFO || (flags & O_PATH) != 0,
1205 ("Unexpected fifo fp %p vp %p", fp, vp));
1206 if ((flags & O_PATH) != 0) {
1207 finit(fp, (flags & FMASK) | (fp->f_flag & FKQALLOWED),
1208 DTYPE_VNODE, NULL, &path_fileops);
1209 } else {
1210 finit_vnode(fp, flags, NULL, &vnops);
1211 }
1212 }
1213 }
1214
1215 /*
1216 * If fpp != NULL, opened file is not installed into the file
1217 * descriptor table, instead it is returned in *fpp. This is
1218 * incompatible with fdopen(), in which case we return EINVAL.
1219 */
1220 static int
openatfp(struct thread * td,int dirfd,const char * path,enum uio_seg pathseg,int flags,int mode,struct file ** fpp)1221 openatfp(struct thread *td, int dirfd, const char *path,
1222 enum uio_seg pathseg, int flags, int mode, struct file **fpp)
1223 {
1224 struct proc *p;
1225 struct filedesc *fdp;
1226 struct pwddesc *pdp;
1227 struct file *fp;
1228 struct vnode *vp;
1229 struct filecaps *fcaps;
1230 struct nameidata nd;
1231 cap_rights_t rights;
1232 int cmode, error, indx;
1233
1234 indx = -1;
1235 p = td->td_proc;
1236 fdp = p->p_fd;
1237 pdp = p->p_pd;
1238
1239 AUDIT_ARG_FFLAGS(flags);
1240 AUDIT_ARG_MODE(mode);
1241 cap_rights_init_one(&rights, CAP_LOOKUP);
1242 flags_to_rights(flags, &rights);
1243
1244 error = openflags(&flags);
1245 if (error != 0)
1246 return (error);
1247
1248 /*
1249 * Allocate a file structure. The descriptor to reference it
1250 * is allocated and used by finstall_refed() below.
1251 */
1252 error = falloc_noinstall(td, &fp);
1253 if (error != 0)
1254 return (error);
1255 /* Set the flags early so the finit in devfs can pick them up. */
1256 fp->f_flag = flags & FMASK;
1257 cmode = ((mode & ~pdp->pd_cmask) & ALLPERMS) & ~S_ISTXT;
1258 NDINIT_ATRIGHTS(&nd, LOOKUP, FOLLOW | AUDITVNODE1 | WANTIOCTLCAPS,
1259 pathseg, path, dirfd, &rights);
1260 td->td_dupfd = -1; /* XXX check for fdopen */
1261 error = vn_open_cred(&nd, &flags, cmode, VN_OPEN_WANTIOCTLCAPS,
1262 td->td_ucred, fp);
1263 if (error != 0) {
1264 /*
1265 * If the vn_open replaced the method vector, something
1266 * wonderous happened deep below and we just pass it up
1267 * pretending we know what we do.
1268 */
1269 if (error == ENXIO && fp->f_ops != &badfileops) {
1270 MPASS((flags & O_PATH) == 0);
1271 goto success;
1272 }
1273
1274 /*
1275 * Handle special fdopen() case. bleh.
1276 *
1277 * Don't do this for relative (capability) lookups; we don't
1278 * understand exactly what would happen, and we don't think
1279 * that it ever should.
1280 */
1281 if ((nd.ni_resflags & NIRES_STRICTREL) == 0 &&
1282 (error == ENODEV || error == ENXIO) &&
1283 td->td_dupfd >= 0) {
1284 MPASS(fpp == NULL);
1285 error = dupfdopen(td, fdp, td->td_dupfd, flags, error,
1286 &indx);
1287 if (error == 0)
1288 goto success;
1289 }
1290
1291 goto bad;
1292 }
1293 td->td_dupfd = 0;
1294 NDFREE_PNBUF(&nd);
1295 vp = nd.ni_vp;
1296
1297 finit_open(fp, vp, flags);
1298 VOP_UNLOCK(vp);
1299 if (flags & O_TRUNC) {
1300 error = fo_truncate(fp, 0, td->td_ucred, td);
1301 if (error != 0)
1302 goto bad;
1303 }
1304 success:
1305 if (fpp != NULL) {
1306 MPASS(error == 0);
1307 NDFREE_IOCTLCAPS(&nd);
1308 *fpp = fp;
1309 return (0);
1310 }
1311
1312 /*
1313 * If we haven't already installed the FD (for dupfdopen), do so now.
1314 */
1315 if (indx == -1) {
1316 #ifdef CAPABILITIES
1317 if ((nd.ni_resflags & NIRES_STRICTREL) != 0)
1318 fcaps = &nd.ni_filecaps;
1319 else
1320 #endif
1321 fcaps = NULL;
1322 if ((nd.ni_resflags & NIRES_BENEATH) != 0)
1323 flags |= O_RESOLVE_BENEATH;
1324 else
1325 flags &= ~O_RESOLVE_BENEATH;
1326 error = finstall_refed(td, fp, &indx, flags, fcaps);
1327 /* On success finstall_refed() consumes fcaps. */
1328 if (error != 0) {
1329 goto bad;
1330 }
1331 } else {
1332 NDFREE_IOCTLCAPS(&nd);
1333 falloc_abort(td, fp);
1334 }
1335
1336 td->td_retval[0] = indx;
1337 return (0);
1338 bad:
1339 KASSERT(indx == -1, ("indx=%d, should be -1", indx));
1340 NDFREE_IOCTLCAPS(&nd);
1341 falloc_abort(td, fp);
1342 return (error);
1343 }
1344
1345 int
kern_openat(struct thread * td,int dirfd,const char * path,enum uio_seg pathseg,int flags,int mode)1346 kern_openat(struct thread *td, int dirfd, const char *path,
1347 enum uio_seg pathseg, int flags, int mode)
1348 {
1349 return (openatfp(td, dirfd, path, pathseg, flags, mode, NULL));
1350 }
1351
1352 int
kern_openatfp(struct thread * td,int dirfd,const char * path,enum uio_seg pathseg,int flags,int mode,struct file ** fpp)1353 kern_openatfp(struct thread *td, int dirfd, const char *path,
1354 enum uio_seg pathseg, int flags, int mode, struct file **fpp)
1355 {
1356 int error, old_dupfd;
1357
1358 old_dupfd = td->td_dupfd;
1359 td->td_dupfd = -1;
1360 error = openatfp(td, dirfd, path, pathseg, flags, mode, fpp);
1361 td->td_dupfd = old_dupfd;
1362 return (error);
1363 }
1364
1365 #ifdef COMPAT_43
1366 /*
1367 * Create a file.
1368 */
1369 #ifndef _SYS_SYSPROTO_H_
1370 struct ocreat_args {
1371 char *path;
1372 int mode;
1373 };
1374 #endif
1375 int
ocreat(struct thread * td,struct ocreat_args * uap)1376 ocreat(struct thread *td, struct ocreat_args *uap)
1377 {
1378
1379 return (kern_openat(td, AT_FDCWD, uap->path, UIO_USERSPACE,
1380 O_WRONLY | O_CREAT | O_TRUNC, uap->mode));
1381 }
1382 #endif /* COMPAT_43 */
1383
1384 /*
1385 * Create a special file.
1386 */
1387 #ifndef _SYS_SYSPROTO_H_
1388 struct mknodat_args {
1389 int fd;
1390 char *path;
1391 mode_t mode;
1392 dev_t dev;
1393 };
1394 #endif
1395 int
sys_mknodat(struct thread * td,struct mknodat_args * uap)1396 sys_mknodat(struct thread *td, struct mknodat_args *uap)
1397 {
1398
1399 return (kern_mknodat(td, uap->fd, uap->path, UIO_USERSPACE, uap->mode,
1400 uap->dev));
1401 }
1402
1403 #if defined(COMPAT_FREEBSD11)
1404 int
freebsd11_mknod(struct thread * td,struct freebsd11_mknod_args * uap)1405 freebsd11_mknod(struct thread *td,
1406 struct freebsd11_mknod_args *uap)
1407 {
1408
1409 return (kern_mknodat(td, AT_FDCWD, uap->path, UIO_USERSPACE,
1410 uap->mode, uap->dev));
1411 }
1412
1413 int
freebsd11_mknodat(struct thread * td,struct freebsd11_mknodat_args * uap)1414 freebsd11_mknodat(struct thread *td,
1415 struct freebsd11_mknodat_args *uap)
1416 {
1417
1418 return (kern_mknodat(td, uap->fd, uap->path, UIO_USERSPACE, uap->mode,
1419 uap->dev));
1420 }
1421 #endif /* COMPAT_FREEBSD11 */
1422
1423 int
kern_mknodat(struct thread * td,int fd,const char * path,enum uio_seg pathseg,int mode,dev_t dev)1424 kern_mknodat(struct thread *td, int fd, const char *path, enum uio_seg pathseg,
1425 int mode, dev_t dev)
1426 {
1427 struct vnode *vp;
1428 struct mount *mp;
1429 struct vattr vattr;
1430 struct nameidata nd;
1431 int error, whiteout = 0;
1432
1433 AUDIT_ARG_MODE(mode);
1434 AUDIT_ARG_DEV(dev);
1435 switch (mode & S_IFMT) {
1436 case S_IFCHR:
1437 case S_IFBLK:
1438 error = priv_check(td, PRIV_VFS_MKNOD_DEV);
1439 if (error == 0 && dev == VNOVAL)
1440 error = EINVAL;
1441 break;
1442 case S_IFWHT:
1443 error = priv_check(td, PRIV_VFS_MKNOD_WHT);
1444 break;
1445 case S_IFIFO:
1446 if (dev == 0)
1447 return (kern_mkfifoat(td, fd, path, pathseg, mode));
1448 /* FALLTHROUGH */
1449 default:
1450 error = EINVAL;
1451 break;
1452 }
1453 if (error != 0)
1454 return (error);
1455 NDPREINIT(&nd);
1456 restart:
1457 bwillwrite();
1458 NDINIT_ATRIGHTS(&nd, CREATE, LOCKPARENT | AUDITVNODE1 | NOCACHE,
1459 pathseg, path, fd, &cap_mknodat_rights);
1460 if ((error = namei(&nd)) != 0)
1461 return (error);
1462 vp = nd.ni_vp;
1463 if (vp != NULL) {
1464 NDFREE_PNBUF(&nd);
1465 if (vp == nd.ni_dvp)
1466 vrele(nd.ni_dvp);
1467 else
1468 vput(nd.ni_dvp);
1469 vrele(vp);
1470 return (EEXIST);
1471 } else if ((vn_irflag_read(nd.ni_dvp) & VIRF_NAMEDDIR) != 0) {
1472 NDFREE_PNBUF(&nd);
1473 vput(nd.ni_dvp);
1474 return (EINVAL);
1475 } else {
1476 VATTR_NULL(&vattr);
1477 vattr.va_mode = (mode & ALLPERMS) &
1478 ~td->td_proc->p_pd->pd_cmask;
1479 vattr.va_rdev = dev;
1480 whiteout = 0;
1481
1482 switch (mode & S_IFMT) {
1483 case S_IFCHR:
1484 vattr.va_type = VCHR;
1485 break;
1486 case S_IFBLK:
1487 vattr.va_type = VBLK;
1488 break;
1489 case S_IFWHT:
1490 whiteout = 1;
1491 break;
1492 default:
1493 panic("kern_mknod: invalid mode");
1494 }
1495 }
1496 if (vn_start_write(nd.ni_dvp, &mp, V_NOWAIT) != 0) {
1497 NDFREE_PNBUF(&nd);
1498 vput(nd.ni_dvp);
1499 if ((error = vn_start_write(NULL, &mp, V_XSLEEP | V_PCATCH)) != 0)
1500 return (error);
1501 goto restart;
1502 }
1503 #ifdef MAC
1504 if (error == 0 && !whiteout)
1505 error = mac_vnode_check_create(td->td_ucred, nd.ni_dvp,
1506 &nd.ni_cnd, &vattr);
1507 #endif
1508 if (error == 0) {
1509 if (whiteout)
1510 error = VOP_WHITEOUT(nd.ni_dvp, &nd.ni_cnd, CREATE);
1511 else {
1512 error = VOP_MKNOD(nd.ni_dvp, &nd.ni_vp,
1513 &nd.ni_cnd, &vattr);
1514 }
1515 }
1516 VOP_VPUT_PAIR(nd.ni_dvp, error == 0 && !whiteout ? &nd.ni_vp : NULL,
1517 true);
1518 vn_finished_write(mp);
1519 NDFREE_PNBUF(&nd);
1520 if (error == ERELOOKUP)
1521 goto restart;
1522 return (error);
1523 }
1524
1525 /*
1526 * Create a named pipe.
1527 */
1528 #ifndef _SYS_SYSPROTO_H_
1529 struct mkfifo_args {
1530 char *path;
1531 int mode;
1532 };
1533 #endif
1534 int
sys_mkfifo(struct thread * td,struct mkfifo_args * uap)1535 sys_mkfifo(struct thread *td, struct mkfifo_args *uap)
1536 {
1537
1538 return (kern_mkfifoat(td, AT_FDCWD, uap->path, UIO_USERSPACE,
1539 uap->mode));
1540 }
1541
1542 #ifndef _SYS_SYSPROTO_H_
1543 struct mkfifoat_args {
1544 int fd;
1545 char *path;
1546 mode_t mode;
1547 };
1548 #endif
1549 int
sys_mkfifoat(struct thread * td,struct mkfifoat_args * uap)1550 sys_mkfifoat(struct thread *td, struct mkfifoat_args *uap)
1551 {
1552
1553 return (kern_mkfifoat(td, uap->fd, uap->path, UIO_USERSPACE,
1554 uap->mode));
1555 }
1556
1557 int
kern_mkfifoat(struct thread * td,int fd,const char * path,enum uio_seg pathseg,int mode)1558 kern_mkfifoat(struct thread *td, int fd, const char *path,
1559 enum uio_seg pathseg, int mode)
1560 {
1561 struct mount *mp;
1562 struct vattr vattr;
1563 struct nameidata nd;
1564 int error;
1565
1566 AUDIT_ARG_MODE(mode);
1567 NDPREINIT(&nd);
1568 restart:
1569 bwillwrite();
1570 NDINIT_ATRIGHTS(&nd, CREATE, LOCKPARENT | AUDITVNODE1 | NOCACHE,
1571 pathseg, path, fd, &cap_mkfifoat_rights);
1572 if ((error = namei(&nd)) != 0)
1573 return (error);
1574 if (nd.ni_vp != NULL) {
1575 NDFREE_PNBUF(&nd);
1576 if (nd.ni_vp == nd.ni_dvp)
1577 vrele(nd.ni_dvp);
1578 else
1579 vput(nd.ni_dvp);
1580 vrele(nd.ni_vp);
1581 return (EEXIST);
1582 }
1583 if ((vn_irflag_read(nd.ni_dvp) & VIRF_NAMEDDIR) != 0) {
1584 NDFREE_PNBUF(&nd);
1585 vput(nd.ni_dvp);
1586 return (EINVAL);
1587 }
1588 if (vn_start_write(nd.ni_dvp, &mp, V_NOWAIT) != 0) {
1589 NDFREE_PNBUF(&nd);
1590 vput(nd.ni_dvp);
1591 if ((error = vn_start_write(NULL, &mp, V_XSLEEP | V_PCATCH)) != 0)
1592 return (error);
1593 goto restart;
1594 }
1595 VATTR_NULL(&vattr);
1596 vattr.va_type = VFIFO;
1597 vattr.va_mode = (mode & ALLPERMS) & ~td->td_proc->p_pd->pd_cmask;
1598 #ifdef MAC
1599 error = mac_vnode_check_create(td->td_ucred, nd.ni_dvp, &nd.ni_cnd,
1600 &vattr);
1601 if (error != 0)
1602 goto out;
1603 #endif
1604 error = VOP_MKNOD(nd.ni_dvp, &nd.ni_vp, &nd.ni_cnd, &vattr);
1605 #ifdef MAC
1606 out:
1607 #endif
1608 VOP_VPUT_PAIR(nd.ni_dvp, error == 0 ? &nd.ni_vp : NULL, true);
1609 vn_finished_write(mp);
1610 NDFREE_PNBUF(&nd);
1611 if (error == ERELOOKUP)
1612 goto restart;
1613 return (error);
1614 }
1615
1616 /*
1617 * Make a hard file link.
1618 */
1619 #ifndef _SYS_SYSPROTO_H_
1620 struct link_args {
1621 char *path;
1622 char *link;
1623 };
1624 #endif
1625 int
sys_link(struct thread * td,struct link_args * uap)1626 sys_link(struct thread *td, struct link_args *uap)
1627 {
1628
1629 return (kern_linkat(td, AT_FDCWD, AT_FDCWD, uap->path, uap->link,
1630 UIO_USERSPACE, AT_SYMLINK_FOLLOW));
1631 }
1632
1633 #ifndef _SYS_SYSPROTO_H_
1634 struct linkat_args {
1635 int fd1;
1636 char *path1;
1637 int fd2;
1638 char *path2;
1639 int flag;
1640 };
1641 #endif
1642 int
sys_linkat(struct thread * td,struct linkat_args * uap)1643 sys_linkat(struct thread *td, struct linkat_args *uap)
1644 {
1645
1646 return (kern_linkat(td, uap->fd1, uap->fd2, uap->path1, uap->path2,
1647 UIO_USERSPACE, uap->flag));
1648 }
1649
1650 int hardlink_check_uid = 0;
1651 SYSCTL_INT(_security_bsd, OID_AUTO, hardlink_check_uid, CTLFLAG_RW,
1652 &hardlink_check_uid, 0,
1653 "Unprivileged processes cannot create hard links to files owned by other "
1654 "users");
1655 static int hardlink_check_gid = 0;
1656 SYSCTL_INT(_security_bsd, OID_AUTO, hardlink_check_gid, CTLFLAG_RW,
1657 &hardlink_check_gid, 0,
1658 "Unprivileged processes cannot create hard links to files owned by other "
1659 "groups");
1660
1661 static int
can_hardlink(struct vnode * vp,struct ucred * cred)1662 can_hardlink(struct vnode *vp, struct ucred *cred)
1663 {
1664 struct vattr va;
1665 int error;
1666
1667 if (!hardlink_check_uid && !hardlink_check_gid)
1668 return (0);
1669
1670 error = VOP_GETATTR(vp, &va, cred);
1671 if (error != 0)
1672 return (error);
1673
1674 if (hardlink_check_uid && cred->cr_uid != va.va_uid) {
1675 error = priv_check_cred(cred, PRIV_VFS_LINK);
1676 if (error != 0)
1677 return (error);
1678 }
1679
1680 if (hardlink_check_gid && !groupmember(va.va_gid, cred)) {
1681 error = priv_check_cred(cred, PRIV_VFS_LINK);
1682 if (error != 0)
1683 return (error);
1684 }
1685
1686 return (0);
1687 }
1688
1689 int
kern_linkat(struct thread * td,int fd1,int fd2,const char * path1,const char * path2,enum uio_seg segflag,int flag)1690 kern_linkat(struct thread *td, int fd1, int fd2, const char *path1,
1691 const char *path2, enum uio_seg segflag, int flag)
1692 {
1693 struct nameidata nd;
1694 int error;
1695
1696 if ((flag & ~(AT_SYMLINK_FOLLOW | AT_RESOLVE_BENEATH |
1697 AT_EMPTY_PATH)) != 0)
1698 return (EINVAL);
1699
1700 NDPREINIT(&nd);
1701 do {
1702 bwillwrite();
1703 NDINIT_ATRIGHTS(&nd, LOOKUP, AUDITVNODE1 | at2cnpflags(flag,
1704 AT_SYMLINK_FOLLOW | AT_RESOLVE_BENEATH | AT_EMPTY_PATH),
1705 segflag, path1, fd1, &cap_linkat_source_rights);
1706 if ((error = namei(&nd)) != 0)
1707 return (error);
1708 NDFREE_PNBUF(&nd);
1709 if ((nd.ni_resflags & NIRES_EMPTYPATH) != 0) {
1710 error = priv_check(td, PRIV_VFS_FHOPEN);
1711 if (error != 0) {
1712 vrele(nd.ni_vp);
1713 return (error);
1714 }
1715 }
1716 error = kern_linkat_vp(td, nd.ni_vp, fd2, path2, segflag);
1717 } while (error == EAGAIN || error == ERELOOKUP);
1718 return (error);
1719 }
1720
1721 static int
kern_linkat_vp(struct thread * td,struct vnode * vp,int fd,const char * path,enum uio_seg segflag)1722 kern_linkat_vp(struct thread *td, struct vnode *vp, int fd, const char *path,
1723 enum uio_seg segflag)
1724 {
1725 struct nameidata nd;
1726 struct mount *mp;
1727 int error;
1728
1729 if (vp->v_type == VDIR) {
1730 vrele(vp);
1731 return (EPERM); /* POSIX */
1732 }
1733 if ((vn_irflag_read(vp) & (VIRF_NAMEDDIR | VIRF_NAMEDATTR)) != 0) {
1734 vrele(vp);
1735 return (EINVAL);
1736 }
1737 NDINIT_ATRIGHTS(&nd, CREATE,
1738 LOCKPARENT | AUDITVNODE2 | NOCACHE, segflag, path, fd,
1739 &cap_linkat_target_rights);
1740 if ((error = namei(&nd)) == 0) {
1741 if (nd.ni_vp != NULL) {
1742 NDFREE_PNBUF(&nd);
1743 if (nd.ni_dvp == nd.ni_vp)
1744 vrele(nd.ni_dvp);
1745 else
1746 vput(nd.ni_dvp);
1747 vrele(nd.ni_vp);
1748 vrele(vp);
1749 return (EEXIST);
1750 } else if (nd.ni_dvp->v_mount != vp->v_mount) {
1751 /*
1752 * Cross-device link. No need to recheck
1753 * vp->v_type, since it cannot change, except
1754 * to VBAD.
1755 */
1756 NDFREE_PNBUF(&nd);
1757 vput(nd.ni_dvp);
1758 vrele(vp);
1759 return (EXDEV);
1760 } else if (vn_lock(vp, LK_EXCLUSIVE) == 0) {
1761 error = can_hardlink(vp, td->td_ucred);
1762 #ifdef MAC
1763 if (error == 0)
1764 error = mac_vnode_check_link(td->td_ucred,
1765 nd.ni_dvp, vp, &nd.ni_cnd);
1766 #endif
1767 if (error != 0) {
1768 vput(vp);
1769 vput(nd.ni_dvp);
1770 NDFREE_PNBUF(&nd);
1771 return (error);
1772 }
1773 error = vn_start_write(vp, &mp, V_NOWAIT);
1774 if (error != 0) {
1775 vput(vp);
1776 vput(nd.ni_dvp);
1777 NDFREE_PNBUF(&nd);
1778 error = vn_start_write(NULL, &mp,
1779 V_XSLEEP | V_PCATCH);
1780 if (error != 0)
1781 return (error);
1782 return (EAGAIN);
1783 }
1784 error = VOP_LINK(nd.ni_dvp, vp, &nd.ni_cnd);
1785 VOP_VPUT_PAIR(nd.ni_dvp, &vp, true);
1786 vn_finished_write(mp);
1787 NDFREE_PNBUF(&nd);
1788 vp = NULL;
1789 } else {
1790 vput(nd.ni_dvp);
1791 NDFREE_PNBUF(&nd);
1792 vrele(vp);
1793 return (EAGAIN);
1794 }
1795 }
1796 if (vp != NULL)
1797 vrele(vp);
1798 return (error);
1799 }
1800
1801 /*
1802 * Make a symbolic link.
1803 */
1804 #ifndef _SYS_SYSPROTO_H_
1805 struct symlink_args {
1806 char *path;
1807 char *link;
1808 };
1809 #endif
1810 int
sys_symlink(struct thread * td,struct symlink_args * uap)1811 sys_symlink(struct thread *td, struct symlink_args *uap)
1812 {
1813
1814 return (kern_symlinkat(td, uap->path, AT_FDCWD, uap->link,
1815 UIO_USERSPACE));
1816 }
1817
1818 #ifndef _SYS_SYSPROTO_H_
1819 struct symlinkat_args {
1820 char *path;
1821 int fd;
1822 char *path2;
1823 };
1824 #endif
1825 int
sys_symlinkat(struct thread * td,struct symlinkat_args * uap)1826 sys_symlinkat(struct thread *td, struct symlinkat_args *uap)
1827 {
1828
1829 return (kern_symlinkat(td, uap->path1, uap->fd, uap->path2,
1830 UIO_USERSPACE));
1831 }
1832
1833 int
kern_symlinkat(struct thread * td,const char * path1,int fd,const char * path2,enum uio_seg segflg)1834 kern_symlinkat(struct thread *td, const char *path1, int fd, const char *path2,
1835 enum uio_seg segflg)
1836 {
1837 struct mount *mp;
1838 struct vattr vattr;
1839 const char *syspath;
1840 char *tmppath;
1841 struct nameidata nd;
1842 int error;
1843
1844 if (segflg == UIO_SYSSPACE) {
1845 syspath = path1;
1846 } else {
1847 tmppath = uma_zalloc(namei_zone, M_WAITOK);
1848 if ((error = copyinstr(path1, tmppath, MAXPATHLEN, NULL)) != 0)
1849 goto out;
1850 syspath = tmppath;
1851 }
1852 AUDIT_ARG_TEXT(syspath);
1853 NDPREINIT(&nd);
1854 restart:
1855 bwillwrite();
1856 NDINIT_ATRIGHTS(&nd, CREATE, LOCKPARENT | AUDITVNODE1 | NOCACHE, segflg,
1857 path2, fd, &cap_symlinkat_rights);
1858 if ((error = namei(&nd)) != 0)
1859 goto out;
1860 if (nd.ni_vp) {
1861 NDFREE_PNBUF(&nd);
1862 if (nd.ni_vp == nd.ni_dvp)
1863 vrele(nd.ni_dvp);
1864 else
1865 vput(nd.ni_dvp);
1866 vrele(nd.ni_vp);
1867 nd.ni_vp = NULL;
1868 error = EEXIST;
1869 goto out;
1870 }
1871 if (vn_start_write(nd.ni_dvp, &mp, V_NOWAIT) != 0) {
1872 NDFREE_PNBUF(&nd);
1873 vput(nd.ni_dvp);
1874 if ((error = vn_start_write(NULL, &mp, V_XSLEEP | V_PCATCH)) != 0)
1875 goto out;
1876 goto restart;
1877 }
1878 if ((vn_irflag_read(nd.ni_dvp) & VIRF_NAMEDDIR) != 0) {
1879 error = EINVAL;
1880 goto out;
1881 }
1882 VATTR_NULL(&vattr);
1883 vattr.va_mode = ACCESSPERMS &~ td->td_proc->p_pd->pd_cmask;
1884 #ifdef MAC
1885 vattr.va_type = VLNK;
1886 error = mac_vnode_check_create(td->td_ucred, nd.ni_dvp, &nd.ni_cnd,
1887 &vattr);
1888 if (error != 0)
1889 goto out2;
1890 #endif
1891 error = VOP_SYMLINK(nd.ni_dvp, &nd.ni_vp, &nd.ni_cnd, &vattr, syspath);
1892 #ifdef MAC
1893 out2:
1894 #endif
1895 VOP_VPUT_PAIR(nd.ni_dvp, error == 0 ? &nd.ni_vp : NULL, true);
1896 vn_finished_write(mp);
1897 NDFREE_PNBUF(&nd);
1898 if (error == ERELOOKUP)
1899 goto restart;
1900 out:
1901 if (segflg != UIO_SYSSPACE)
1902 uma_zfree(namei_zone, tmppath);
1903 return (error);
1904 }
1905
1906 /*
1907 * Delete a whiteout from the filesystem.
1908 */
1909 #ifndef _SYS_SYSPROTO_H_
1910 struct undelete_args {
1911 char *path;
1912 };
1913 #endif
1914 int
sys_undelete(struct thread * td,struct undelete_args * uap)1915 sys_undelete(struct thread *td, struct undelete_args *uap)
1916 {
1917 struct mount *mp;
1918 struct nameidata nd;
1919 int error;
1920
1921 NDPREINIT(&nd);
1922 restart:
1923 bwillwrite();
1924 NDINIT(&nd, DELETE, LOCKPARENT | DOWHITEOUT | AUDITVNODE1,
1925 UIO_USERSPACE, uap->path);
1926 error = namei(&nd);
1927 if (error != 0)
1928 return (error);
1929
1930 if (nd.ni_vp != NULLVP || !(nd.ni_cnd.cn_flags & ISWHITEOUT)) {
1931 NDFREE_PNBUF(&nd);
1932 if (nd.ni_vp == nd.ni_dvp)
1933 vrele(nd.ni_dvp);
1934 else
1935 vput(nd.ni_dvp);
1936 if (nd.ni_vp)
1937 vrele(nd.ni_vp);
1938 return (EEXIST);
1939 }
1940 if (vn_start_write(nd.ni_dvp, &mp, V_NOWAIT) != 0) {
1941 NDFREE_PNBUF(&nd);
1942 vput(nd.ni_dvp);
1943 if ((error = vn_start_write(NULL, &mp, V_XSLEEP | V_PCATCH)) != 0)
1944 return (error);
1945 goto restart;
1946 }
1947 error = VOP_WHITEOUT(nd.ni_dvp, &nd.ni_cnd, DELETE);
1948 NDFREE_PNBUF(&nd);
1949 vput(nd.ni_dvp);
1950 vn_finished_write(mp);
1951 if (error == ERELOOKUP)
1952 goto restart;
1953 return (error);
1954 }
1955
1956 /*
1957 * Delete a name from the filesystem.
1958 */
1959 #ifndef _SYS_SYSPROTO_H_
1960 struct unlink_args {
1961 char *path;
1962 };
1963 #endif
1964 int
sys_unlink(struct thread * td,struct unlink_args * uap)1965 sys_unlink(struct thread *td, struct unlink_args *uap)
1966 {
1967
1968 return (kern_funlinkat(td, AT_FDCWD, uap->path, FD_NONE, UIO_USERSPACE,
1969 0, 0));
1970 }
1971
1972 static int
kern_funlinkat_ex(struct thread * td,int dfd,const char * path,int fd,int flag,enum uio_seg pathseg,ino_t oldinum)1973 kern_funlinkat_ex(struct thread *td, int dfd, const char *path, int fd,
1974 int flag, enum uio_seg pathseg, ino_t oldinum)
1975 {
1976
1977 if ((flag & ~(AT_REMOVEDIR | AT_RESOLVE_BENEATH)) != 0)
1978 return (EINVAL);
1979
1980 if ((flag & AT_REMOVEDIR) != 0)
1981 return (kern_frmdirat(td, dfd, path, fd, UIO_USERSPACE, 0));
1982
1983 return (kern_funlinkat(td, dfd, path, fd, UIO_USERSPACE, 0, 0));
1984 }
1985
1986 #ifndef _SYS_SYSPROTO_H_
1987 struct unlinkat_args {
1988 int fd;
1989 char *path;
1990 int flag;
1991 };
1992 #endif
1993 int
sys_unlinkat(struct thread * td,struct unlinkat_args * uap)1994 sys_unlinkat(struct thread *td, struct unlinkat_args *uap)
1995 {
1996
1997 return (kern_funlinkat_ex(td, uap->fd, uap->path, FD_NONE, uap->flag,
1998 UIO_USERSPACE, 0));
1999 }
2000
2001 #ifndef _SYS_SYSPROTO_H_
2002 struct funlinkat_args {
2003 int dfd;
2004 const char *path;
2005 int fd;
2006 int flag;
2007 };
2008 #endif
2009 int
sys_funlinkat(struct thread * td,struct funlinkat_args * uap)2010 sys_funlinkat(struct thread *td, struct funlinkat_args *uap)
2011 {
2012
2013 return (kern_funlinkat_ex(td, uap->dfd, uap->path, uap->fd, uap->flag,
2014 UIO_USERSPACE, 0));
2015 }
2016
2017 int
kern_funlinkat(struct thread * td,int dfd,const char * path,int fd,enum uio_seg pathseg,int flag,ino_t oldinum)2018 kern_funlinkat(struct thread *td, int dfd, const char *path, int fd,
2019 enum uio_seg pathseg, int flag, ino_t oldinum)
2020 {
2021 struct mount *mp;
2022 struct file *fp;
2023 struct vnode *vp;
2024 struct nameidata nd;
2025 struct stat sb;
2026 int error;
2027
2028 fp = NULL;
2029 if (fd != FD_NONE) {
2030 error = getvnode_path(td, fd, &cap_no_rights, NULL, &fp);
2031 if (error != 0)
2032 return (error);
2033 }
2034
2035 NDPREINIT(&nd);
2036 restart:
2037 bwillwrite();
2038 NDINIT_ATRIGHTS(&nd, DELETE, LOCKPARENT | LOCKLEAF | AUDITVNODE1 |
2039 at2cnpflags(flag, AT_RESOLVE_BENEATH),
2040 pathseg, path, dfd, &cap_unlinkat_rights);
2041 if ((error = namei(&nd)) != 0) {
2042 if (error == EINVAL)
2043 error = EPERM;
2044 goto fdout;
2045 }
2046 vp = nd.ni_vp;
2047 if (vp->v_type == VDIR && oldinum == 0) {
2048 error = EPERM; /* POSIX */
2049 } else if (oldinum != 0 &&
2050 ((error = VOP_STAT(vp, &sb, td->td_ucred, NOCRED)) == 0) &&
2051 sb.st_ino != oldinum) {
2052 error = EIDRM; /* Identifier removed */
2053 } else if (fp != NULL && fp->f_vnode != vp) {
2054 if (VN_IS_DOOMED(fp->f_vnode))
2055 error = EBADF;
2056 else
2057 error = EDEADLK;
2058 } else {
2059 /*
2060 * The root of a mounted filesystem cannot be deleted.
2061 *
2062 * XXX: can this only be a VDIR case?
2063 */
2064 if (vp->v_vflag & VV_ROOT)
2065 error = EBUSY;
2066 }
2067 if (error == 0) {
2068 if (vn_start_write(nd.ni_dvp, &mp, V_NOWAIT) != 0) {
2069 NDFREE_PNBUF(&nd);
2070 vput(nd.ni_dvp);
2071 if (vp == nd.ni_dvp)
2072 vrele(vp);
2073 else
2074 vput(vp);
2075 if ((error = vn_start_write(NULL, &mp,
2076 V_XSLEEP | V_PCATCH)) != 0) {
2077 goto fdout;
2078 }
2079 goto restart;
2080 }
2081 #ifdef MAC
2082 error = mac_vnode_check_unlink(td->td_ucred, nd.ni_dvp, vp,
2083 &nd.ni_cnd);
2084 if (error != 0)
2085 goto out;
2086 #endif
2087 error = VOP_REMOVE(nd.ni_dvp, vp, &nd.ni_cnd);
2088 #ifdef MAC
2089 out:
2090 #endif
2091 vn_finished_write(mp);
2092 }
2093 NDFREE_PNBUF(&nd);
2094 vput(nd.ni_dvp);
2095 if (vp == nd.ni_dvp)
2096 vrele(vp);
2097 else
2098 vput(vp);
2099 if (error == ERELOOKUP)
2100 goto restart;
2101 fdout:
2102 if (fp != NULL)
2103 fdrop(fp, td);
2104 return (error);
2105 }
2106
2107 /*
2108 * Reposition read/write file offset.
2109 */
2110 #ifndef _SYS_SYSPROTO_H_
2111 struct lseek_args {
2112 int fd;
2113 int pad;
2114 off_t offset;
2115 int whence;
2116 };
2117 #endif
2118 int
sys_lseek(struct thread * td,struct lseek_args * uap)2119 sys_lseek(struct thread *td, struct lseek_args *uap)
2120 {
2121
2122 return (kern_lseek(td, uap->fd, uap->offset, uap->whence));
2123 }
2124
2125 int
kern_lseek(struct thread * td,int fd,off_t offset,int whence)2126 kern_lseek(struct thread *td, int fd, off_t offset, int whence)
2127 {
2128 struct file *fp;
2129 int error;
2130
2131 AUDIT_ARG_FD(fd);
2132 error = fget(td, fd, &cap_seek_rights, &fp);
2133 if (error != 0)
2134 return (error);
2135 error = (fp->f_ops->fo_flags & DFLAG_SEEKABLE) != 0 ?
2136 fo_seek(fp, offset, whence, td) : ESPIPE;
2137 fdrop(fp, td);
2138 return (error);
2139 }
2140
2141 #if defined(COMPAT_43)
2142 /*
2143 * Reposition read/write file offset.
2144 */
2145 #ifndef _SYS_SYSPROTO_H_
2146 struct olseek_args {
2147 int fd;
2148 long offset;
2149 int whence;
2150 };
2151 #endif
2152 int
olseek(struct thread * td,struct olseek_args * uap)2153 olseek(struct thread *td, struct olseek_args *uap)
2154 {
2155
2156 return (kern_lseek(td, uap->fd, uap->offset, uap->whence));
2157 }
2158 #endif /* COMPAT_43 */
2159
2160 #if defined(COMPAT_FREEBSD6)
2161 /* Version with the 'pad' argument */
2162 int
freebsd6_lseek(struct thread * td,struct freebsd6_lseek_args * uap)2163 freebsd6_lseek(struct thread *td, struct freebsd6_lseek_args *uap)
2164 {
2165
2166 return (kern_lseek(td, uap->fd, uap->offset, uap->whence));
2167 }
2168 #endif
2169
2170 /*
2171 * Check access permissions using passed credentials.
2172 */
2173 static int
vn_access(struct vnode * vp,int user_flags,struct ucred * cred,struct thread * td)2174 vn_access(struct vnode *vp, int user_flags, struct ucred *cred,
2175 struct thread *td)
2176 {
2177 accmode_t accmode;
2178 int error;
2179
2180 /* Flags == 0 means only check for existence. */
2181 if (user_flags == 0)
2182 return (0);
2183
2184 accmode = 0;
2185 if (user_flags & R_OK)
2186 accmode |= VREAD;
2187 if (user_flags & W_OK)
2188 accmode |= VWRITE;
2189 if (user_flags & X_OK)
2190 accmode |= VEXEC;
2191 #ifdef MAC
2192 error = mac_vnode_check_access(cred, vp, accmode);
2193 if (error != 0)
2194 return (error);
2195 #endif
2196 if ((accmode & VWRITE) == 0 || (error = vn_writechk(vp)) == 0)
2197 error = VOP_ACCESS(vp, accmode, cred, td);
2198 return (error);
2199 }
2200
2201 /*
2202 * Check access permissions using "real" credentials.
2203 */
2204 #ifndef _SYS_SYSPROTO_H_
2205 struct access_args {
2206 char *path;
2207 int amode;
2208 };
2209 #endif
2210 int
sys_access(struct thread * td,struct access_args * uap)2211 sys_access(struct thread *td, struct access_args *uap)
2212 {
2213
2214 return (kern_accessat(td, AT_FDCWD, uap->path, UIO_USERSPACE,
2215 0, uap->amode));
2216 }
2217
2218 #ifndef _SYS_SYSPROTO_H_
2219 struct faccessat_args {
2220 int dirfd;
2221 char *path;
2222 int amode;
2223 int flag;
2224 }
2225 #endif
2226 int
sys_faccessat(struct thread * td,struct faccessat_args * uap)2227 sys_faccessat(struct thread *td, struct faccessat_args *uap)
2228 {
2229
2230 return (kern_accessat(td, uap->fd, uap->path, UIO_USERSPACE, uap->flag,
2231 uap->amode));
2232 }
2233
2234 int
kern_accessat(struct thread * td,int fd,const char * path,enum uio_seg pathseg,int flag,int amode)2235 kern_accessat(struct thread *td, int fd, const char *path,
2236 enum uio_seg pathseg, int flag, int amode)
2237 {
2238 struct ucred *cred, *usecred;
2239 struct vnode *vp;
2240 struct nameidata nd;
2241 int error;
2242
2243 if ((flag & ~(AT_EACCESS | AT_RESOLVE_BENEATH | AT_EMPTY_PATH |
2244 AT_SYMLINK_NOFOLLOW)) != 0)
2245 return (EINVAL);
2246 if (amode != F_OK && (amode & ~(R_OK | W_OK | X_OK)) != 0)
2247 return (EINVAL);
2248
2249 /*
2250 * Create and modify a temporary credential instead of one that
2251 * is potentially shared (if we need one).
2252 */
2253 cred = td->td_ucred;
2254 if ((flag & AT_EACCESS) == 0 &&
2255 ((cred->cr_uid != cred->cr_ruid ||
2256 cred->cr_rgid != cred->cr_groups[0]))) {
2257 usecred = crdup(cred);
2258 usecred->cr_uid = cred->cr_ruid;
2259 usecred->cr_groups[0] = cred->cr_rgid;
2260 td->td_ucred = usecred;
2261 } else
2262 usecred = cred;
2263 AUDIT_ARG_VALUE(amode);
2264 NDINIT_ATRIGHTS(&nd, LOOKUP, LOCKSHARED | LOCKLEAF |
2265 AUDITVNODE1 | at2cnpflags(flag, AT_RESOLVE_BENEATH | AT_SYMLINK_NOFOLLOW |
2266 AT_EMPTY_PATH), pathseg, path, fd, &cap_fstat_rights);
2267 if ((error = namei(&nd)) != 0)
2268 goto out;
2269 vp = nd.ni_vp;
2270
2271 error = vn_access(vp, amode, usecred, td);
2272 NDFREE_PNBUF(&nd);
2273 vput(vp);
2274 out:
2275 if (usecred != cred) {
2276 td->td_ucred = cred;
2277 crfree(usecred);
2278 }
2279 return (error);
2280 }
2281
2282 /*
2283 * Check access permissions using "effective" credentials.
2284 */
2285 #ifndef _SYS_SYSPROTO_H_
2286 struct eaccess_args {
2287 char *path;
2288 int amode;
2289 };
2290 #endif
2291 int
sys_eaccess(struct thread * td,struct eaccess_args * uap)2292 sys_eaccess(struct thread *td, struct eaccess_args *uap)
2293 {
2294
2295 return (kern_accessat(td, AT_FDCWD, uap->path, UIO_USERSPACE,
2296 AT_EACCESS, uap->amode));
2297 }
2298
2299 #if defined(COMPAT_43)
2300 /*
2301 * Get file status; this version follows links.
2302 */
2303 #ifndef _SYS_SYSPROTO_H_
2304 struct ostat_args {
2305 char *path;
2306 struct ostat *ub;
2307 };
2308 #endif
2309 int
ostat(struct thread * td,struct ostat_args * uap)2310 ostat(struct thread *td, struct ostat_args *uap)
2311 {
2312 struct stat sb;
2313 struct ostat osb;
2314 int error;
2315
2316 error = kern_statat(td, 0, AT_FDCWD, uap->path, UIO_USERSPACE, &sb);
2317 if (error != 0)
2318 return (error);
2319 cvtstat(&sb, &osb);
2320 return (copyout(&osb, uap->ub, sizeof (osb)));
2321 }
2322
2323 /*
2324 * Get file status; this version does not follow links.
2325 */
2326 #ifndef _SYS_SYSPROTO_H_
2327 struct olstat_args {
2328 char *path;
2329 struct ostat *ub;
2330 };
2331 #endif
2332 int
olstat(struct thread * td,struct olstat_args * uap)2333 olstat(struct thread *td, struct olstat_args *uap)
2334 {
2335 struct stat sb;
2336 struct ostat osb;
2337 int error;
2338
2339 error = kern_statat(td, AT_SYMLINK_NOFOLLOW, AT_FDCWD, uap->path,
2340 UIO_USERSPACE, &sb);
2341 if (error != 0)
2342 return (error);
2343 cvtstat(&sb, &osb);
2344 return (copyout(&osb, uap->ub, sizeof (osb)));
2345 }
2346
2347 /*
2348 * Convert from an old to a new stat structure.
2349 * XXX: many values are blindly truncated.
2350 */
2351 void
cvtstat(struct stat * st,struct ostat * ost)2352 cvtstat(struct stat *st, struct ostat *ost)
2353 {
2354
2355 bzero(ost, sizeof(*ost));
2356 ost->st_dev = st->st_dev;
2357 ost->st_ino = st->st_ino;
2358 ost->st_mode = st->st_mode;
2359 ost->st_nlink = st->st_nlink;
2360 ost->st_uid = st->st_uid;
2361 ost->st_gid = st->st_gid;
2362 ost->st_rdev = st->st_rdev;
2363 ost->st_size = MIN(st->st_size, INT32_MAX);
2364 ost->st_atim = st->st_atim;
2365 ost->st_mtim = st->st_mtim;
2366 ost->st_ctim = st->st_ctim;
2367 ost->st_blksize = st->st_blksize;
2368 ost->st_blocks = st->st_blocks;
2369 ost->st_flags = st->st_flags;
2370 ost->st_gen = st->st_gen;
2371 }
2372 #endif /* COMPAT_43 */
2373
2374 #if defined(COMPAT_43) || defined(COMPAT_FREEBSD11)
2375 int ino64_trunc_error;
2376 SYSCTL_INT(_vfs, OID_AUTO, ino64_trunc_error, CTLFLAG_RW,
2377 &ino64_trunc_error, 0,
2378 "Error on truncation of device, file or inode number, or link count");
2379
2380 int
freebsd11_cvtstat(struct stat * st,struct freebsd11_stat * ost)2381 freebsd11_cvtstat(struct stat *st, struct freebsd11_stat *ost)
2382 {
2383
2384 ost->st_dev = st->st_dev;
2385 if (ost->st_dev != st->st_dev) {
2386 switch (ino64_trunc_error) {
2387 default:
2388 /*
2389 * Since dev_t is almost raw, don't clamp to the
2390 * maximum for case 2, but ignore the error.
2391 */
2392 break;
2393 case 1:
2394 return (EOVERFLOW);
2395 }
2396 }
2397 ost->st_ino = st->st_ino;
2398 if (ost->st_ino != st->st_ino) {
2399 switch (ino64_trunc_error) {
2400 default:
2401 case 0:
2402 break;
2403 case 1:
2404 return (EOVERFLOW);
2405 case 2:
2406 ost->st_ino = UINT32_MAX;
2407 break;
2408 }
2409 }
2410 ost->st_mode = st->st_mode;
2411 ost->st_nlink = st->st_nlink;
2412 if (ost->st_nlink != st->st_nlink) {
2413 switch (ino64_trunc_error) {
2414 default:
2415 case 0:
2416 break;
2417 case 1:
2418 return (EOVERFLOW);
2419 case 2:
2420 ost->st_nlink = UINT16_MAX;
2421 break;
2422 }
2423 }
2424 ost->st_uid = st->st_uid;
2425 ost->st_gid = st->st_gid;
2426 ost->st_rdev = st->st_rdev;
2427 if (ost->st_rdev != st->st_rdev) {
2428 switch (ino64_trunc_error) {
2429 default:
2430 break;
2431 case 1:
2432 return (EOVERFLOW);
2433 }
2434 }
2435 ost->st_atim = st->st_atim;
2436 ost->st_mtim = st->st_mtim;
2437 ost->st_ctim = st->st_ctim;
2438 ost->st_size = st->st_size;
2439 ost->st_blocks = st->st_blocks;
2440 ost->st_blksize = st->st_blksize;
2441 ost->st_flags = st->st_flags;
2442 ost->st_gen = st->st_gen;
2443 ost->st_lspare = 0;
2444 ost->st_birthtim = st->st_birthtim;
2445 bzero((char *)&ost->st_birthtim + sizeof(ost->st_birthtim),
2446 sizeof(*ost) - offsetof(struct freebsd11_stat,
2447 st_birthtim) - sizeof(ost->st_birthtim));
2448 return (0);
2449 }
2450
2451 int
freebsd11_stat(struct thread * td,struct freebsd11_stat_args * uap)2452 freebsd11_stat(struct thread *td, struct freebsd11_stat_args* uap)
2453 {
2454 struct stat sb;
2455 struct freebsd11_stat osb;
2456 int error;
2457
2458 error = kern_statat(td, 0, AT_FDCWD, uap->path, UIO_USERSPACE, &sb);
2459 if (error != 0)
2460 return (error);
2461 error = freebsd11_cvtstat(&sb, &osb);
2462 if (error == 0)
2463 error = copyout(&osb, uap->ub, sizeof(osb));
2464 return (error);
2465 }
2466
2467 int
freebsd11_lstat(struct thread * td,struct freebsd11_lstat_args * uap)2468 freebsd11_lstat(struct thread *td, struct freebsd11_lstat_args* uap)
2469 {
2470 struct stat sb;
2471 struct freebsd11_stat osb;
2472 int error;
2473
2474 error = kern_statat(td, AT_SYMLINK_NOFOLLOW, AT_FDCWD, uap->path,
2475 UIO_USERSPACE, &sb);
2476 if (error != 0)
2477 return (error);
2478 error = freebsd11_cvtstat(&sb, &osb);
2479 if (error == 0)
2480 error = copyout(&osb, uap->ub, sizeof(osb));
2481 return (error);
2482 }
2483
2484 int
freebsd11_fhstat(struct thread * td,struct freebsd11_fhstat_args * uap)2485 freebsd11_fhstat(struct thread *td, struct freebsd11_fhstat_args* uap)
2486 {
2487 struct fhandle fh;
2488 struct stat sb;
2489 struct freebsd11_stat osb;
2490 int error;
2491
2492 error = copyin(uap->u_fhp, &fh, sizeof(fhandle_t));
2493 if (error != 0)
2494 return (error);
2495 error = kern_fhstat(td, fh, &sb);
2496 if (error != 0)
2497 return (error);
2498 error = freebsd11_cvtstat(&sb, &osb);
2499 if (error == 0)
2500 error = copyout(&osb, uap->sb, sizeof(osb));
2501 return (error);
2502 }
2503
2504 int
freebsd11_fstatat(struct thread * td,struct freebsd11_fstatat_args * uap)2505 freebsd11_fstatat(struct thread *td, struct freebsd11_fstatat_args* uap)
2506 {
2507 struct stat sb;
2508 struct freebsd11_stat osb;
2509 int error;
2510
2511 error = kern_statat(td, uap->flag, uap->fd, uap->path,
2512 UIO_USERSPACE, &sb);
2513 if (error != 0)
2514 return (error);
2515 error = freebsd11_cvtstat(&sb, &osb);
2516 if (error == 0)
2517 error = copyout(&osb, uap->buf, sizeof(osb));
2518 return (error);
2519 }
2520 #endif /* COMPAT_FREEBSD11 */
2521
2522 /*
2523 * Get file status
2524 */
2525 #ifndef _SYS_SYSPROTO_H_
2526 struct fstatat_args {
2527 int fd;
2528 char *path;
2529 struct stat *buf;
2530 int flag;
2531 }
2532 #endif
2533 int
sys_fstatat(struct thread * td,struct fstatat_args * uap)2534 sys_fstatat(struct thread *td, struct fstatat_args *uap)
2535 {
2536 struct stat sb;
2537 int error;
2538
2539 error = kern_statat(td, uap->flag, uap->fd, uap->path,
2540 UIO_USERSPACE, &sb);
2541 if (error == 0)
2542 error = copyout(&sb, uap->buf, sizeof (sb));
2543 return (error);
2544 }
2545
2546 int
kern_statat(struct thread * td,int flag,int fd,const char * path,enum uio_seg pathseg,struct stat * sbp)2547 kern_statat(struct thread *td, int flag, int fd, const char *path,
2548 enum uio_seg pathseg, struct stat *sbp)
2549 {
2550 struct nameidata nd;
2551 int error;
2552
2553 if ((flag & ~(AT_SYMLINK_NOFOLLOW | AT_RESOLVE_BENEATH |
2554 AT_EMPTY_PATH)) != 0)
2555 return (EINVAL);
2556
2557 NDINIT_ATRIGHTS(&nd, LOOKUP, at2cnpflags(flag, AT_RESOLVE_BENEATH |
2558 AT_SYMLINK_NOFOLLOW | AT_EMPTY_PATH) | LOCKSHARED | LOCKLEAF |
2559 AUDITVNODE1, pathseg, path, fd, &cap_fstat_rights);
2560
2561 if ((error = namei(&nd)) != 0) {
2562 if (error == ENOTDIR &&
2563 (nd.ni_resflags & NIRES_EMPTYPATH) != 0)
2564 error = kern_fstat(td, fd, sbp);
2565 return (error);
2566 }
2567 error = VOP_STAT(nd.ni_vp, sbp, td->td_ucred, NOCRED);
2568 NDFREE_PNBUF(&nd);
2569 vput(nd.ni_vp);
2570 #ifdef __STAT_TIME_T_EXT
2571 sbp->st_atim_ext = 0;
2572 sbp->st_mtim_ext = 0;
2573 sbp->st_ctim_ext = 0;
2574 sbp->st_btim_ext = 0;
2575 #endif
2576 #ifdef KTRACE
2577 if (KTRPOINT(td, KTR_STRUCT))
2578 ktrstat_error(sbp, error);
2579 #endif
2580 return (error);
2581 }
2582
2583 #if defined(COMPAT_FREEBSD11)
2584 /*
2585 * Implementation of the NetBSD [l]stat() functions.
2586 */
2587 int
freebsd11_cvtnstat(struct stat * sb,struct nstat * nsb)2588 freebsd11_cvtnstat(struct stat *sb, struct nstat *nsb)
2589 {
2590 struct freebsd11_stat sb11;
2591 int error;
2592
2593 error = freebsd11_cvtstat(sb, &sb11);
2594 if (error != 0)
2595 return (error);
2596
2597 bzero(nsb, sizeof(*nsb));
2598 CP(sb11, *nsb, st_dev);
2599 CP(sb11, *nsb, st_ino);
2600 CP(sb11, *nsb, st_mode);
2601 CP(sb11, *nsb, st_nlink);
2602 CP(sb11, *nsb, st_uid);
2603 CP(sb11, *nsb, st_gid);
2604 CP(sb11, *nsb, st_rdev);
2605 CP(sb11, *nsb, st_atim);
2606 CP(sb11, *nsb, st_mtim);
2607 CP(sb11, *nsb, st_ctim);
2608 CP(sb11, *nsb, st_size);
2609 CP(sb11, *nsb, st_blocks);
2610 CP(sb11, *nsb, st_blksize);
2611 CP(sb11, *nsb, st_flags);
2612 CP(sb11, *nsb, st_gen);
2613 CP(sb11, *nsb, st_birthtim);
2614 return (0);
2615 }
2616
2617 #ifndef _SYS_SYSPROTO_H_
2618 struct freebsd11_nstat_args {
2619 char *path;
2620 struct nstat *ub;
2621 };
2622 #endif
2623 int
freebsd11_nstat(struct thread * td,struct freebsd11_nstat_args * uap)2624 freebsd11_nstat(struct thread *td, struct freebsd11_nstat_args *uap)
2625 {
2626 struct stat sb;
2627 struct nstat nsb;
2628 int error;
2629
2630 error = kern_statat(td, 0, AT_FDCWD, uap->path, UIO_USERSPACE, &sb);
2631 if (error != 0)
2632 return (error);
2633 error = freebsd11_cvtnstat(&sb, &nsb);
2634 if (error == 0)
2635 error = copyout(&nsb, uap->ub, sizeof (nsb));
2636 return (error);
2637 }
2638
2639 /*
2640 * NetBSD lstat. Get file status; this version does not follow links.
2641 */
2642 #ifndef _SYS_SYSPROTO_H_
2643 struct freebsd11_nlstat_args {
2644 char *path;
2645 struct nstat *ub;
2646 };
2647 #endif
2648 int
freebsd11_nlstat(struct thread * td,struct freebsd11_nlstat_args * uap)2649 freebsd11_nlstat(struct thread *td, struct freebsd11_nlstat_args *uap)
2650 {
2651 struct stat sb;
2652 struct nstat nsb;
2653 int error;
2654
2655 error = kern_statat(td, AT_SYMLINK_NOFOLLOW, AT_FDCWD, uap->path,
2656 UIO_USERSPACE, &sb);
2657 if (error != 0)
2658 return (error);
2659 error = freebsd11_cvtnstat(&sb, &nsb);
2660 if (error == 0)
2661 error = copyout(&nsb, uap->ub, sizeof (nsb));
2662 return (error);
2663 }
2664 #endif /* COMPAT_FREEBSD11 */
2665
2666 /*
2667 * Get configurable pathname variables.
2668 */
2669 #ifndef _SYS_SYSPROTO_H_
2670 struct pathconf_args {
2671 char *path;
2672 int name;
2673 };
2674 #endif
2675 int
sys_pathconf(struct thread * td,struct pathconf_args * uap)2676 sys_pathconf(struct thread *td, struct pathconf_args *uap)
2677 {
2678 long value;
2679 int error;
2680
2681 error = kern_pathconf(td, uap->path, UIO_USERSPACE, uap->name, FOLLOW,
2682 &value);
2683 if (error == 0)
2684 td->td_retval[0] = value;
2685 return (error);
2686 }
2687
2688 #ifndef _SYS_SYSPROTO_H_
2689 struct lpathconf_args {
2690 char *path;
2691 int name;
2692 };
2693 #endif
2694 int
sys_lpathconf(struct thread * td,struct lpathconf_args * uap)2695 sys_lpathconf(struct thread *td, struct lpathconf_args *uap)
2696 {
2697 long value;
2698 int error;
2699
2700 error = kern_pathconf(td, uap->path, UIO_USERSPACE, uap->name,
2701 NOFOLLOW, &value);
2702 if (error == 0)
2703 td->td_retval[0] = value;
2704 return (error);
2705 }
2706
2707 int
kern_pathconf(struct thread * td,const char * path,enum uio_seg pathseg,int name,u_long flags,long * valuep)2708 kern_pathconf(struct thread *td, const char *path, enum uio_seg pathseg,
2709 int name, u_long flags, long *valuep)
2710 {
2711 struct nameidata nd;
2712 int error;
2713
2714 NDINIT(&nd, LOOKUP, LOCKSHARED | LOCKLEAF | AUDITVNODE1 | flags,
2715 pathseg, path);
2716 if ((error = namei(&nd)) != 0)
2717 return (error);
2718 NDFREE_PNBUF(&nd);
2719
2720 error = VOP_PATHCONF(nd.ni_vp, name, valuep);
2721 vput(nd.ni_vp);
2722 return (error);
2723 }
2724
2725 /*
2726 * Return target name of a symbolic link.
2727 */
2728 #ifndef _SYS_SYSPROTO_H_
2729 struct readlink_args {
2730 char *path;
2731 char *buf;
2732 size_t count;
2733 };
2734 #endif
2735 int
sys_readlink(struct thread * td,struct readlink_args * uap)2736 sys_readlink(struct thread *td, struct readlink_args *uap)
2737 {
2738
2739 return (kern_readlinkat(td, AT_FDCWD, uap->path, UIO_USERSPACE,
2740 uap->buf, UIO_USERSPACE, uap->count));
2741 }
2742 #ifndef _SYS_SYSPROTO_H_
2743 struct readlinkat_args {
2744 int fd;
2745 char *path;
2746 char *buf;
2747 size_t bufsize;
2748 };
2749 #endif
2750 int
sys_readlinkat(struct thread * td,struct readlinkat_args * uap)2751 sys_readlinkat(struct thread *td, struct readlinkat_args *uap)
2752 {
2753
2754 return (kern_readlinkat(td, uap->fd, uap->path, UIO_USERSPACE,
2755 uap->buf, UIO_USERSPACE, uap->bufsize));
2756 }
2757
2758 int
kern_readlinkat(struct thread * td,int fd,const char * path,enum uio_seg pathseg,char * buf,enum uio_seg bufseg,size_t count)2759 kern_readlinkat(struct thread *td, int fd, const char *path,
2760 enum uio_seg pathseg, char *buf, enum uio_seg bufseg, size_t count)
2761 {
2762 struct vnode *vp;
2763 struct nameidata nd;
2764 int error;
2765
2766 if (count > IOSIZE_MAX)
2767 return (EINVAL);
2768
2769 NDINIT_AT(&nd, LOOKUP, NOFOLLOW | LOCKSHARED | LOCKLEAF | AUDITVNODE1 |
2770 EMPTYPATH, pathseg, path, fd);
2771
2772 if ((error = namei(&nd)) != 0)
2773 return (error);
2774 NDFREE_PNBUF(&nd);
2775 vp = nd.ni_vp;
2776
2777 error = kern_readlink_vp(vp, buf, bufseg, count, td);
2778 vput(vp);
2779
2780 return (error);
2781 }
2782
2783 /*
2784 * Helper function to readlink from a vnode
2785 */
2786 static int
kern_readlink_vp(struct vnode * vp,char * buf,enum uio_seg bufseg,size_t count,struct thread * td)2787 kern_readlink_vp(struct vnode *vp, char *buf, enum uio_seg bufseg, size_t count,
2788 struct thread *td)
2789 {
2790 struct iovec aiov;
2791 struct uio auio;
2792 int error;
2793
2794 ASSERT_VOP_LOCKED(vp, "kern_readlink_vp(): vp not locked");
2795 #ifdef MAC
2796 error = mac_vnode_check_readlink(td->td_ucred, vp);
2797 if (error != 0)
2798 return (error);
2799 #endif
2800 if (vp->v_type != VLNK && (vp->v_vflag & VV_READLINK) == 0)
2801 return (EINVAL);
2802
2803 aiov.iov_base = buf;
2804 aiov.iov_len = count;
2805 auio.uio_iov = &aiov;
2806 auio.uio_iovcnt = 1;
2807 auio.uio_offset = 0;
2808 auio.uio_rw = UIO_READ;
2809 auio.uio_segflg = bufseg;
2810 auio.uio_td = td;
2811 auio.uio_resid = count;
2812 error = VOP_READLINK(vp, &auio, td->td_ucred);
2813 td->td_retval[0] = count - auio.uio_resid;
2814 return (error);
2815 }
2816
2817 /*
2818 * Common implementation code for chflags() and fchflags().
2819 */
2820 static int
setfflags(struct thread * td,struct vnode * vp,u_long flags)2821 setfflags(struct thread *td, struct vnode *vp, u_long flags)
2822 {
2823 struct mount *mp;
2824 struct vattr vattr;
2825 int error;
2826
2827 /* We can't support the value matching VNOVAL. */
2828 if (flags == VNOVAL)
2829 return (EOPNOTSUPP);
2830
2831 /*
2832 * Prevent non-root users from setting flags on devices. When
2833 * a device is reused, users can retain ownership of the device
2834 * if they are allowed to set flags and programs assume that
2835 * chown can't fail when done as root.
2836 */
2837 if (vp->v_type == VCHR || vp->v_type == VBLK) {
2838 error = priv_check(td, PRIV_VFS_CHFLAGS_DEV);
2839 if (error != 0)
2840 return (error);
2841 }
2842
2843 if ((error = vn_start_write(vp, &mp, V_WAIT | V_PCATCH)) != 0)
2844 return (error);
2845 VATTR_NULL(&vattr);
2846 vattr.va_flags = flags;
2847 vn_lock(vp, LK_EXCLUSIVE | LK_RETRY);
2848 #ifdef MAC
2849 error = mac_vnode_check_setflags(td->td_ucred, vp, vattr.va_flags);
2850 if (error == 0)
2851 #endif
2852 error = VOP_SETATTR(vp, &vattr, td->td_ucred);
2853 VOP_UNLOCK(vp);
2854 vn_finished_write(mp);
2855 return (error);
2856 }
2857
2858 /*
2859 * Change flags of a file given a path name.
2860 */
2861 #ifndef _SYS_SYSPROTO_H_
2862 struct chflags_args {
2863 const char *path;
2864 u_long flags;
2865 };
2866 #endif
2867 int
sys_chflags(struct thread * td,struct chflags_args * uap)2868 sys_chflags(struct thread *td, struct chflags_args *uap)
2869 {
2870
2871 return (kern_chflagsat(td, AT_FDCWD, uap->path, UIO_USERSPACE,
2872 uap->flags, 0));
2873 }
2874
2875 #ifndef _SYS_SYSPROTO_H_
2876 struct chflagsat_args {
2877 int fd;
2878 const char *path;
2879 u_long flags;
2880 int atflag;
2881 }
2882 #endif
2883 int
sys_chflagsat(struct thread * td,struct chflagsat_args * uap)2884 sys_chflagsat(struct thread *td, struct chflagsat_args *uap)
2885 {
2886
2887 return (kern_chflagsat(td, uap->fd, uap->path, UIO_USERSPACE,
2888 uap->flags, uap->atflag));
2889 }
2890
2891 /*
2892 * Same as chflags() but doesn't follow symlinks.
2893 */
2894 #ifndef _SYS_SYSPROTO_H_
2895 struct lchflags_args {
2896 const char *path;
2897 u_long flags;
2898 };
2899 #endif
2900 int
sys_lchflags(struct thread * td,struct lchflags_args * uap)2901 sys_lchflags(struct thread *td, struct lchflags_args *uap)
2902 {
2903
2904 return (kern_chflagsat(td, AT_FDCWD, uap->path, UIO_USERSPACE,
2905 uap->flags, AT_SYMLINK_NOFOLLOW));
2906 }
2907
2908 static int
kern_chflagsat(struct thread * td,int fd,const char * path,enum uio_seg pathseg,u_long flags,int atflag)2909 kern_chflagsat(struct thread *td, int fd, const char *path,
2910 enum uio_seg pathseg, u_long flags, int atflag)
2911 {
2912 struct nameidata nd;
2913 int error;
2914
2915 if ((atflag & ~(AT_SYMLINK_NOFOLLOW | AT_RESOLVE_BENEATH |
2916 AT_EMPTY_PATH)) != 0)
2917 return (EINVAL);
2918
2919 AUDIT_ARG_FFLAGS(flags);
2920 NDINIT_ATRIGHTS(&nd, LOOKUP, at2cnpflags(atflag, AT_SYMLINK_NOFOLLOW |
2921 AT_RESOLVE_BENEATH | AT_EMPTY_PATH) | AUDITVNODE1, pathseg, path,
2922 fd, &cap_fchflags_rights);
2923 if ((error = namei(&nd)) != 0)
2924 return (error);
2925 NDFREE_PNBUF(&nd);
2926 error = setfflags(td, nd.ni_vp, flags);
2927 vrele(nd.ni_vp);
2928 return (error);
2929 }
2930
2931 /*
2932 * Change flags of a file given a file descriptor.
2933 */
2934 #ifndef _SYS_SYSPROTO_H_
2935 struct fchflags_args {
2936 int fd;
2937 u_long flags;
2938 };
2939 #endif
2940 int
sys_fchflags(struct thread * td,struct fchflags_args * uap)2941 sys_fchflags(struct thread *td, struct fchflags_args *uap)
2942 {
2943 struct file *fp;
2944 int error;
2945
2946 AUDIT_ARG_FD(uap->fd);
2947 AUDIT_ARG_FFLAGS(uap->flags);
2948 error = getvnode(td, uap->fd, &cap_fchflags_rights,
2949 &fp);
2950 if (error != 0)
2951 return (error);
2952 #ifdef AUDIT
2953 if (AUDITING_TD(td)) {
2954 vn_lock(fp->f_vnode, LK_SHARED | LK_RETRY);
2955 AUDIT_ARG_VNODE1(fp->f_vnode);
2956 VOP_UNLOCK(fp->f_vnode);
2957 }
2958 #endif
2959 error = setfflags(td, fp->f_vnode, uap->flags);
2960 fdrop(fp, td);
2961 return (error);
2962 }
2963
2964 /*
2965 * Common implementation code for chmod(), lchmod() and fchmod().
2966 */
2967 int
setfmode(struct thread * td,struct ucred * cred,struct vnode * vp,int mode)2968 setfmode(struct thread *td, struct ucred *cred, struct vnode *vp, int mode)
2969 {
2970 struct mount *mp;
2971 struct vattr vattr;
2972 int error;
2973
2974 if ((error = vn_start_write(vp, &mp, V_WAIT | V_PCATCH)) != 0)
2975 return (error);
2976 vn_lock(vp, LK_EXCLUSIVE | LK_RETRY);
2977 VATTR_NULL(&vattr);
2978 vattr.va_mode = mode & ALLPERMS;
2979 #ifdef MAC
2980 error = mac_vnode_check_setmode(cred, vp, vattr.va_mode);
2981 if (error == 0)
2982 #endif
2983 error = VOP_SETATTR(vp, &vattr, cred);
2984 VOP_UNLOCK(vp);
2985 vn_finished_write(mp);
2986 return (error);
2987 }
2988
2989 /*
2990 * Change mode of a file given path name.
2991 */
2992 #ifndef _SYS_SYSPROTO_H_
2993 struct chmod_args {
2994 char *path;
2995 int mode;
2996 };
2997 #endif
2998 int
sys_chmod(struct thread * td,struct chmod_args * uap)2999 sys_chmod(struct thread *td, struct chmod_args *uap)
3000 {
3001
3002 return (kern_fchmodat(td, AT_FDCWD, uap->path, UIO_USERSPACE,
3003 uap->mode, 0));
3004 }
3005
3006 #ifndef _SYS_SYSPROTO_H_
3007 struct fchmodat_args {
3008 int dirfd;
3009 char *path;
3010 mode_t mode;
3011 int flag;
3012 }
3013 #endif
3014 int
sys_fchmodat(struct thread * td,struct fchmodat_args * uap)3015 sys_fchmodat(struct thread *td, struct fchmodat_args *uap)
3016 {
3017
3018 return (kern_fchmodat(td, uap->fd, uap->path, UIO_USERSPACE,
3019 uap->mode, uap->flag));
3020 }
3021
3022 /*
3023 * Change mode of a file given path name (don't follow links.)
3024 */
3025 #ifndef _SYS_SYSPROTO_H_
3026 struct lchmod_args {
3027 char *path;
3028 int mode;
3029 };
3030 #endif
3031 int
sys_lchmod(struct thread * td,struct lchmod_args * uap)3032 sys_lchmod(struct thread *td, struct lchmod_args *uap)
3033 {
3034
3035 return (kern_fchmodat(td, AT_FDCWD, uap->path, UIO_USERSPACE,
3036 uap->mode, AT_SYMLINK_NOFOLLOW));
3037 }
3038
3039 int
kern_fchmodat(struct thread * td,int fd,const char * path,enum uio_seg pathseg,mode_t mode,int flag)3040 kern_fchmodat(struct thread *td, int fd, const char *path,
3041 enum uio_seg pathseg, mode_t mode, int flag)
3042 {
3043 struct nameidata nd;
3044 int error;
3045
3046 if ((flag & ~(AT_SYMLINK_NOFOLLOW | AT_RESOLVE_BENEATH |
3047 AT_EMPTY_PATH)) != 0)
3048 return (EINVAL);
3049
3050 AUDIT_ARG_MODE(mode);
3051 NDINIT_ATRIGHTS(&nd, LOOKUP, at2cnpflags(flag, AT_SYMLINK_NOFOLLOW |
3052 AT_RESOLVE_BENEATH | AT_EMPTY_PATH) | AUDITVNODE1, pathseg, path,
3053 fd, &cap_fchmod_rights);
3054 if ((error = namei(&nd)) != 0)
3055 return (error);
3056 NDFREE_PNBUF(&nd);
3057 error = setfmode(td, td->td_ucred, nd.ni_vp, mode);
3058 vrele(nd.ni_vp);
3059 return (error);
3060 }
3061
3062 /*
3063 * Change mode of a file given a file descriptor.
3064 */
3065 #ifndef _SYS_SYSPROTO_H_
3066 struct fchmod_args {
3067 int fd;
3068 int mode;
3069 };
3070 #endif
3071 int
sys_fchmod(struct thread * td,struct fchmod_args * uap)3072 sys_fchmod(struct thread *td, struct fchmod_args *uap)
3073 {
3074 struct file *fp;
3075 int error;
3076
3077 AUDIT_ARG_FD(uap->fd);
3078 AUDIT_ARG_MODE(uap->mode);
3079
3080 error = fget(td, uap->fd, &cap_fchmod_rights, &fp);
3081 if (error != 0)
3082 return (error);
3083 error = fo_chmod(fp, uap->mode, td->td_ucred, td);
3084 fdrop(fp, td);
3085 return (error);
3086 }
3087
3088 /*
3089 * Common implementation for chown(), lchown(), and fchown()
3090 */
3091 int
setfown(struct thread * td,struct ucred * cred,struct vnode * vp,uid_t uid,gid_t gid)3092 setfown(struct thread *td, struct ucred *cred, struct vnode *vp, uid_t uid,
3093 gid_t gid)
3094 {
3095 struct mount *mp;
3096 struct vattr vattr;
3097 int error;
3098
3099 if ((error = vn_start_write(vp, &mp, V_WAIT | V_PCATCH)) != 0)
3100 return (error);
3101 vn_lock(vp, LK_EXCLUSIVE | LK_RETRY);
3102 VATTR_NULL(&vattr);
3103 vattr.va_uid = uid;
3104 vattr.va_gid = gid;
3105 #ifdef MAC
3106 error = mac_vnode_check_setowner(cred, vp, vattr.va_uid,
3107 vattr.va_gid);
3108 if (error == 0)
3109 #endif
3110 error = VOP_SETATTR(vp, &vattr, cred);
3111 VOP_UNLOCK(vp);
3112 vn_finished_write(mp);
3113 return (error);
3114 }
3115
3116 /*
3117 * Set ownership given a path name.
3118 */
3119 #ifndef _SYS_SYSPROTO_H_
3120 struct chown_args {
3121 char *path;
3122 int uid;
3123 int gid;
3124 };
3125 #endif
3126 int
sys_chown(struct thread * td,struct chown_args * uap)3127 sys_chown(struct thread *td, struct chown_args *uap)
3128 {
3129
3130 return (kern_fchownat(td, AT_FDCWD, uap->path, UIO_USERSPACE, uap->uid,
3131 uap->gid, 0));
3132 }
3133
3134 #ifndef _SYS_SYSPROTO_H_
3135 struct fchownat_args {
3136 int fd;
3137 const char * path;
3138 uid_t uid;
3139 gid_t gid;
3140 int flag;
3141 };
3142 #endif
3143 int
sys_fchownat(struct thread * td,struct fchownat_args * uap)3144 sys_fchownat(struct thread *td, struct fchownat_args *uap)
3145 {
3146
3147 return (kern_fchownat(td, uap->fd, uap->path, UIO_USERSPACE, uap->uid,
3148 uap->gid, uap->flag));
3149 }
3150
3151 int
kern_fchownat(struct thread * td,int fd,const char * path,enum uio_seg pathseg,int uid,int gid,int flag)3152 kern_fchownat(struct thread *td, int fd, const char *path,
3153 enum uio_seg pathseg, int uid, int gid, int flag)
3154 {
3155 struct nameidata nd;
3156 int error;
3157
3158 if ((flag & ~(AT_SYMLINK_NOFOLLOW | AT_RESOLVE_BENEATH |
3159 AT_EMPTY_PATH)) != 0)
3160 return (EINVAL);
3161
3162 AUDIT_ARG_OWNER(uid, gid);
3163 NDINIT_ATRIGHTS(&nd, LOOKUP, at2cnpflags(flag, AT_SYMLINK_NOFOLLOW |
3164 AT_RESOLVE_BENEATH | AT_EMPTY_PATH) | AUDITVNODE1, pathseg, path,
3165 fd, &cap_fchown_rights);
3166
3167 if ((error = namei(&nd)) != 0)
3168 return (error);
3169 NDFREE_PNBUF(&nd);
3170 error = setfown(td, td->td_ucred, nd.ni_vp, uid, gid);
3171 vrele(nd.ni_vp);
3172 return (error);
3173 }
3174
3175 /*
3176 * Set ownership given a path name, do not cross symlinks.
3177 */
3178 #ifndef _SYS_SYSPROTO_H_
3179 struct lchown_args {
3180 char *path;
3181 int uid;
3182 int gid;
3183 };
3184 #endif
3185 int
sys_lchown(struct thread * td,struct lchown_args * uap)3186 sys_lchown(struct thread *td, struct lchown_args *uap)
3187 {
3188
3189 return (kern_fchownat(td, AT_FDCWD, uap->path, UIO_USERSPACE,
3190 uap->uid, uap->gid, AT_SYMLINK_NOFOLLOW));
3191 }
3192
3193 /*
3194 * Set ownership given a file descriptor.
3195 */
3196 #ifndef _SYS_SYSPROTO_H_
3197 struct fchown_args {
3198 int fd;
3199 int uid;
3200 int gid;
3201 };
3202 #endif
3203 int
sys_fchown(struct thread * td,struct fchown_args * uap)3204 sys_fchown(struct thread *td, struct fchown_args *uap)
3205 {
3206 struct file *fp;
3207 int error;
3208
3209 AUDIT_ARG_FD(uap->fd);
3210 AUDIT_ARG_OWNER(uap->uid, uap->gid);
3211 error = fget(td, uap->fd, &cap_fchown_rights, &fp);
3212 if (error != 0)
3213 return (error);
3214 error = fo_chown(fp, uap->uid, uap->gid, td->td_ucred, td);
3215 fdrop(fp, td);
3216 return (error);
3217 }
3218
3219 /*
3220 * Common implementation code for utimes(), lutimes(), and futimes().
3221 */
3222 static int
getutimes(const struct timeval * usrtvp,enum uio_seg tvpseg,struct timespec * tsp)3223 getutimes(const struct timeval *usrtvp, enum uio_seg tvpseg,
3224 struct timespec *tsp)
3225 {
3226 struct timeval tv[2];
3227 const struct timeval *tvp;
3228 int error;
3229
3230 if (usrtvp == NULL) {
3231 vfs_timestamp(&tsp[0]);
3232 tsp[1] = tsp[0];
3233 } else {
3234 if (tvpseg == UIO_SYSSPACE) {
3235 tvp = usrtvp;
3236 } else {
3237 if ((error = copyin(usrtvp, tv, sizeof(tv))) != 0)
3238 return (error);
3239 tvp = tv;
3240 }
3241
3242 if (tvp[0].tv_usec < 0 || tvp[0].tv_usec >= 1000000 ||
3243 tvp[1].tv_usec < 0 || tvp[1].tv_usec >= 1000000)
3244 return (EINVAL);
3245 TIMEVAL_TO_TIMESPEC(&tvp[0], &tsp[0]);
3246 TIMEVAL_TO_TIMESPEC(&tvp[1], &tsp[1]);
3247 }
3248 return (0);
3249 }
3250
3251 /*
3252 * Common implementation code for futimens(), utimensat().
3253 */
3254 #define UTIMENS_NULL 0x1
3255 #define UTIMENS_EXIT 0x2
3256 static int
getutimens(const struct timespec * usrtsp,enum uio_seg tspseg,struct timespec * tsp,int * retflags)3257 getutimens(const struct timespec *usrtsp, enum uio_seg tspseg,
3258 struct timespec *tsp, int *retflags)
3259 {
3260 struct timespec tsnow;
3261 int error;
3262
3263 vfs_timestamp(&tsnow);
3264 *retflags = 0;
3265 if (usrtsp == NULL) {
3266 tsp[0] = tsnow;
3267 tsp[1] = tsnow;
3268 *retflags |= UTIMENS_NULL;
3269 return (0);
3270 }
3271 if (tspseg == UIO_SYSSPACE) {
3272 tsp[0] = usrtsp[0];
3273 tsp[1] = usrtsp[1];
3274 } else if ((error = copyin(usrtsp, tsp, sizeof(*tsp) * 2)) != 0)
3275 return (error);
3276 if (tsp[0].tv_nsec == UTIME_OMIT && tsp[1].tv_nsec == UTIME_OMIT)
3277 *retflags |= UTIMENS_EXIT;
3278 if (tsp[0].tv_nsec == UTIME_NOW && tsp[1].tv_nsec == UTIME_NOW)
3279 *retflags |= UTIMENS_NULL;
3280 if (tsp[0].tv_nsec == UTIME_OMIT)
3281 tsp[0].tv_sec = VNOVAL;
3282 else if (tsp[0].tv_nsec == UTIME_NOW)
3283 tsp[0] = tsnow;
3284 else if (tsp[0].tv_nsec < 0 || tsp[0].tv_nsec >= 1000000000L)
3285 return (EINVAL);
3286 if (tsp[1].tv_nsec == UTIME_OMIT)
3287 tsp[1].tv_sec = VNOVAL;
3288 else if (tsp[1].tv_nsec == UTIME_NOW)
3289 tsp[1] = tsnow;
3290 else if (tsp[1].tv_nsec < 0 || tsp[1].tv_nsec >= 1000000000L)
3291 return (EINVAL);
3292
3293 return (0);
3294 }
3295
3296 /*
3297 * Common implementation code for utimes(), lutimes(), futimes(), futimens(),
3298 * and utimensat().
3299 */
3300 static int
setutimes(struct thread * td,struct vnode * vp,const struct timespec * ts,int numtimes,int nullflag)3301 setutimes(struct thread *td, struct vnode *vp, const struct timespec *ts,
3302 int numtimes, int nullflag)
3303 {
3304 struct mount *mp;
3305 struct vattr vattr;
3306 int error;
3307 bool setbirthtime;
3308
3309 setbirthtime = false;
3310 vattr.va_birthtime.tv_sec = VNOVAL;
3311 vattr.va_birthtime.tv_nsec = 0;
3312
3313 if ((error = vn_start_write(vp, &mp, V_WAIT | V_PCATCH)) != 0)
3314 return (error);
3315 vn_lock(vp, LK_EXCLUSIVE | LK_RETRY);
3316 if (numtimes < 3 && VOP_GETATTR(vp, &vattr, td->td_ucred) == 0 &&
3317 timespeccmp(&ts[1], &vattr.va_birthtime, < ))
3318 setbirthtime = true;
3319 VATTR_NULL(&vattr);
3320 vattr.va_atime = ts[0];
3321 vattr.va_mtime = ts[1];
3322 if (setbirthtime)
3323 vattr.va_birthtime = ts[1];
3324 if (numtimes > 2)
3325 vattr.va_birthtime = ts[2];
3326 if (nullflag)
3327 vattr.va_vaflags |= VA_UTIMES_NULL;
3328 #ifdef MAC
3329 error = mac_vnode_check_setutimes(td->td_ucred, vp, vattr.va_atime,
3330 vattr.va_mtime);
3331 #endif
3332 if (error == 0)
3333 error = VOP_SETATTR(vp, &vattr, td->td_ucred);
3334 VOP_UNLOCK(vp);
3335 vn_finished_write(mp);
3336 return (error);
3337 }
3338
3339 /*
3340 * Set the access and modification times of a file.
3341 */
3342 #ifndef _SYS_SYSPROTO_H_
3343 struct utimes_args {
3344 char *path;
3345 struct timeval *tptr;
3346 };
3347 #endif
3348 int
sys_utimes(struct thread * td,struct utimes_args * uap)3349 sys_utimes(struct thread *td, struct utimes_args *uap)
3350 {
3351
3352 return (kern_utimesat(td, AT_FDCWD, uap->path, UIO_USERSPACE,
3353 uap->tptr, UIO_USERSPACE));
3354 }
3355
3356 #ifndef _SYS_SYSPROTO_H_
3357 struct futimesat_args {
3358 int fd;
3359 const char * path;
3360 const struct timeval * times;
3361 };
3362 #endif
3363 int
sys_futimesat(struct thread * td,struct futimesat_args * uap)3364 sys_futimesat(struct thread *td, struct futimesat_args *uap)
3365 {
3366
3367 return (kern_utimesat(td, uap->fd, uap->path, UIO_USERSPACE,
3368 uap->times, UIO_USERSPACE));
3369 }
3370
3371 int
kern_utimesat(struct thread * td,int fd,const char * path,enum uio_seg pathseg,const struct timeval * tptr,enum uio_seg tptrseg)3372 kern_utimesat(struct thread *td, int fd, const char *path,
3373 enum uio_seg pathseg, const struct timeval *tptr, enum uio_seg tptrseg)
3374 {
3375 struct nameidata nd;
3376 struct timespec ts[2];
3377 int error;
3378
3379 if ((error = getutimes(tptr, tptrseg, ts)) != 0)
3380 return (error);
3381 NDINIT_ATRIGHTS(&nd, LOOKUP, FOLLOW | AUDITVNODE1, pathseg, path, fd,
3382 &cap_futimes_rights);
3383
3384 if ((error = namei(&nd)) != 0)
3385 return (error);
3386 NDFREE_PNBUF(&nd);
3387 error = setutimes(td, nd.ni_vp, ts, 2, tptr == NULL);
3388 vrele(nd.ni_vp);
3389 return (error);
3390 }
3391
3392 /*
3393 * Set the access and modification times of a file.
3394 */
3395 #ifndef _SYS_SYSPROTO_H_
3396 struct lutimes_args {
3397 char *path;
3398 struct timeval *tptr;
3399 };
3400 #endif
3401 int
sys_lutimes(struct thread * td,struct lutimes_args * uap)3402 sys_lutimes(struct thread *td, struct lutimes_args *uap)
3403 {
3404
3405 return (kern_lutimes(td, uap->path, UIO_USERSPACE, uap->tptr,
3406 UIO_USERSPACE));
3407 }
3408
3409 int
kern_lutimes(struct thread * td,const char * path,enum uio_seg pathseg,const struct timeval * tptr,enum uio_seg tptrseg)3410 kern_lutimes(struct thread *td, const char *path, enum uio_seg pathseg,
3411 const struct timeval *tptr, enum uio_seg tptrseg)
3412 {
3413 struct timespec ts[2];
3414 struct nameidata nd;
3415 int error;
3416
3417 if ((error = getutimes(tptr, tptrseg, ts)) != 0)
3418 return (error);
3419 NDINIT(&nd, LOOKUP, NOFOLLOW | AUDITVNODE1, pathseg, path);
3420 if ((error = namei(&nd)) != 0)
3421 return (error);
3422 NDFREE_PNBUF(&nd);
3423 error = setutimes(td, nd.ni_vp, ts, 2, tptr == NULL);
3424 vrele(nd.ni_vp);
3425 return (error);
3426 }
3427
3428 /*
3429 * Set the access and modification times of a file.
3430 */
3431 #ifndef _SYS_SYSPROTO_H_
3432 struct futimes_args {
3433 int fd;
3434 struct timeval *tptr;
3435 };
3436 #endif
3437 int
sys_futimes(struct thread * td,struct futimes_args * uap)3438 sys_futimes(struct thread *td, struct futimes_args *uap)
3439 {
3440
3441 return (kern_futimes(td, uap->fd, uap->tptr, UIO_USERSPACE));
3442 }
3443
3444 int
kern_futimes(struct thread * td,int fd,const struct timeval * tptr,enum uio_seg tptrseg)3445 kern_futimes(struct thread *td, int fd, const struct timeval *tptr,
3446 enum uio_seg tptrseg)
3447 {
3448 struct timespec ts[2];
3449 struct file *fp;
3450 int error;
3451
3452 AUDIT_ARG_FD(fd);
3453 error = getutimes(tptr, tptrseg, ts);
3454 if (error != 0)
3455 return (error);
3456 error = getvnode(td, fd, &cap_futimes_rights, &fp);
3457 if (error != 0)
3458 return (error);
3459 #ifdef AUDIT
3460 if (AUDITING_TD(td)) {
3461 vn_lock(fp->f_vnode, LK_SHARED | LK_RETRY);
3462 AUDIT_ARG_VNODE1(fp->f_vnode);
3463 VOP_UNLOCK(fp->f_vnode);
3464 }
3465 #endif
3466 error = setutimes(td, fp->f_vnode, ts, 2, tptr == NULL);
3467 fdrop(fp, td);
3468 return (error);
3469 }
3470
3471 int
sys_futimens(struct thread * td,struct futimens_args * uap)3472 sys_futimens(struct thread *td, struct futimens_args *uap)
3473 {
3474
3475 return (kern_futimens(td, uap->fd, uap->times, UIO_USERSPACE));
3476 }
3477
3478 int
kern_futimens(struct thread * td,int fd,const struct timespec * tptr,enum uio_seg tptrseg)3479 kern_futimens(struct thread *td, int fd, const struct timespec *tptr,
3480 enum uio_seg tptrseg)
3481 {
3482 struct timespec ts[2];
3483 struct file *fp;
3484 int error, flags;
3485
3486 AUDIT_ARG_FD(fd);
3487 error = getutimens(tptr, tptrseg, ts, &flags);
3488 if (error != 0)
3489 return (error);
3490 if (flags & UTIMENS_EXIT)
3491 return (0);
3492 error = getvnode(td, fd, &cap_futimes_rights, &fp);
3493 if (error != 0)
3494 return (error);
3495 #ifdef AUDIT
3496 if (AUDITING_TD(td)) {
3497 vn_lock(fp->f_vnode, LK_SHARED | LK_RETRY);
3498 AUDIT_ARG_VNODE1(fp->f_vnode);
3499 VOP_UNLOCK(fp->f_vnode);
3500 }
3501 #endif
3502 error = setutimes(td, fp->f_vnode, ts, 2, flags & UTIMENS_NULL);
3503 fdrop(fp, td);
3504 return (error);
3505 }
3506
3507 int
sys_utimensat(struct thread * td,struct utimensat_args * uap)3508 sys_utimensat(struct thread *td, struct utimensat_args *uap)
3509 {
3510
3511 return (kern_utimensat(td, uap->fd, uap->path, UIO_USERSPACE,
3512 uap->times, UIO_USERSPACE, uap->flag));
3513 }
3514
3515 int
kern_utimensat(struct thread * td,int fd,const char * path,enum uio_seg pathseg,const struct timespec * tptr,enum uio_seg tptrseg,int flag)3516 kern_utimensat(struct thread *td, int fd, const char *path,
3517 enum uio_seg pathseg, const struct timespec *tptr, enum uio_seg tptrseg,
3518 int flag)
3519 {
3520 struct nameidata nd;
3521 struct timespec ts[2];
3522 int error, flags;
3523
3524 if ((flag & ~(AT_SYMLINK_NOFOLLOW | AT_RESOLVE_BENEATH |
3525 AT_EMPTY_PATH)) != 0)
3526 return (EINVAL);
3527
3528 if ((error = getutimens(tptr, tptrseg, ts, &flags)) != 0)
3529 return (error);
3530 NDINIT_ATRIGHTS(&nd, LOOKUP, at2cnpflags(flag, AT_SYMLINK_NOFOLLOW |
3531 AT_RESOLVE_BENEATH | AT_EMPTY_PATH) | AUDITVNODE1,
3532 pathseg, path, fd, &cap_futimes_rights);
3533 if ((error = namei(&nd)) != 0)
3534 return (error);
3535 /*
3536 * We are allowed to call namei() regardless of 2xUTIME_OMIT.
3537 * POSIX states:
3538 * "If both tv_nsec fields are UTIME_OMIT... EACCESS may be detected."
3539 * "Search permission is denied by a component of the path prefix."
3540 */
3541 NDFREE_PNBUF(&nd);
3542 if ((flags & UTIMENS_EXIT) == 0)
3543 error = setutimes(td, nd.ni_vp, ts, 2, flags & UTIMENS_NULL);
3544 vrele(nd.ni_vp);
3545 return (error);
3546 }
3547
3548 /*
3549 * Truncate a file given its path name.
3550 */
3551 #ifndef _SYS_SYSPROTO_H_
3552 struct truncate_args {
3553 char *path;
3554 int pad;
3555 off_t length;
3556 };
3557 #endif
3558 int
sys_truncate(struct thread * td,struct truncate_args * uap)3559 sys_truncate(struct thread *td, struct truncate_args *uap)
3560 {
3561
3562 return (kern_truncate(td, uap->path, UIO_USERSPACE, uap->length));
3563 }
3564
3565 int
kern_truncate(struct thread * td,const char * path,enum uio_seg pathseg,off_t length)3566 kern_truncate(struct thread *td, const char *path, enum uio_seg pathseg,
3567 off_t length)
3568 {
3569 struct mount *mp;
3570 struct vnode *vp;
3571 void *rl_cookie;
3572 struct nameidata nd;
3573 int error;
3574
3575 if (length < 0)
3576 return (EINVAL);
3577 NDPREINIT(&nd);
3578 retry:
3579 NDINIT(&nd, LOOKUP, FOLLOW | AUDITVNODE1, pathseg, path);
3580 if ((error = namei(&nd)) != 0)
3581 return (error);
3582 vp = nd.ni_vp;
3583 NDFREE_PNBUF(&nd);
3584 rl_cookie = vn_rangelock_wlock(vp, 0, OFF_MAX);
3585 if ((error = vn_start_write(vp, &mp, V_WAIT | V_PCATCH)) != 0) {
3586 vn_rangelock_unlock(vp, rl_cookie);
3587 vrele(vp);
3588 return (error);
3589 }
3590 vn_lock(vp, LK_EXCLUSIVE | LK_RETRY);
3591 if (vp->v_type == VDIR) {
3592 error = EISDIR;
3593 goto out;
3594 }
3595 #ifdef MAC
3596 error = mac_vnode_check_write(td->td_ucred, NOCRED, vp);
3597 if (error != 0)
3598 goto out;
3599 #endif
3600 error = VOP_ACCESS(vp, VWRITE, td->td_ucred, td);
3601 if (error != 0)
3602 goto out;
3603
3604 error = vn_truncate_locked(vp, length, false, td->td_ucred);
3605 out:
3606 VOP_UNLOCK(vp);
3607 vn_finished_write(mp);
3608 vn_rangelock_unlock(vp, rl_cookie);
3609 vrele(vp);
3610 if (error == ERELOOKUP)
3611 goto retry;
3612 return (error);
3613 }
3614
3615 #if defined(COMPAT_43)
3616 /*
3617 * Truncate a file given its path name.
3618 */
3619 #ifndef _SYS_SYSPROTO_H_
3620 struct otruncate_args {
3621 char *path;
3622 long length;
3623 };
3624 #endif
3625 int
otruncate(struct thread * td,struct otruncate_args * uap)3626 otruncate(struct thread *td, struct otruncate_args *uap)
3627 {
3628
3629 return (kern_truncate(td, uap->path, UIO_USERSPACE, uap->length));
3630 }
3631 #endif /* COMPAT_43 */
3632
3633 #if defined(COMPAT_FREEBSD6)
3634 /* Versions with the pad argument */
3635 int
freebsd6_truncate(struct thread * td,struct freebsd6_truncate_args * uap)3636 freebsd6_truncate(struct thread *td, struct freebsd6_truncate_args *uap)
3637 {
3638
3639 return (kern_truncate(td, uap->path, UIO_USERSPACE, uap->length));
3640 }
3641
3642 int
freebsd6_ftruncate(struct thread * td,struct freebsd6_ftruncate_args * uap)3643 freebsd6_ftruncate(struct thread *td, struct freebsd6_ftruncate_args *uap)
3644 {
3645
3646 return (kern_ftruncate(td, uap->fd, uap->length));
3647 }
3648 #endif
3649
3650 int
kern_fsync(struct thread * td,int fd,bool fullsync)3651 kern_fsync(struct thread *td, int fd, bool fullsync)
3652 {
3653 struct vnode *vp;
3654 struct mount *mp;
3655 struct file *fp;
3656 int error;
3657
3658 AUDIT_ARG_FD(fd);
3659 error = getvnode(td, fd, &cap_fsync_rights, &fp);
3660 if (error != 0)
3661 return (error);
3662 vp = fp->f_vnode;
3663 #if 0
3664 if (!fullsync)
3665 /* XXXKIB: compete outstanding aio writes */;
3666 #endif
3667 retry:
3668 error = vn_start_write(vp, &mp, V_WAIT | V_PCATCH);
3669 if (error != 0)
3670 goto drop;
3671 vn_lock(vp, vn_lktype_write(mp, vp) | LK_RETRY);
3672 AUDIT_ARG_VNODE1(vp);
3673 vnode_pager_clean_async(vp);
3674 error = fullsync ? VOP_FSYNC(vp, MNT_WAIT, td) : VOP_FDATASYNC(vp, td);
3675 VOP_UNLOCK(vp);
3676 vn_finished_write(mp);
3677 if (error == ERELOOKUP)
3678 goto retry;
3679 drop:
3680 fdrop(fp, td);
3681 return (error);
3682 }
3683
3684 /*
3685 * Sync an open file.
3686 */
3687 #ifndef _SYS_SYSPROTO_H_
3688 struct fsync_args {
3689 int fd;
3690 };
3691 #endif
3692 int
sys_fsync(struct thread * td,struct fsync_args * uap)3693 sys_fsync(struct thread *td, struct fsync_args *uap)
3694 {
3695
3696 return (kern_fsync(td, uap->fd, true));
3697 }
3698
3699 int
sys_fdatasync(struct thread * td,struct fdatasync_args * uap)3700 sys_fdatasync(struct thread *td, struct fdatasync_args *uap)
3701 {
3702
3703 return (kern_fsync(td, uap->fd, false));
3704 }
3705
3706 /*
3707 * Rename files. Source and destination must either both be directories, or
3708 * both not be directories. If target is a directory, it must be empty.
3709 */
3710 #ifndef _SYS_SYSPROTO_H_
3711 struct rename_args {
3712 char *from;
3713 char *to;
3714 };
3715 #endif
3716 int
sys_rename(struct thread * td,struct rename_args * uap)3717 sys_rename(struct thread *td, struct rename_args *uap)
3718 {
3719
3720 return (kern_renameat(td, AT_FDCWD, uap->from, AT_FDCWD,
3721 uap->to, UIO_USERSPACE));
3722 }
3723
3724 #ifndef _SYS_SYSPROTO_H_
3725 struct renameat_args {
3726 int oldfd;
3727 char *old;
3728 int newfd;
3729 char *new;
3730 };
3731 #endif
3732 int
sys_renameat(struct thread * td,struct renameat_args * uap)3733 sys_renameat(struct thread *td, struct renameat_args *uap)
3734 {
3735
3736 return (kern_renameat(td, uap->oldfd, uap->old, uap->newfd, uap->new,
3737 UIO_USERSPACE));
3738 }
3739
3740 #ifdef MAC
3741 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)3742 kern_renameat_mac(struct thread *td, int oldfd, const char *old, int newfd,
3743 const char *new, enum uio_seg pathseg, struct nameidata *fromnd)
3744 {
3745 int error;
3746
3747 NDINIT_ATRIGHTS(fromnd, DELETE, LOCKPARENT | LOCKLEAF | AUDITVNODE1,
3748 pathseg, old, oldfd, &cap_renameat_source_rights);
3749 if ((error = namei(fromnd)) != 0)
3750 return (error);
3751 error = mac_vnode_check_rename_from(td->td_ucred, fromnd->ni_dvp,
3752 fromnd->ni_vp, &fromnd->ni_cnd);
3753 VOP_UNLOCK(fromnd->ni_dvp);
3754 if (fromnd->ni_dvp != fromnd->ni_vp)
3755 VOP_UNLOCK(fromnd->ni_vp);
3756 if (error != 0) {
3757 NDFREE_PNBUF(fromnd);
3758 vrele(fromnd->ni_dvp);
3759 vrele(fromnd->ni_vp);
3760 }
3761 return (error);
3762 }
3763 #endif
3764
3765 int
kern_renameat(struct thread * td,int oldfd,const char * old,int newfd,const char * new,enum uio_seg pathseg)3766 kern_renameat(struct thread *td, int oldfd, const char *old, int newfd,
3767 const char *new, enum uio_seg pathseg)
3768 {
3769 struct mount *mp = NULL;
3770 struct vnode *tvp, *fvp, *tdvp;
3771 struct nameidata fromnd, tond;
3772 uint64_t tondflags;
3773 int error;
3774 short irflag;
3775
3776 again:
3777 bwillwrite();
3778 #ifdef MAC
3779 if (mac_vnode_check_rename_from_enabled()) {
3780 error = kern_renameat_mac(td, oldfd, old, newfd, new, pathseg,
3781 &fromnd);
3782 if (error != 0)
3783 return (error);
3784 } else {
3785 #endif
3786 NDINIT_ATRIGHTS(&fromnd, DELETE, WANTPARENT | AUDITVNODE1,
3787 pathseg, old, oldfd, &cap_renameat_source_rights);
3788 if ((error = namei(&fromnd)) != 0)
3789 return (error);
3790 #ifdef MAC
3791 }
3792 #endif
3793 fvp = fromnd.ni_vp;
3794 tondflags = LOCKPARENT | LOCKLEAF | NOCACHE | AUDITVNODE2;
3795 if (fromnd.ni_vp->v_type == VDIR)
3796 tondflags |= WILLBEDIR;
3797 NDINIT_ATRIGHTS(&tond, RENAME, tondflags, pathseg, new, newfd,
3798 &cap_renameat_target_rights);
3799 if ((error = namei(&tond)) != 0) {
3800 /* Translate error code for rename("dir1", "dir2/."). */
3801 if (error == EISDIR && fvp->v_type == VDIR)
3802 error = EINVAL;
3803 NDFREE_PNBUF(&fromnd);
3804 vrele(fromnd.ni_dvp);
3805 vrele(fvp);
3806 goto out1;
3807 }
3808 tdvp = tond.ni_dvp;
3809 tvp = tond.ni_vp;
3810 error = vn_start_write(fvp, &mp, V_NOWAIT);
3811 if (error != 0) {
3812 NDFREE_PNBUF(&fromnd);
3813 NDFREE_PNBUF(&tond);
3814 if (tvp != NULL)
3815 vput(tvp);
3816 if (tdvp == tvp)
3817 vrele(tdvp);
3818 else
3819 vput(tdvp);
3820 vrele(fromnd.ni_dvp);
3821 vrele(fvp);
3822 error = vn_start_write(NULL, &mp, V_XSLEEP | V_PCATCH);
3823 if (error != 0)
3824 return (error);
3825 goto again;
3826 }
3827 irflag = vn_irflag_read(fvp);
3828 if (((irflag & VIRF_NAMEDATTR) != 0 && tdvp != fromnd.ni_dvp) ||
3829 (irflag & VIRF_NAMEDDIR) != 0) {
3830 error = EINVAL;
3831 goto out;
3832 }
3833 if (tvp != NULL) {
3834 if (fvp->v_type == VDIR && tvp->v_type != VDIR) {
3835 error = ENOTDIR;
3836 goto out;
3837 } else if (fvp->v_type != VDIR && tvp->v_type == VDIR) {
3838 error = EISDIR;
3839 goto out;
3840 }
3841 #ifdef CAPABILITIES
3842 if (newfd != AT_FDCWD && (tond.ni_resflags & NIRES_ABS) == 0) {
3843 /*
3844 * If the target already exists we require CAP_UNLINKAT
3845 * from 'newfd', when newfd was used for the lookup.
3846 */
3847 error = cap_check(&tond.ni_filecaps.fc_rights,
3848 &cap_unlinkat_rights);
3849 if (error != 0)
3850 goto out;
3851 }
3852 #endif
3853 }
3854 if (fvp == tdvp) {
3855 error = EINVAL;
3856 goto out;
3857 }
3858 /*
3859 * If the source is the same as the destination (that is, if they
3860 * are links to the same vnode), then there is nothing to do.
3861 */
3862 if (fvp == tvp)
3863 error = ERESTART;
3864 #ifdef MAC
3865 else
3866 error = mac_vnode_check_rename_to(td->td_ucred, tdvp,
3867 tond.ni_vp, fromnd.ni_dvp == tdvp, &tond.ni_cnd);
3868 #endif
3869 out:
3870 if (error == 0) {
3871 error = VOP_RENAME(fromnd.ni_dvp, fromnd.ni_vp, &fromnd.ni_cnd,
3872 tond.ni_dvp, tond.ni_vp, &tond.ni_cnd);
3873 NDFREE_PNBUF(&fromnd);
3874 NDFREE_PNBUF(&tond);
3875 } else {
3876 NDFREE_PNBUF(&fromnd);
3877 NDFREE_PNBUF(&tond);
3878 if (tvp != NULL)
3879 vput(tvp);
3880 if (tdvp == tvp)
3881 vrele(tdvp);
3882 else
3883 vput(tdvp);
3884 vrele(fromnd.ni_dvp);
3885 vrele(fvp);
3886 }
3887 vn_finished_write(mp);
3888 out1:
3889 if (error == ERESTART)
3890 return (0);
3891 if (error == ERELOOKUP)
3892 goto again;
3893 return (error);
3894 }
3895
3896 /*
3897 * Make a directory file.
3898 */
3899 #ifndef _SYS_SYSPROTO_H_
3900 struct mkdir_args {
3901 char *path;
3902 int mode;
3903 };
3904 #endif
3905 int
sys_mkdir(struct thread * td,struct mkdir_args * uap)3906 sys_mkdir(struct thread *td, struct mkdir_args *uap)
3907 {
3908
3909 return (kern_mkdirat(td, AT_FDCWD, uap->path, UIO_USERSPACE,
3910 uap->mode));
3911 }
3912
3913 #ifndef _SYS_SYSPROTO_H_
3914 struct mkdirat_args {
3915 int fd;
3916 char *path;
3917 mode_t mode;
3918 };
3919 #endif
3920 int
sys_mkdirat(struct thread * td,struct mkdirat_args * uap)3921 sys_mkdirat(struct thread *td, struct mkdirat_args *uap)
3922 {
3923
3924 return (kern_mkdirat(td, uap->fd, uap->path, UIO_USERSPACE, uap->mode));
3925 }
3926
3927 int
kern_mkdirat(struct thread * td,int fd,const char * path,enum uio_seg segflg,int mode)3928 kern_mkdirat(struct thread *td, int fd, const char *path, enum uio_seg segflg,
3929 int mode)
3930 {
3931 struct mount *mp;
3932 struct vattr vattr;
3933 struct nameidata nd;
3934 int error;
3935
3936 AUDIT_ARG_MODE(mode);
3937 NDPREINIT(&nd);
3938 restart:
3939 bwillwrite();
3940 NDINIT_ATRIGHTS(&nd, CREATE, LOCKPARENT | AUDITVNODE1 |
3941 NC_NOMAKEENTRY | NC_KEEPPOSENTRY | FAILIFEXISTS | WILLBEDIR,
3942 segflg, path, fd, &cap_mkdirat_rights);
3943 if ((error = namei(&nd)) != 0)
3944 return (error);
3945 if (vn_start_write(nd.ni_dvp, &mp, V_NOWAIT) != 0) {
3946 NDFREE_PNBUF(&nd);
3947 vput(nd.ni_dvp);
3948 if ((error = vn_start_write(NULL, &mp, V_XSLEEP | V_PCATCH)) != 0)
3949 return (error);
3950 goto restart;
3951 }
3952 if ((vn_irflag_read(nd.ni_dvp) & VIRF_NAMEDDIR) != 0) {
3953 error = EINVAL;
3954 goto out;
3955 }
3956 VATTR_NULL(&vattr);
3957 vattr.va_type = VDIR;
3958 vattr.va_mode = (mode & ACCESSPERMS) &~ td->td_proc->p_pd->pd_cmask;
3959 #ifdef MAC
3960 error = mac_vnode_check_create(td->td_ucred, nd.ni_dvp, &nd.ni_cnd,
3961 &vattr);
3962 if (error != 0)
3963 goto out;
3964 #endif
3965 error = VOP_MKDIR(nd.ni_dvp, &nd.ni_vp, &nd.ni_cnd, &vattr);
3966 out:
3967 NDFREE_PNBUF(&nd);
3968 VOP_VPUT_PAIR(nd.ni_dvp, error == 0 ? &nd.ni_vp : NULL, true);
3969 vn_finished_write(mp);
3970 if (error == ERELOOKUP)
3971 goto restart;
3972 return (error);
3973 }
3974
3975 /*
3976 * Remove a directory file.
3977 */
3978 #ifndef _SYS_SYSPROTO_H_
3979 struct rmdir_args {
3980 char *path;
3981 };
3982 #endif
3983 int
sys_rmdir(struct thread * td,struct rmdir_args * uap)3984 sys_rmdir(struct thread *td, struct rmdir_args *uap)
3985 {
3986
3987 return (kern_frmdirat(td, AT_FDCWD, uap->path, FD_NONE, UIO_USERSPACE,
3988 0));
3989 }
3990
3991 int
kern_frmdirat(struct thread * td,int dfd,const char * path,int fd,enum uio_seg pathseg,int flag)3992 kern_frmdirat(struct thread *td, int dfd, const char *path, int fd,
3993 enum uio_seg pathseg, int flag)
3994 {
3995 struct mount *mp;
3996 struct vnode *vp;
3997 struct file *fp;
3998 struct nameidata nd;
3999 cap_rights_t rights;
4000 int error;
4001
4002 fp = NULL;
4003 if (fd != FD_NONE) {
4004 error = getvnode(td, fd, cap_rights_init_one(&rights,
4005 CAP_LOOKUP), &fp);
4006 if (error != 0)
4007 return (error);
4008 }
4009
4010 NDPREINIT(&nd);
4011 restart:
4012 bwillwrite();
4013 NDINIT_ATRIGHTS(&nd, DELETE, LOCKPARENT | LOCKLEAF | AUDITVNODE1 |
4014 at2cnpflags(flag, AT_RESOLVE_BENEATH),
4015 pathseg, path, dfd, &cap_unlinkat_rights);
4016 if ((error = namei(&nd)) != 0)
4017 goto fdout;
4018 vp = nd.ni_vp;
4019 if (vp->v_type != VDIR) {
4020 error = ENOTDIR;
4021 goto out;
4022 }
4023 /*
4024 * No rmdir "." please.
4025 */
4026 if (nd.ni_dvp == vp) {
4027 error = EINVAL;
4028 goto out;
4029 }
4030 /*
4031 * The root of a mounted filesystem cannot be deleted.
4032 */
4033 if (vp->v_vflag & VV_ROOT) {
4034 error = EBUSY;
4035 goto out;
4036 }
4037
4038 if (fp != NULL && fp->f_vnode != vp) {
4039 if (VN_IS_DOOMED(fp->f_vnode))
4040 error = EBADF;
4041 else
4042 error = EDEADLK;
4043 goto out;
4044 }
4045
4046 #ifdef MAC
4047 error = mac_vnode_check_unlink(td->td_ucred, nd.ni_dvp, vp,
4048 &nd.ni_cnd);
4049 if (error != 0)
4050 goto out;
4051 #endif
4052 if (vn_start_write(nd.ni_dvp, &mp, V_NOWAIT) != 0) {
4053 NDFREE_PNBUF(&nd);
4054 vput(vp);
4055 if (nd.ni_dvp == vp)
4056 vrele(nd.ni_dvp);
4057 else
4058 vput(nd.ni_dvp);
4059 if ((error = vn_start_write(NULL, &mp, V_XSLEEP | V_PCATCH)) != 0)
4060 goto fdout;
4061 goto restart;
4062 }
4063 error = VOP_RMDIR(nd.ni_dvp, nd.ni_vp, &nd.ni_cnd);
4064 vn_finished_write(mp);
4065 out:
4066 NDFREE_PNBUF(&nd);
4067 vput(vp);
4068 if (nd.ni_dvp == vp)
4069 vrele(nd.ni_dvp);
4070 else
4071 vput(nd.ni_dvp);
4072 if (error == ERELOOKUP)
4073 goto restart;
4074 fdout:
4075 if (fp != NULL)
4076 fdrop(fp, td);
4077 return (error);
4078 }
4079
4080 #if defined(COMPAT_43) || defined(COMPAT_FREEBSD11)
4081 int
freebsd11_kern_getdirentries(struct thread * td,int fd,char * ubuf,u_int count,long * basep,void (* func)(struct freebsd11_dirent *))4082 freebsd11_kern_getdirentries(struct thread *td, int fd, char *ubuf, u_int count,
4083 long *basep, void (*func)(struct freebsd11_dirent *))
4084 {
4085 struct freebsd11_dirent dstdp;
4086 struct dirent *dp, *edp;
4087 char *dirbuf;
4088 off_t base;
4089 ssize_t resid, ucount;
4090 int error;
4091
4092 /* XXX arbitrary sanity limit on `count'. */
4093 count = min(count, 64 * 1024);
4094
4095 dirbuf = malloc(count, M_TEMP, M_WAITOK);
4096
4097 error = kern_getdirentries(td, fd, dirbuf, count, &base, &resid,
4098 UIO_SYSSPACE);
4099 if (error != 0)
4100 goto done;
4101 if (basep != NULL)
4102 *basep = base;
4103
4104 ucount = 0;
4105 for (dp = (struct dirent *)dirbuf,
4106 edp = (struct dirent *)&dirbuf[count - resid];
4107 ucount < count && dp < edp; ) {
4108 if (dp->d_reclen == 0)
4109 break;
4110 MPASS(dp->d_reclen >= _GENERIC_DIRLEN(0));
4111 if (dp->d_namlen >= sizeof(dstdp.d_name))
4112 continue;
4113 dstdp.d_type = dp->d_type;
4114 dstdp.d_namlen = dp->d_namlen;
4115 dstdp.d_fileno = dp->d_fileno; /* truncate */
4116 if (dstdp.d_fileno != dp->d_fileno) {
4117 switch (ino64_trunc_error) {
4118 default:
4119 case 0:
4120 break;
4121 case 1:
4122 error = EOVERFLOW;
4123 goto done;
4124 case 2:
4125 dstdp.d_fileno = UINT32_MAX;
4126 break;
4127 }
4128 }
4129 dstdp.d_reclen = sizeof(dstdp) - sizeof(dstdp.d_name) +
4130 ((dp->d_namlen + 1 + 3) &~ 3);
4131 bcopy(dp->d_name, dstdp.d_name, dstdp.d_namlen);
4132 bzero(dstdp.d_name + dstdp.d_namlen,
4133 dstdp.d_reclen - offsetof(struct freebsd11_dirent, d_name) -
4134 dstdp.d_namlen);
4135 MPASS(dstdp.d_reclen <= dp->d_reclen);
4136 MPASS(ucount + dstdp.d_reclen <= count);
4137 if (func != NULL)
4138 func(&dstdp);
4139 error = copyout(&dstdp, ubuf + ucount, dstdp.d_reclen);
4140 if (error != 0)
4141 break;
4142 dp = (struct dirent *)((char *)dp + dp->d_reclen);
4143 ucount += dstdp.d_reclen;
4144 }
4145
4146 done:
4147 free(dirbuf, M_TEMP);
4148 if (error == 0)
4149 td->td_retval[0] = ucount;
4150 return (error);
4151 }
4152 #endif /* COMPAT */
4153
4154 #ifdef COMPAT_43
4155 static void
ogetdirentries_cvt(struct freebsd11_dirent * dp)4156 ogetdirentries_cvt(struct freebsd11_dirent *dp)
4157 {
4158 #if (BYTE_ORDER == LITTLE_ENDIAN)
4159 /*
4160 * The expected low byte of dp->d_namlen is our dp->d_type.
4161 * The high MBZ byte of dp->d_namlen is our dp->d_namlen.
4162 */
4163 dp->d_type = dp->d_namlen;
4164 dp->d_namlen = 0;
4165 #else
4166 /*
4167 * The dp->d_type is the high byte of the expected dp->d_namlen,
4168 * so must be zero'ed.
4169 */
4170 dp->d_type = 0;
4171 #endif
4172 }
4173
4174 /*
4175 * Read a block of directory entries in a filesystem independent format.
4176 */
4177 #ifndef _SYS_SYSPROTO_H_
4178 struct ogetdirentries_args {
4179 int fd;
4180 char *buf;
4181 u_int count;
4182 long *basep;
4183 };
4184 #endif
4185 int
ogetdirentries(struct thread * td,struct ogetdirentries_args * uap)4186 ogetdirentries(struct thread *td, struct ogetdirentries_args *uap)
4187 {
4188 long loff;
4189 int error;
4190
4191 error = kern_ogetdirentries(td, uap, &loff);
4192 if (error == 0)
4193 error = copyout(&loff, uap->basep, sizeof(long));
4194 return (error);
4195 }
4196
4197 int
kern_ogetdirentries(struct thread * td,struct ogetdirentries_args * uap,long * ploff)4198 kern_ogetdirentries(struct thread *td, struct ogetdirentries_args *uap,
4199 long *ploff)
4200 {
4201 long base;
4202 int error;
4203
4204 /* XXX arbitrary sanity limit on `count'. */
4205 if (uap->count > 64 * 1024)
4206 return (EINVAL);
4207
4208 error = freebsd11_kern_getdirentries(td, uap->fd, uap->buf, uap->count,
4209 &base, ogetdirentries_cvt);
4210
4211 if (error == 0 && uap->basep != NULL)
4212 error = copyout(&base, uap->basep, sizeof(long));
4213
4214 return (error);
4215 }
4216 #endif /* COMPAT_43 */
4217
4218 #if defined(COMPAT_FREEBSD11)
4219 #ifndef _SYS_SYSPROTO_H_
4220 struct freebsd11_getdirentries_args {
4221 int fd;
4222 char *buf;
4223 u_int count;
4224 long *basep;
4225 };
4226 #endif
4227 int
freebsd11_getdirentries(struct thread * td,struct freebsd11_getdirentries_args * uap)4228 freebsd11_getdirentries(struct thread *td,
4229 struct freebsd11_getdirentries_args *uap)
4230 {
4231 long base;
4232 int error;
4233
4234 error = freebsd11_kern_getdirentries(td, uap->fd, uap->buf, uap->count,
4235 &base, NULL);
4236
4237 if (error == 0 && uap->basep != NULL)
4238 error = copyout(&base, uap->basep, sizeof(long));
4239 return (error);
4240 }
4241
4242 int
freebsd11_getdents(struct thread * td,struct freebsd11_getdents_args * uap)4243 freebsd11_getdents(struct thread *td, struct freebsd11_getdents_args *uap)
4244 {
4245 struct freebsd11_getdirentries_args ap;
4246
4247 ap.fd = uap->fd;
4248 ap.buf = uap->buf;
4249 ap.count = uap->count;
4250 ap.basep = NULL;
4251 return (freebsd11_getdirentries(td, &ap));
4252 }
4253 #endif /* COMPAT_FREEBSD11 */
4254
4255 /*
4256 * Read a block of directory entries in a filesystem independent format.
4257 */
4258 int
sys_getdirentries(struct thread * td,struct getdirentries_args * uap)4259 sys_getdirentries(struct thread *td, struct getdirentries_args *uap)
4260 {
4261 off_t base;
4262 int error;
4263
4264 error = kern_getdirentries(td, uap->fd, uap->buf, uap->count, &base,
4265 NULL, UIO_USERSPACE);
4266 if (error != 0)
4267 return (error);
4268 if (uap->basep != NULL)
4269 error = copyout(&base, uap->basep, sizeof(off_t));
4270 return (error);
4271 }
4272
4273 int
kern_getdirentries(struct thread * td,int fd,char * buf,size_t count,off_t * basep,ssize_t * residp,enum uio_seg bufseg)4274 kern_getdirentries(struct thread *td, int fd, char *buf, size_t count,
4275 off_t *basep, ssize_t *residp, enum uio_seg bufseg)
4276 {
4277 struct vnode *vp;
4278 struct file *fp;
4279 struct uio auio;
4280 struct iovec aiov;
4281 off_t loff;
4282 int error, eofflag;
4283 off_t foffset;
4284
4285 AUDIT_ARG_FD(fd);
4286 if (count > IOSIZE_MAX)
4287 return (EINVAL);
4288 auio.uio_resid = count;
4289 error = getvnode(td, fd, &cap_read_rights, &fp);
4290 if (error != 0)
4291 return (error);
4292 if ((fp->f_flag & FREAD) == 0) {
4293 fdrop(fp, td);
4294 return (EBADF);
4295 }
4296 vp = fp->f_vnode;
4297 foffset = foffset_lock(fp, 0);
4298 unionread:
4299 if (vp->v_type != VDIR) {
4300 error = EINVAL;
4301 goto fail;
4302 }
4303 if (__predict_false((vp->v_vflag & VV_UNLINKED) != 0)) {
4304 error = ENOENT;
4305 goto fail;
4306 }
4307 aiov.iov_base = buf;
4308 aiov.iov_len = count;
4309 auio.uio_iov = &aiov;
4310 auio.uio_iovcnt = 1;
4311 auio.uio_rw = UIO_READ;
4312 auio.uio_segflg = bufseg;
4313 auio.uio_td = td;
4314 vn_lock(vp, LK_SHARED | LK_RETRY);
4315 AUDIT_ARG_VNODE1(vp);
4316 loff = auio.uio_offset = foffset;
4317 #ifdef MAC
4318 error = mac_vnode_check_readdir(td->td_ucred, vp);
4319 if (error == 0)
4320 #endif
4321 error = VOP_READDIR(vp, &auio, fp->f_cred, &eofflag, NULL,
4322 NULL);
4323 foffset = auio.uio_offset;
4324 if (error != 0) {
4325 VOP_UNLOCK(vp);
4326 goto fail;
4327 }
4328 if (count == auio.uio_resid &&
4329 (vp->v_vflag & VV_ROOT) &&
4330 (vp->v_mount->mnt_flag & MNT_UNION)) {
4331 struct vnode *tvp = vp;
4332
4333 vp = vp->v_mount->mnt_vnodecovered;
4334 VREF(vp);
4335 fp->f_vnode = vp;
4336 foffset = 0;
4337 vput(tvp);
4338 goto unionread;
4339 }
4340 VOP_UNLOCK(vp);
4341 *basep = loff;
4342 if (residp != NULL)
4343 *residp = auio.uio_resid;
4344 td->td_retval[0] = count - auio.uio_resid;
4345 fail:
4346 foffset_unlock(fp, foffset, 0);
4347 fdrop(fp, td);
4348 return (error);
4349 }
4350
4351 /*
4352 * Set the mode mask for creation of filesystem nodes.
4353 */
4354 #ifndef _SYS_SYSPROTO_H_
4355 struct umask_args {
4356 int newmask;
4357 };
4358 #endif
4359 int
sys_umask(struct thread * td,struct umask_args * uap)4360 sys_umask(struct thread *td, struct umask_args *uap)
4361 {
4362 struct pwddesc *pdp;
4363
4364 pdp = td->td_proc->p_pd;
4365 PWDDESC_XLOCK(pdp);
4366 td->td_retval[0] = pdp->pd_cmask;
4367 pdp->pd_cmask = uap->newmask & ALLPERMS;
4368 PWDDESC_XUNLOCK(pdp);
4369 return (0);
4370 }
4371
4372 /*
4373 * Void all references to file by ripping underlying filesystem away from
4374 * vnode.
4375 */
4376 #ifndef _SYS_SYSPROTO_H_
4377 struct revoke_args {
4378 char *path;
4379 };
4380 #endif
4381 int
sys_revoke(struct thread * td,struct revoke_args * uap)4382 sys_revoke(struct thread *td, struct revoke_args *uap)
4383 {
4384 struct vnode *vp;
4385 struct vattr vattr;
4386 struct nameidata nd;
4387 int error;
4388
4389 NDINIT(&nd, LOOKUP, FOLLOW | LOCKLEAF | AUDITVNODE1, UIO_USERSPACE,
4390 uap->path);
4391 if ((error = namei(&nd)) != 0)
4392 return (error);
4393 vp = nd.ni_vp;
4394 NDFREE_PNBUF(&nd);
4395 if (vp->v_type != VCHR || vp->v_rdev == NULL) {
4396 error = EINVAL;
4397 goto out;
4398 }
4399 #ifdef MAC
4400 error = mac_vnode_check_revoke(td->td_ucred, vp);
4401 if (error != 0)
4402 goto out;
4403 #endif
4404 error = VOP_GETATTR(vp, &vattr, td->td_ucred);
4405 if (error != 0)
4406 goto out;
4407 if (td->td_ucred->cr_uid != vattr.va_uid) {
4408 error = priv_check(td, PRIV_VFS_ADMIN);
4409 if (error != 0)
4410 goto out;
4411 }
4412 if (devfs_usecount(vp) > 0)
4413 VOP_REVOKE(vp, REVOKEALL);
4414 out:
4415 vput(vp);
4416 return (error);
4417 }
4418
4419 /*
4420 * This variant of getvnode() allows O_PATH files. Caller should
4421 * ensure that returned file and vnode are only used for compatible
4422 * semantics.
4423 */
4424 int
getvnode_path(struct thread * td,int fd,const cap_rights_t * rightsp,uint8_t * flagsp,struct file ** fpp)4425 getvnode_path(struct thread *td, int fd, const cap_rights_t *rightsp,
4426 uint8_t *flagsp, struct file **fpp)
4427 {
4428 struct file *fp;
4429 int error;
4430
4431 error = fget_unlocked_flags(td, fd, rightsp, flagsp, &fp);
4432 if (error != 0)
4433 return (error);
4434
4435 /*
4436 * The file could be not of the vnode type, or it may be not
4437 * yet fully initialized, in which case the f_vnode pointer
4438 * may be set, but f_ops is still badfileops. E.g.,
4439 * devfs_open() transiently create such situation to
4440 * facilitate csw d_fdopen().
4441 *
4442 * Dupfdopen() handling in kern_openat() installs the
4443 * half-baked file into the process descriptor table, allowing
4444 * other thread to dereference it. Guard against the race by
4445 * checking f_ops.
4446 */
4447 if (__predict_false(fp->f_vnode == NULL || fp->f_ops == &badfileops)) {
4448 fdrop(fp, td);
4449 *fpp = NULL;
4450 return (EINVAL);
4451 }
4452
4453 *fpp = fp;
4454 return (0);
4455 }
4456
4457 /*
4458 * Convert a user file descriptor to a kernel file entry and check
4459 * that, if it is a capability, the correct rights are present.
4460 * A reference on the file entry is held upon returning.
4461 */
4462 int
getvnode(struct thread * td,int fd,const cap_rights_t * rightsp,struct file ** fpp)4463 getvnode(struct thread *td, int fd, const cap_rights_t *rightsp,
4464 struct file **fpp)
4465 {
4466 int error;
4467
4468 error = getvnode_path(td, fd, rightsp, NULL, fpp);
4469 if (__predict_false(error != 0))
4470 return (error);
4471
4472 /*
4473 * Filter out O_PATH file descriptors, most getvnode() callers
4474 * do not call fo_ methods.
4475 */
4476 if (__predict_false((*fpp)->f_ops == &path_fileops)) {
4477 fdrop(*fpp, td);
4478 *fpp = NULL;
4479 error = EBADF;
4480 }
4481
4482 return (error);
4483 }
4484
4485 /*
4486 * Get an (NFS) file handle.
4487 */
4488 #ifndef _SYS_SYSPROTO_H_
4489 struct lgetfh_args {
4490 char *fname;
4491 fhandle_t *fhp;
4492 };
4493 #endif
4494 int
sys_lgetfh(struct thread * td,struct lgetfh_args * uap)4495 sys_lgetfh(struct thread *td, struct lgetfh_args *uap)
4496 {
4497
4498 return (kern_getfhat(td, AT_SYMLINK_NOFOLLOW, AT_FDCWD, uap->fname,
4499 UIO_USERSPACE, uap->fhp, UIO_USERSPACE));
4500 }
4501
4502 #ifndef _SYS_SYSPROTO_H_
4503 struct getfh_args {
4504 char *fname;
4505 fhandle_t *fhp;
4506 };
4507 #endif
4508 int
sys_getfh(struct thread * td,struct getfh_args * uap)4509 sys_getfh(struct thread *td, struct getfh_args *uap)
4510 {
4511
4512 return (kern_getfhat(td, 0, AT_FDCWD, uap->fname, UIO_USERSPACE,
4513 uap->fhp, UIO_USERSPACE));
4514 }
4515
4516 /*
4517 * syscall for the rpc.lockd to use to translate an open descriptor into
4518 * a NFS file handle.
4519 *
4520 * warning: do not remove the priv_check() call or this becomes one giant
4521 * security hole.
4522 */
4523 #ifndef _SYS_SYSPROTO_H_
4524 struct getfhat_args {
4525 int fd;
4526 char *path;
4527 fhandle_t *fhp;
4528 int flags;
4529 };
4530 #endif
4531 int
sys_getfhat(struct thread * td,struct getfhat_args * uap)4532 sys_getfhat(struct thread *td, struct getfhat_args *uap)
4533 {
4534
4535 return (kern_getfhat(td, uap->flags, uap->fd, uap->path, UIO_USERSPACE,
4536 uap->fhp, UIO_USERSPACE));
4537 }
4538
4539 int
kern_getfhat(struct thread * td,int flags,int fd,const char * path,enum uio_seg pathseg,fhandle_t * fhp,enum uio_seg fhseg)4540 kern_getfhat(struct thread *td, int flags, int fd, const char *path,
4541 enum uio_seg pathseg, fhandle_t *fhp, enum uio_seg fhseg)
4542 {
4543 struct nameidata nd;
4544 fhandle_t fh;
4545 struct vnode *vp;
4546 int error;
4547
4548 if ((flags & ~(AT_SYMLINK_NOFOLLOW | AT_RESOLVE_BENEATH)) != 0)
4549 return (EINVAL);
4550 error = priv_check(td, PRIV_VFS_GETFH);
4551 if (error != 0)
4552 return (error);
4553 NDINIT_AT(&nd, LOOKUP, at2cnpflags(flags, AT_SYMLINK_NOFOLLOW |
4554 AT_RESOLVE_BENEATH) | LOCKLEAF | AUDITVNODE1, pathseg, path,
4555 fd);
4556 error = namei(&nd);
4557 if (error != 0)
4558 return (error);
4559 NDFREE_PNBUF(&nd);
4560 vp = nd.ni_vp;
4561 bzero(&fh, sizeof(fh));
4562 fh.fh_fsid = vp->v_mount->mnt_stat.f_fsid;
4563 error = VOP_VPTOFH(vp, &fh.fh_fid);
4564 vput(vp);
4565 if (error == 0) {
4566 if (fhseg == UIO_USERSPACE)
4567 error = copyout(&fh, fhp, sizeof (fh));
4568 else
4569 memcpy(fhp, &fh, sizeof(fh));
4570 }
4571 return (error);
4572 }
4573
4574 #ifndef _SYS_SYSPROTO_H_
4575 struct fhlink_args {
4576 fhandle_t *fhp;
4577 const char *to;
4578 };
4579 #endif
4580 int
sys_fhlink(struct thread * td,struct fhlink_args * uap)4581 sys_fhlink(struct thread *td, struct fhlink_args *uap)
4582 {
4583
4584 return (kern_fhlinkat(td, AT_FDCWD, uap->to, UIO_USERSPACE, uap->fhp));
4585 }
4586
4587 #ifndef _SYS_SYSPROTO_H_
4588 struct fhlinkat_args {
4589 fhandle_t *fhp;
4590 int tofd;
4591 const char *to;
4592 };
4593 #endif
4594 int
sys_fhlinkat(struct thread * td,struct fhlinkat_args * uap)4595 sys_fhlinkat(struct thread *td, struct fhlinkat_args *uap)
4596 {
4597
4598 return (kern_fhlinkat(td, uap->tofd, uap->to, UIO_USERSPACE, uap->fhp));
4599 }
4600
4601 static int
kern_fhlinkat(struct thread * td,int fd,const char * path,enum uio_seg pathseg,fhandle_t * fhp)4602 kern_fhlinkat(struct thread *td, int fd, const char *path,
4603 enum uio_seg pathseg, fhandle_t *fhp)
4604 {
4605 fhandle_t fh;
4606 struct mount *mp;
4607 struct vnode *vp;
4608 int error;
4609
4610 error = priv_check(td, PRIV_VFS_GETFH);
4611 if (error != 0)
4612 return (error);
4613 error = copyin(fhp, &fh, sizeof(fh));
4614 if (error != 0)
4615 return (error);
4616 do {
4617 bwillwrite();
4618 if ((mp = vfs_busyfs(&fh.fh_fsid)) == NULL)
4619 return (ESTALE);
4620 error = VFS_FHTOVP(mp, &fh.fh_fid, LK_SHARED, &vp);
4621 vfs_unbusy(mp);
4622 if (error != 0)
4623 return (error);
4624 VOP_UNLOCK(vp);
4625 error = kern_linkat_vp(td, vp, fd, path, pathseg);
4626 } while (error == EAGAIN || error == ERELOOKUP);
4627 return (error);
4628 }
4629
4630 #ifndef _SYS_SYSPROTO_H_
4631 struct fhreadlink_args {
4632 fhandle_t *fhp;
4633 char *buf;
4634 size_t bufsize;
4635 };
4636 #endif
4637 int
sys_fhreadlink(struct thread * td,struct fhreadlink_args * uap)4638 sys_fhreadlink(struct thread *td, struct fhreadlink_args *uap)
4639 {
4640 fhandle_t fh;
4641 struct mount *mp;
4642 struct vnode *vp;
4643 int error;
4644
4645 error = priv_check(td, PRIV_VFS_GETFH);
4646 if (error != 0)
4647 return (error);
4648 if (uap->bufsize > IOSIZE_MAX)
4649 return (EINVAL);
4650 error = copyin(uap->fhp, &fh, sizeof(fh));
4651 if (error != 0)
4652 return (error);
4653 if ((mp = vfs_busyfs(&fh.fh_fsid)) == NULL)
4654 return (ESTALE);
4655 error = VFS_FHTOVP(mp, &fh.fh_fid, LK_SHARED, &vp);
4656 vfs_unbusy(mp);
4657 if (error != 0)
4658 return (error);
4659 error = kern_readlink_vp(vp, uap->buf, UIO_USERSPACE, uap->bufsize, td);
4660 vput(vp);
4661 return (error);
4662 }
4663
4664 /*
4665 * syscall for the rpc.lockd to use to translate a NFS file handle into an
4666 * open descriptor.
4667 *
4668 * warning: do not remove the priv_check() call or this becomes one giant
4669 * security hole.
4670 */
4671 #ifndef _SYS_SYSPROTO_H_
4672 struct fhopen_args {
4673 const struct fhandle *u_fhp;
4674 int flags;
4675 };
4676 #endif
4677 int
sys_fhopen(struct thread * td,struct fhopen_args * uap)4678 sys_fhopen(struct thread *td, struct fhopen_args *uap)
4679 {
4680 return (kern_fhopen(td, uap->u_fhp, uap->flags));
4681 }
4682
4683 int
kern_fhopen(struct thread * td,const struct fhandle * u_fhp,int flags)4684 kern_fhopen(struct thread *td, const struct fhandle *u_fhp, int flags)
4685 {
4686 struct mount *mp;
4687 struct vnode *vp;
4688 struct fhandle fhp;
4689 struct file *fp;
4690 int error, indx;
4691 bool named_attr;
4692
4693 error = priv_check(td, PRIV_VFS_FHOPEN);
4694 if (error != 0)
4695 return (error);
4696
4697 indx = -1;
4698 if ((flags & O_CREAT) != 0)
4699 return (EINVAL);
4700 error = openflags(&flags);
4701 if (error != 0)
4702 return (error);
4703 error = copyin(u_fhp, &fhp, sizeof(fhp));
4704 if (error != 0)
4705 return (error);
4706 /* find the mount point */
4707 mp = vfs_busyfs(&fhp.fh_fsid);
4708 if (mp == NULL)
4709 return (ESTALE);
4710 /* now give me my vnode, it gets returned to me locked */
4711 error = VFS_FHTOVP(mp, &fhp.fh_fid, LK_EXCLUSIVE, &vp);
4712 vfs_unbusy(mp);
4713 if (error != 0)
4714 return (error);
4715
4716 /*
4717 * Check to see if the file handle refers to a named attribute
4718 * directory or attribute. If it does, the O_NAMEDATTR flag
4719 * must have been specified.
4720 */
4721 named_attr = (vn_irflag_read(vp) &
4722 (VIRF_NAMEDDIR | VIRF_NAMEDATTR)) != 0;
4723 if ((named_attr && (flags & O_NAMEDATTR) == 0) ||
4724 (!named_attr && (flags & O_NAMEDATTR) != 0)) {
4725 vput(vp);
4726 return (ENOATTR);
4727 }
4728
4729 error = falloc_noinstall(td, &fp);
4730 if (error != 0) {
4731 vput(vp);
4732 return (error);
4733 }
4734 /* Set the flags early so the finit in devfs can pick them up. */
4735 fp->f_flag = flags & FMASK;
4736
4737 #ifdef INVARIANTS
4738 td->td_dupfd = -1;
4739 #endif
4740 error = vn_open_vnode(vp, flags, td->td_ucred, td, fp);
4741 if (error != 0) {
4742 KASSERT(fp->f_ops == &badfileops,
4743 ("VOP_OPEN in fhopen() set f_ops"));
4744 KASSERT(td->td_dupfd < 0,
4745 ("fhopen() encountered fdopen()"));
4746
4747 vput(vp);
4748 goto bad;
4749 }
4750 #ifdef INVARIANTS
4751 td->td_dupfd = 0;
4752 #endif
4753 finit_open(fp, vp, flags);
4754 VOP_UNLOCK(vp);
4755 if ((flags & O_TRUNC) != 0) {
4756 error = fo_truncate(fp, 0, td->td_ucred, td);
4757 if (error != 0)
4758 goto bad;
4759 }
4760
4761 error = finstall(td, fp, &indx, flags, NULL);
4762 bad:
4763 fdrop(fp, td);
4764 td->td_retval[0] = indx;
4765 return (error);
4766 }
4767
4768 /*
4769 * Stat an (NFS) file handle.
4770 */
4771 #ifndef _SYS_SYSPROTO_H_
4772 struct fhstat_args {
4773 struct fhandle *u_fhp;
4774 struct stat *sb;
4775 };
4776 #endif
4777 int
sys_fhstat(struct thread * td,struct fhstat_args * uap)4778 sys_fhstat(struct thread *td, struct fhstat_args *uap)
4779 {
4780 struct stat sb;
4781 struct fhandle fh;
4782 int error;
4783
4784 error = copyin(uap->u_fhp, &fh, sizeof(fh));
4785 if (error != 0)
4786 return (error);
4787 error = kern_fhstat(td, fh, &sb);
4788 if (error == 0)
4789 error = copyout(&sb, uap->sb, sizeof(sb));
4790 return (error);
4791 }
4792
4793 int
kern_fhstat(struct thread * td,struct fhandle fh,struct stat * sb)4794 kern_fhstat(struct thread *td, struct fhandle fh, struct stat *sb)
4795 {
4796 struct mount *mp;
4797 struct vnode *vp;
4798 int error;
4799
4800 error = priv_check(td, PRIV_VFS_FHSTAT);
4801 if (error != 0)
4802 return (error);
4803 if ((mp = vfs_busyfs(&fh.fh_fsid)) == NULL)
4804 return (ESTALE);
4805 error = VFS_FHTOVP(mp, &fh.fh_fid, LK_EXCLUSIVE, &vp);
4806 vfs_unbusy(mp);
4807 if (error != 0)
4808 return (error);
4809 error = VOP_STAT(vp, sb, td->td_ucred, NOCRED);
4810 vput(vp);
4811 return (error);
4812 }
4813
4814 /*
4815 * Implement fstatfs() for (NFS) file handles.
4816 */
4817 #ifndef _SYS_SYSPROTO_H_
4818 struct fhstatfs_args {
4819 struct fhandle *u_fhp;
4820 struct statfs *buf;
4821 };
4822 #endif
4823 int
sys_fhstatfs(struct thread * td,struct fhstatfs_args * uap)4824 sys_fhstatfs(struct thread *td, struct fhstatfs_args *uap)
4825 {
4826 struct statfs *sfp;
4827 fhandle_t fh;
4828 int error;
4829
4830 error = copyin(uap->u_fhp, &fh, sizeof(fhandle_t));
4831 if (error != 0)
4832 return (error);
4833 sfp = malloc(sizeof(struct statfs), M_STATFS, M_WAITOK);
4834 error = kern_fhstatfs(td, fh, sfp);
4835 if (error == 0)
4836 error = copyout(sfp, uap->buf, sizeof(*sfp));
4837 free(sfp, M_STATFS);
4838 return (error);
4839 }
4840
4841 int
kern_fhstatfs(struct thread * td,fhandle_t fh,struct statfs * buf)4842 kern_fhstatfs(struct thread *td, fhandle_t fh, struct statfs *buf)
4843 {
4844 struct mount *mp;
4845 struct vnode *vp;
4846 int error;
4847
4848 error = priv_check(td, PRIV_VFS_FHSTATFS);
4849 if (error != 0)
4850 return (error);
4851 if ((mp = vfs_busyfs(&fh.fh_fsid)) == NULL)
4852 return (ESTALE);
4853 error = VFS_FHTOVP(mp, &fh.fh_fid, LK_EXCLUSIVE, &vp);
4854 if (error != 0) {
4855 vfs_unbusy(mp);
4856 return (error);
4857 }
4858 vput(vp);
4859 error = prison_canseemount(td->td_ucred, mp);
4860 if (error != 0)
4861 goto out;
4862 #ifdef MAC
4863 error = mac_mount_check_stat(td->td_ucred, mp);
4864 if (error != 0)
4865 goto out;
4866 #endif
4867 error = VFS_STATFS(mp, buf);
4868 out:
4869 vfs_unbusy(mp);
4870 return (error);
4871 }
4872
4873 /*
4874 * Unlike madvise(2), we do not make a best effort to remember every
4875 * possible caching hint. Instead, we remember the last setting with
4876 * the exception that we will allow POSIX_FADV_NORMAL to adjust the
4877 * region of any current setting.
4878 */
4879 int
kern_posix_fadvise(struct thread * td,int fd,off_t offset,off_t len,int advice)4880 kern_posix_fadvise(struct thread *td, int fd, off_t offset, off_t len,
4881 int advice)
4882 {
4883 struct fadvise_info *fa, *new;
4884 struct file *fp;
4885 struct vnode *vp;
4886 off_t end;
4887 int error;
4888
4889 if (offset < 0 || len < 0 || offset > OFF_MAX - len)
4890 return (EINVAL);
4891 AUDIT_ARG_VALUE(advice);
4892 switch (advice) {
4893 case POSIX_FADV_SEQUENTIAL:
4894 case POSIX_FADV_RANDOM:
4895 case POSIX_FADV_NOREUSE:
4896 new = malloc(sizeof(*fa), M_FADVISE, M_WAITOK);
4897 break;
4898 case POSIX_FADV_NORMAL:
4899 case POSIX_FADV_WILLNEED:
4900 case POSIX_FADV_DONTNEED:
4901 new = NULL;
4902 break;
4903 default:
4904 return (EINVAL);
4905 }
4906 /* XXX: CAP_POSIX_FADVISE? */
4907 AUDIT_ARG_FD(fd);
4908 error = fget(td, fd, &cap_no_rights, &fp);
4909 if (error != 0)
4910 goto out;
4911 AUDIT_ARG_FILE(td->td_proc, fp);
4912 if ((fp->f_ops->fo_flags & DFLAG_SEEKABLE) == 0) {
4913 error = ESPIPE;
4914 goto out;
4915 }
4916 if (fp->f_type != DTYPE_VNODE) {
4917 error = ENODEV;
4918 goto out;
4919 }
4920 vp = fp->f_vnode;
4921 if (vp->v_type != VREG) {
4922 error = ENODEV;
4923 goto out;
4924 }
4925 if (len == 0)
4926 end = OFF_MAX;
4927 else
4928 end = offset + len - 1;
4929 switch (advice) {
4930 case POSIX_FADV_SEQUENTIAL:
4931 case POSIX_FADV_RANDOM:
4932 case POSIX_FADV_NOREUSE:
4933 /*
4934 * Try to merge any existing non-standard region with
4935 * this new region if possible, otherwise create a new
4936 * non-standard region for this request.
4937 */
4938 mtx_pool_lock(mtxpool_sleep, fp);
4939 fa = fp->f_advice;
4940 if (fa != NULL && fa->fa_advice == advice &&
4941 ((fa->fa_start <= end && fa->fa_end >= offset) ||
4942 (end != OFF_MAX && fa->fa_start == end + 1) ||
4943 (fa->fa_end != OFF_MAX && fa->fa_end + 1 == offset))) {
4944 if (offset < fa->fa_start)
4945 fa->fa_start = offset;
4946 if (end > fa->fa_end)
4947 fa->fa_end = end;
4948 } else {
4949 new->fa_advice = advice;
4950 new->fa_start = offset;
4951 new->fa_end = end;
4952 fp->f_advice = new;
4953 new = fa;
4954 }
4955 mtx_pool_unlock(mtxpool_sleep, fp);
4956 break;
4957 case POSIX_FADV_NORMAL:
4958 /*
4959 * If a the "normal" region overlaps with an existing
4960 * non-standard region, trim or remove the
4961 * non-standard region.
4962 */
4963 mtx_pool_lock(mtxpool_sleep, fp);
4964 fa = fp->f_advice;
4965 if (fa != NULL) {
4966 if (offset <= fa->fa_start && end >= fa->fa_end) {
4967 new = fa;
4968 fp->f_advice = NULL;
4969 } else if (offset <= fa->fa_start &&
4970 end >= fa->fa_start)
4971 fa->fa_start = end + 1;
4972 else if (offset <= fa->fa_end && end >= fa->fa_end)
4973 fa->fa_end = offset - 1;
4974 else if (offset >= fa->fa_start && end <= fa->fa_end) {
4975 /*
4976 * If the "normal" region is a middle
4977 * portion of the existing
4978 * non-standard region, just remove
4979 * the whole thing rather than picking
4980 * one side or the other to
4981 * preserve.
4982 */
4983 new = fa;
4984 fp->f_advice = NULL;
4985 }
4986 }
4987 mtx_pool_unlock(mtxpool_sleep, fp);
4988 break;
4989 case POSIX_FADV_WILLNEED:
4990 case POSIX_FADV_DONTNEED:
4991 error = VOP_ADVISE(vp, offset, end, advice);
4992 break;
4993 }
4994 out:
4995 if (fp != NULL)
4996 fdrop(fp, td);
4997 free(new, M_FADVISE);
4998 return (error);
4999 }
5000
5001 int
sys_posix_fadvise(struct thread * td,struct posix_fadvise_args * uap)5002 sys_posix_fadvise(struct thread *td, struct posix_fadvise_args *uap)
5003 {
5004 int error;
5005
5006 error = kern_posix_fadvise(td, uap->fd, uap->offset, uap->len,
5007 uap->advice);
5008 return (kern_posix_error(td, error));
5009 }
5010
5011 int
kern_copy_file_range(struct thread * td,int infd,off_t * inoffp,int outfd,off_t * outoffp,size_t len,unsigned int flags)5012 kern_copy_file_range(struct thread *td, int infd, off_t *inoffp, int outfd,
5013 off_t *outoffp, size_t len, unsigned int flags)
5014 {
5015 struct file *infp, *infp1, *outfp, *outfp1;
5016 struct vnode *invp, *outvp;
5017 int error;
5018 size_t retlen;
5019 void *rl_rcookie, *rl_wcookie;
5020 off_t inoff, outoff, savinoff, savoutoff;
5021 bool foffsets_locked;
5022
5023 infp = outfp = NULL;
5024 rl_rcookie = rl_wcookie = NULL;
5025 foffsets_locked = false;
5026 error = 0;
5027 retlen = 0;
5028
5029 if (flags != 0) {
5030 error = EINVAL;
5031 goto out;
5032 }
5033 if (len > SSIZE_MAX)
5034 /*
5035 * Although the len argument is size_t, the return argument
5036 * is ssize_t (which is signed). Therefore a size that won't
5037 * fit in ssize_t can't be returned.
5038 */
5039 len = SSIZE_MAX;
5040
5041 /* Get the file structures for the file descriptors. */
5042 error = fget_read(td, infd,
5043 inoffp != NULL ? &cap_pread_rights : &cap_read_rights, &infp);
5044 if (error != 0)
5045 goto out;
5046 if (infp->f_ops == &badfileops) {
5047 error = EBADF;
5048 goto out;
5049 }
5050 if (infp->f_vnode == NULL) {
5051 error = EINVAL;
5052 goto out;
5053 }
5054 error = fget_write(td, outfd,
5055 outoffp != NULL ? &cap_pwrite_rights : &cap_write_rights, &outfp);
5056 if (error != 0)
5057 goto out;
5058 if (outfp->f_ops == &badfileops) {
5059 error = EBADF;
5060 goto out;
5061 }
5062 if (outfp->f_vnode == NULL) {
5063 error = EINVAL;
5064 goto out;
5065 }
5066
5067 /*
5068 * Figure out which file offsets we're reading from and writing to.
5069 * If the offsets come from the file descriptions, we need to lock them,
5070 * and locking both offsets requires a loop to avoid deadlocks.
5071 */
5072 infp1 = outfp1 = NULL;
5073 if (inoffp != NULL)
5074 inoff = *inoffp;
5075 else
5076 infp1 = infp;
5077 if (outoffp != NULL)
5078 outoff = *outoffp;
5079 else
5080 outfp1 = outfp;
5081 if (infp1 != NULL || outfp1 != NULL) {
5082 if (infp1 == outfp1) {
5083 /*
5084 * Overlapping ranges are not allowed. A more thorough
5085 * check appears below, but we must not lock the same
5086 * offset twice.
5087 */
5088 error = EINVAL;
5089 goto out;
5090 }
5091 foffset_lock_pair(infp1, &inoff, outfp1, &outoff, 0);
5092 foffsets_locked = true;
5093 }
5094 savinoff = inoff;
5095 savoutoff = outoff;
5096
5097 invp = infp->f_vnode;
5098 outvp = outfp->f_vnode;
5099 /* Sanity check the f_flag bits. */
5100 if ((outfp->f_flag & (FWRITE | FAPPEND)) != FWRITE ||
5101 (infp->f_flag & FREAD) == 0) {
5102 error = EBADF;
5103 goto out;
5104 }
5105
5106 /* If len == 0, just return 0. */
5107 if (len == 0)
5108 goto out;
5109
5110 /*
5111 * Make sure that the ranges we check and lock below are valid. Note
5112 * that len is clamped to SSIZE_MAX above.
5113 */
5114 if (inoff < 0 || outoff < 0) {
5115 error = EINVAL;
5116 goto out;
5117 }
5118
5119 /*
5120 * If infp and outfp refer to the same file, the byte ranges cannot
5121 * overlap.
5122 */
5123 if (invp == outvp) {
5124 if ((inoff <= outoff && inoff + len > outoff) ||
5125 (inoff > outoff && outoff + len > inoff)) {
5126 error = EINVAL;
5127 goto out;
5128 }
5129 rangelock_may_recurse(&invp->v_rl);
5130 }
5131
5132 /* Range lock the byte ranges for both invp and outvp. */
5133 for (;;) {
5134 rl_wcookie = vn_rangelock_wlock(outvp, outoff, outoff + len);
5135 rl_rcookie = vn_rangelock_tryrlock(invp, inoff, inoff + len);
5136 if (rl_rcookie != NULL)
5137 break;
5138 vn_rangelock_unlock(outvp, rl_wcookie);
5139 rl_rcookie = vn_rangelock_rlock(invp, inoff, inoff + len);
5140 vn_rangelock_unlock(invp, rl_rcookie);
5141 }
5142
5143 retlen = len;
5144 error = vn_copy_file_range(invp, &inoff, outvp, &outoff, &retlen,
5145 flags, infp->f_cred, outfp->f_cred, td);
5146 out:
5147 if (rl_rcookie != NULL)
5148 vn_rangelock_unlock(invp, rl_rcookie);
5149 if (rl_wcookie != NULL)
5150 vn_rangelock_unlock(outvp, rl_wcookie);
5151 if (foffsets_locked) {
5152 if (error == EINTR || error == ERESTART) {
5153 inoff = savinoff;
5154 outoff = savoutoff;
5155 }
5156 if (inoffp == NULL)
5157 foffset_unlock(infp, inoff, 0);
5158 else
5159 *inoffp = inoff;
5160 if (outoffp == NULL)
5161 foffset_unlock(outfp, outoff, 0);
5162 else
5163 *outoffp = outoff;
5164 }
5165 if (outfp != NULL)
5166 fdrop(outfp, td);
5167 if (infp != NULL)
5168 fdrop(infp, td);
5169 td->td_retval[0] = retlen;
5170 return (error);
5171 }
5172
5173 int
sys_copy_file_range(struct thread * td,struct copy_file_range_args * uap)5174 sys_copy_file_range(struct thread *td, struct copy_file_range_args *uap)
5175 {
5176 off_t inoff, outoff, *inoffp, *outoffp;
5177 int error;
5178
5179 inoffp = outoffp = NULL;
5180 if (uap->inoffp != NULL) {
5181 error = copyin(uap->inoffp, &inoff, sizeof(off_t));
5182 if (error != 0)
5183 return (error);
5184 inoffp = &inoff;
5185 }
5186 if (uap->outoffp != NULL) {
5187 error = copyin(uap->outoffp, &outoff, sizeof(off_t));
5188 if (error != 0)
5189 return (error);
5190 outoffp = &outoff;
5191 }
5192 error = kern_copy_file_range(td, uap->infd, inoffp, uap->outfd,
5193 outoffp, uap->len, uap->flags);
5194 if (error == 0 && uap->inoffp != NULL)
5195 error = copyout(inoffp, uap->inoffp, sizeof(off_t));
5196 if (error == 0 && uap->outoffp != NULL)
5197 error = copyout(outoffp, uap->outoffp, sizeof(off_t));
5198 return (error);
5199 }
5200