2012-11-30 17:26:37 +04:00
|
|
|
/* $NetBSD: vfs_syscalls.c,v 1.462 2012/11/30 13:26:37 njoly Exp $ */
|
2008-01-30 14:46:59 +03:00
|
|
|
|
|
|
|
/*-
|
2009-02-23 23:33:30 +03:00
|
|
|
* Copyright (c) 2008, 2009 The NetBSD Foundation, Inc.
|
2008-01-30 14:46:59 +03:00
|
|
|
* All rights reserved.
|
|
|
|
*
|
2009-02-23 23:33:30 +03:00
|
|
|
* This code is derived from software contributed to The NetBSD Foundation
|
|
|
|
* by Andrew Doran.
|
|
|
|
*
|
2008-01-30 14:46:59 +03:00
|
|
|
* Redistribution and use in source and binary forms, with or without
|
|
|
|
* modification, are permitted provided that the following conditions
|
|
|
|
* are met:
|
|
|
|
* 1. Redistributions of source code must retain the above copyright
|
|
|
|
* notice, this list of conditions and the following disclaimer.
|
|
|
|
* 2. Redistributions in binary form must reproduce the above copyright
|
|
|
|
* notice, this list of conditions and the following disclaimer in the
|
|
|
|
* documentation and/or other materials provided with the distribution.
|
|
|
|
*
|
|
|
|
* THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
|
|
|
|
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
|
|
|
|
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
|
|
|
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
|
|
|
|
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
|
|
|
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
|
|
|
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
|
|
|
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
|
|
|
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
|
|
|
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
|
|
|
* POSSIBILITY OF SUCH DAMAGE.
|
|
|
|
*/
|
1994-06-29 10:29:24 +04:00
|
|
|
|
|
|
|
/*
|
|
|
|
* Copyright (c) 1989, 1993
|
|
|
|
* The Regents of the University of California. All rights reserved.
|
|
|
|
* (c) UNIX System Laboratories, Inc.
|
|
|
|
* All or some portions of this file are derived from material licensed
|
|
|
|
* to the University of California by American Telephone and Telegraph
|
|
|
|
* Co. or Unix System Laboratories, Inc. and are reproduced herein with
|
|
|
|
* the permission of UNIX System Laboratories, Inc.
|
|
|
|
*
|
|
|
|
* Redistribution and use in source and binary forms, with or without
|
|
|
|
* modification, are permitted provided that the following conditions
|
|
|
|
* are met:
|
|
|
|
* 1. Redistributions of source code must retain the above copyright
|
|
|
|
* notice, this list of conditions and the following disclaimer.
|
|
|
|
* 2. Redistributions in binary form must reproduce the above copyright
|
|
|
|
* notice, this list of conditions and the following disclaimer in the
|
|
|
|
* documentation and/or other materials provided with the distribution.
|
2003-08-07 20:26:28 +04:00
|
|
|
* 3. Neither the name of the University nor the names of its contributors
|
1994-06-29 10:29:24 +04:00
|
|
|
* may be used to endorse or promote products derived from this software
|
|
|
|
* without specific prior written permission.
|
|
|
|
*
|
|
|
|
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
|
|
|
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
|
|
|
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
|
|
|
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
|
|
|
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
|
|
|
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
|
|
|
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
|
|
|
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
|
|
|
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
|
|
|
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
|
|
|
* SUCH DAMAGE.
|
|
|
|
*
|
1998-03-01 05:20:01 +03:00
|
|
|
* @(#)vfs_syscalls.c 8.42 (Berkeley) 7/31/95
|
1994-06-29 10:29:24 +04:00
|
|
|
*/
|
|
|
|
|
2011-04-02 08:28:56 +04:00
|
|
|
/*
|
|
|
|
* Virtual File System System Calls
|
|
|
|
*/
|
|
|
|
|
2001-11-12 18:25:01 +03:00
|
|
|
#include <sys/cdefs.h>
|
2012-11-30 17:26:37 +04:00
|
|
|
__KERNEL_RCSID(0, "$NetBSD: vfs_syscalls.c,v 1.462 2012/11/30 13:26:37 njoly Exp $");
|
2001-11-12 18:25:01 +03:00
|
|
|
|
2008-11-15 02:10:57 +03:00
|
|
|
#ifdef _KERNEL_OPT
|
2006-07-24 20:37:28 +04:00
|
|
|
#include "opt_fileassoc.h"
|
2006-07-26 13:33:57 +04:00
|
|
|
#include "veriexec.h"
|
2008-11-15 02:10:57 +03:00
|
|
|
#endif
|
1998-02-10 17:08:44 +03:00
|
|
|
|
1994-06-29 10:29:24 +04:00
|
|
|
#include <sys/param.h>
|
|
|
|
#include <sys/systm.h>
|
|
|
|
#include <sys/namei.h>
|
|
|
|
#include <sys/filedesc.h>
|
|
|
|
#include <sys/kernel.h>
|
|
|
|
#include <sys/file.h>
|
2011-08-08 16:08:52 +04:00
|
|
|
#include <sys/fcntl.h>
|
1994-06-29 10:29:24 +04:00
|
|
|
#include <sys/stat.h>
|
|
|
|
#include <sys/vnode.h>
|
|
|
|
#include <sys/mount.h>
|
|
|
|
#include <sys/proc.h>
|
|
|
|
#include <sys/uio.h>
|
2006-07-14 19:59:29 +04:00
|
|
|
#include <sys/kmem.h>
|
1994-06-29 10:29:24 +04:00
|
|
|
#include <sys/dirent.h>
|
2001-10-29 10:02:30 +03:00
|
|
|
#include <sys/sysctl.h>
|
1994-10-20 07:22:35 +03:00
|
|
|
#include <sys/syscallargs.h>
|
2007-03-10 19:50:01 +03:00
|
|
|
#include <sys/vfs_syscalls.h>
|
2012-02-01 09:34:38 +04:00
|
|
|
#include <sys/quota.h>
|
|
|
|
#include <sys/quotactl.h>
|
2003-09-02 16:31:35 +04:00
|
|
|
#include <sys/ktrace.h>
|
okay, since there was no way to divide this to two commits, here it goes..
introduce fileassoc(9), a kernel interface for associating meta-data with
files using in-kernel memory. this is very similar to what we had in
veriexec till now, only abstracted so it can be used more easily by more
consumers.
this also prompted the redesign of the interface, making it work on vnodes
and mounts and not directly on devices and inodes. internally, we still
use file-id but that's gonna change soon... the interface will remain
consistent.
as a result, veriexec went under some heavy changes to conform to the new
interface. since we no longer use device numbers to identify file-systems,
the veriexec sysctl stuff changed too: kern.veriexec.count.dev_N is now
kern.veriexec.tableN.* where 'N' is NOT the device number but rather a
way to distinguish several mounts.
also worth noting is the plugging of unmount/delete operations
wrt/fileassoc and veriexec.
tons of input from yamt@, wrstuden@, martin@, and christos@.
2006-07-14 22:41:40 +04:00
|
|
|
#ifdef FILEASSOC
|
|
|
|
#include <sys/fileassoc.h>
|
|
|
|
#endif /* FILEASSOC */
|
2011-06-17 18:23:50 +04:00
|
|
|
#include <sys/extattr.h>
|
2005-04-20 17:44:45 +04:00
|
|
|
#include <sys/verified_exec.h>
|
2006-05-15 01:15:11 +04:00
|
|
|
#include <sys/kauth.h>
|
2008-03-22 00:54:58 +03:00
|
|
|
#include <sys/atomic.h>
|
2008-05-20 21:25:49 +04:00
|
|
|
#include <sys/module.h>
|
2008-11-16 21:44:07 +03:00
|
|
|
#include <sys/buf.h>
|
1994-10-20 07:22:35 +03:00
|
|
|
|
1999-11-15 21:49:07 +03:00
|
|
|
#include <miscfs/genfs/genfs.h>
|
|
|
|
#include <miscfs/syncfs/syncfs.h>
|
2008-01-24 20:32:52 +03:00
|
|
|
#include <miscfs/specfs/specdev.h>
|
1999-11-15 21:49:07 +03:00
|
|
|
|
2005-09-26 01:57:40 +04:00
|
|
|
#include <nfs/rpcv2.h>
|
|
|
|
#include <nfs/nfsproto.h>
|
|
|
|
#include <nfs/nfs.h>
|
|
|
|
#include <nfs/nfs_var.h>
|
|
|
|
|
2005-12-11 15:16:03 +03:00
|
|
|
static int change_flags(struct vnode *, u_long, struct lwp *);
|
|
|
|
static int change_mode(struct vnode *, int, struct lwp *l);
|
|
|
|
static int change_owner(struct vnode *, uid_t, gid_t, struct lwp *, int);
|
Add most system calls for POSIX extended API set, part 2, with test cases:
faccessat(2), fchmodat(2), fchownat(2), fstatat(2), mkdirat(2), mkfifoat(2),
mknodat(2), linkat(2), readlinkat(2), symlinkat(2), renameat(2), unlinkat(2),
utimensat(2), openat(2).
Also implement O_SEARCH for openat(2)
Still missing:
- some flags for openat(2)
- fexecve(2) implementation
2012-11-18 21:41:51 +04:00
|
|
|
static int do_open(lwp_t *, struct vnode *, struct pathbuf *, int, int, int *);
|
|
|
|
static int do_sys_openat(lwp_t *, int, const char *, int, int, int *);
|
|
|
|
static int do_sys_mknodat(struct lwp *, int, const char *, mode_t,
|
|
|
|
dev_t, register_t *, enum uio_seg);
|
|
|
|
static int do_sys_mkdirat(struct lwp *l, int, const char *, mode_t,
|
|
|
|
enum uio_seg);
|
|
|
|
static int do_sys_mkfifoat(struct lwp *, int, const char *, mode_t);
|
|
|
|
static int do_sys_chmodat(struct lwp *, int, const char *, int, int);
|
|
|
|
static int do_sys_chownat(struct lwp *, int, const char *, uid_t, gid_t, int);
|
|
|
|
static int do_sys_utimensat(struct lwp *, int, struct vnode *,
|
|
|
|
const char *, int, const struct timespec *, enum uio_seg);
|
|
|
|
static int do_sys_accessat(struct lwp *, int, const char *, int ,int);
|
|
|
|
static int do_sys_statat(struct lwp *, int, const char *, unsigned int,
|
|
|
|
struct stat *);
|
|
|
|
static int do_sys_symlinkat(struct lwp *, const char *, int, const char *,
|
|
|
|
enum uio_seg);
|
|
|
|
static int do_sys_linkat(struct lwp *, int, const char *, int, const char *,
|
|
|
|
int, register_t *);
|
|
|
|
static int do_sys_renameat(struct lwp *l, int, const char *, int, const char *,
|
|
|
|
enum uio_seg, int);
|
|
|
|
static int do_sys_readlinkat(struct lwp *, int, const char *, char *,
|
|
|
|
size_t, register_t *);
|
|
|
|
static int do_sys_unlinkat(struct lwp *, int, const char *, int, enum uio_seg);
|
|
|
|
|
|
|
|
static int fd_nameiat(struct lwp *, int, struct nameidata *);
|
|
|
|
static int fd_nameiat_simple_user(struct lwp *, int, const char *,
|
|
|
|
namei_simple_flags_t, struct vnode **);
|
|
|
|
|
1996-02-04 05:17:43 +03:00
|
|
|
|
1997-10-06 13:19:11 +04:00
|
|
|
/*
|
|
|
|
* This table is used to maintain compatibility with 4.3BSD
|
2008-11-15 02:10:57 +03:00
|
|
|
* and NetBSD 0.9 mount syscalls - and possibly other systems.
|
|
|
|
* Note, the order is important!
|
1998-11-13 07:12:35 +03:00
|
|
|
*
|
2001-06-28 12:04:18 +04:00
|
|
|
* Do not modify this table. It should only contain filesystems
|
|
|
|
* supported by NetBSD 0.9 and 4.3BSD.
|
1997-10-06 13:19:11 +04:00
|
|
|
*/
|
2001-06-28 12:04:18 +04:00
|
|
|
const char * const mountcompatnames[] = {
|
1997-10-06 13:19:11 +04:00
|
|
|
NULL, /* 0 = MOUNT_NONE */
|
2001-06-28 12:04:18 +04:00
|
|
|
MOUNT_FFS, /* 1 = MOUNT_UFS */
|
1997-10-06 13:19:11 +04:00
|
|
|
MOUNT_NFS, /* 2 */
|
|
|
|
MOUNT_MFS, /* 3 */
|
|
|
|
MOUNT_MSDOS, /* 4 */
|
2001-06-28 12:04:18 +04:00
|
|
|
MOUNT_CD9660, /* 5 = MOUNT_ISOFS */
|
|
|
|
MOUNT_FDESC, /* 6 */
|
|
|
|
MOUNT_KERNFS, /* 7 */
|
|
|
|
NULL, /* 8 = MOUNT_DEVFS */
|
|
|
|
MOUNT_AFS, /* 9 */
|
1997-10-06 13:19:11 +04:00
|
|
|
};
|
2011-04-02 08:28:56 +04:00
|
|
|
|
|
|
|
const int nmountcompatnames = __arraycount(mountcompatnames);
|
1997-10-06 13:19:11 +04:00
|
|
|
|
Add most system calls for POSIX extended API set, part 2, with test cases:
faccessat(2), fchmodat(2), fchownat(2), fstatat(2), mkdirat(2), mkfifoat(2),
mknodat(2), linkat(2), readlinkat(2), symlinkat(2), renameat(2), unlinkat(2),
utimensat(2), openat(2).
Also implement O_SEARCH for openat(2)
Still missing:
- some flags for openat(2)
- fexecve(2) implementation
2012-11-18 21:41:51 +04:00
|
|
|
static int
|
|
|
|
fd_nameiat(struct lwp *l, int fdat, struct nameidata *ndp)
|
|
|
|
{
|
|
|
|
file_t *dfp;
|
|
|
|
int error;
|
|
|
|
|
|
|
|
if (fdat != AT_FDCWD) {
|
|
|
|
if ((error = fd_getvnode(fdat, &dfp)) != 0)
|
|
|
|
goto out;
|
|
|
|
|
|
|
|
if (!(dfp->f_flag & FSEARCH)) {
|
2012-11-30 17:26:37 +04:00
|
|
|
vn_lock(dfp->f_data, LK_EXCLUSIVE);
|
Add most system calls for POSIX extended API set, part 2, with test cases:
faccessat(2), fchmodat(2), fchownat(2), fstatat(2), mkdirat(2), mkfifoat(2),
mknodat(2), linkat(2), readlinkat(2), symlinkat(2), renameat(2), unlinkat(2),
utimensat(2), openat(2).
Also implement O_SEARCH for openat(2)
Still missing:
- some flags for openat(2)
- fexecve(2) implementation
2012-11-18 21:41:51 +04:00
|
|
|
error = VOP_ACCESS(dfp->f_data, VEXEC, l->l_cred);
|
2012-11-30 17:26:37 +04:00
|
|
|
VOP_UNLOCK(dfp->f_data);
|
Add most system calls for POSIX extended API set, part 2, with test cases:
faccessat(2), fchmodat(2), fchownat(2), fstatat(2), mkdirat(2), mkfifoat(2),
mknodat(2), linkat(2), readlinkat(2), symlinkat(2), renameat(2), unlinkat(2),
utimensat(2), openat(2).
Also implement O_SEARCH for openat(2)
Still missing:
- some flags for openat(2)
- fexecve(2) implementation
2012-11-18 21:41:51 +04:00
|
|
|
if (error)
|
|
|
|
goto cleanup;
|
|
|
|
}
|
|
|
|
|
|
|
|
NDAT(ndp, dfp->f_data);
|
|
|
|
}
|
|
|
|
|
|
|
|
error = namei(ndp);
|
|
|
|
|
|
|
|
cleanup:
|
|
|
|
if (fdat != AT_FDCWD)
|
|
|
|
fd_putfile(fdat);
|
|
|
|
out:
|
|
|
|
return error;
|
|
|
|
}
|
|
|
|
|
|
|
|
static int
|
|
|
|
fd_nameiat_simple_user(struct lwp *l, int fdat, const char *path,
|
|
|
|
namei_simple_flags_t sflags, struct vnode **vp_ret)
|
|
|
|
{
|
|
|
|
file_t *dfp;
|
|
|
|
struct vnode *dvp;
|
|
|
|
int error;
|
|
|
|
|
|
|
|
if (fdat != AT_FDCWD) {
|
|
|
|
if ((error = fd_getvnode(fdat, &dfp)) != 0)
|
|
|
|
goto out;
|
|
|
|
|
|
|
|
if (!(dfp->f_flag & FSEARCH)) {
|
2012-11-30 17:26:37 +04:00
|
|
|
vn_lock(dfp->f_data, LK_EXCLUSIVE);
|
Add most system calls for POSIX extended API set, part 2, with test cases:
faccessat(2), fchmodat(2), fchownat(2), fstatat(2), mkdirat(2), mkfifoat(2),
mknodat(2), linkat(2), readlinkat(2), symlinkat(2), renameat(2), unlinkat(2),
utimensat(2), openat(2).
Also implement O_SEARCH for openat(2)
Still missing:
- some flags for openat(2)
- fexecve(2) implementation
2012-11-18 21:41:51 +04:00
|
|
|
error = VOP_ACCESS(dfp->f_data, VEXEC, l->l_cred);
|
2012-11-30 17:26:37 +04:00
|
|
|
VOP_UNLOCK(dfp->f_data);
|
Add most system calls for POSIX extended API set, part 2, with test cases:
faccessat(2), fchmodat(2), fchownat(2), fstatat(2), mkdirat(2), mkfifoat(2),
mknodat(2), linkat(2), readlinkat(2), symlinkat(2), renameat(2), unlinkat(2),
utimensat(2), openat(2).
Also implement O_SEARCH for openat(2)
Still missing:
- some flags for openat(2)
- fexecve(2) implementation
2012-11-18 21:41:51 +04:00
|
|
|
if (error)
|
|
|
|
goto cleanup;
|
|
|
|
}
|
|
|
|
|
|
|
|
dvp = dfp->f_data;
|
|
|
|
} else {
|
|
|
|
dvp = NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
error = nameiat_simple_user(dvp, path, sflags, vp_ret);
|
|
|
|
|
|
|
|
cleanup:
|
|
|
|
if (fdat != AT_FDCWD)
|
|
|
|
fd_putfile(fdat);
|
|
|
|
out:
|
|
|
|
return error;
|
|
|
|
}
|
|
|
|
|
2011-04-10 19:45:33 +04:00
|
|
|
static int
|
|
|
|
open_setfp(struct lwp *l, file_t *fp, struct vnode *vp, int indx, int flags)
|
|
|
|
{
|
|
|
|
int error;
|
|
|
|
|
|
|
|
fp->f_flag = flags & FMASK;
|
|
|
|
fp->f_type = DTYPE_VNODE;
|
|
|
|
fp->f_ops = &vnops;
|
|
|
|
fp->f_data = vp;
|
|
|
|
|
|
|
|
if (flags & (O_EXLOCK | O_SHLOCK)) {
|
|
|
|
struct flock lf;
|
|
|
|
int type;
|
|
|
|
|
|
|
|
lf.l_whence = SEEK_SET;
|
|
|
|
lf.l_start = 0;
|
|
|
|
lf.l_len = 0;
|
|
|
|
if (flags & O_EXLOCK)
|
|
|
|
lf.l_type = F_WRLCK;
|
|
|
|
else
|
|
|
|
lf.l_type = F_RDLCK;
|
|
|
|
type = F_FLOCK;
|
|
|
|
if ((flags & FNONBLOCK) == 0)
|
|
|
|
type |= F_WAIT;
|
|
|
|
VOP_UNLOCK(vp);
|
|
|
|
error = VOP_ADVLOCK(vp, fp, F_SETLK, &lf, type);
|
|
|
|
if (error) {
|
|
|
|
(void) vn_close(vp, fp->f_flag, fp->f_cred);
|
|
|
|
fd_abort(l->l_proc, fp, indx);
|
|
|
|
return error;
|
|
|
|
}
|
|
|
|
vn_lock(vp, LK_EXCLUSIVE | LK_RETRY);
|
|
|
|
atomic_or_uint(&fp->f_flag, FHASLOCK);
|
|
|
|
}
|
|
|
|
if (flags & O_CLOEXEC)
|
|
|
|
fd_set_exclose(l, indx, true);
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2006-12-26 01:03:42 +03:00
|
|
|
static int
|
2006-12-24 15:43:17 +03:00
|
|
|
mount_update(struct lwp *l, struct vnode *vp, const char *path, int flags,
|
2007-08-01 01:14:15 +04:00
|
|
|
void *data, size_t *data_len)
|
1995-09-20 01:40:36 +04:00
|
|
|
{
|
1998-03-01 05:20:01 +03:00
|
|
|
struct mount *mp;
|
2006-12-24 15:43:17 +03:00
|
|
|
int error = 0, saved_flags;
|
1994-06-29 10:29:24 +04:00
|
|
|
|
2006-12-24 15:43:17 +03:00
|
|
|
mp = vp->v_mount;
|
|
|
|
saved_flags = mp->mnt_flag;
|
2005-04-06 17:49:31 +04:00
|
|
|
|
2007-10-11 00:42:20 +04:00
|
|
|
/* We can operate only on VV_ROOT nodes. */
|
|
|
|
if ((vp->v_vflag & VV_ROOT) == 0) {
|
|
|
|
error = EINVAL;
|
|
|
|
goto out;
|
|
|
|
}
|
2005-04-06 17:49:31 +04:00
|
|
|
|
1994-06-29 10:29:24 +04:00
|
|
|
/*
|
2006-12-24 15:43:17 +03:00
|
|
|
* We only allow the filesystem to be reloaded if it
|
2008-09-24 14:07:19 +04:00
|
|
|
* is currently mounted read-only. Additionally, we
|
|
|
|
* prevent read-write to read-only downgrades.
|
1994-06-29 10:29:24 +04:00
|
|
|
*/
|
2008-09-24 14:07:19 +04:00
|
|
|
if ((flags & (MNT_RELOAD | MNT_RDONLY)) != 0 &&
|
2011-01-13 10:25:50 +03:00
|
|
|
(mp->mnt_flag & MNT_RDONLY) == 0 &&
|
|
|
|
(mp->mnt_iflag & IMNT_CAN_RWTORO) == 0) {
|
2007-10-11 00:42:20 +04:00
|
|
|
error = EOPNOTSUPP; /* Needs translation */
|
|
|
|
goto out;
|
|
|
|
}
|
2007-01-02 13:47:28 +03:00
|
|
|
|
|
|
|
error = kauth_authorize_system(l->l_cred, KAUTH_SYSTEM_MOUNT,
|
|
|
|
KAUTH_REQ_SYSTEM_MOUNT_UPDATE, mp, KAUTH_ARG(flags), data);
|
|
|
|
if (error)
|
2007-10-11 00:42:20 +04:00
|
|
|
goto out;
|
2007-01-02 13:47:28 +03:00
|
|
|
|
PR kern/38141 lookup/vfs_busy acquire rwlock recursively
Simplify the mount locking. Remove all the crud to deal with recursion on
the mount lock, and crud to deal with unmount as another weirdo lock.
Hopefully this will once and for all fix the deadlocks with this. With this
commit there are two locks on each mount:
- krwlock_t mnt_unmounting. This is used to prevent unmount across critical
sections like getnewvnode(). It's only ever read locked with rw_tryenter(),
and is only ever write locked in dounmount(). A write hold can't be taken
on this lock if the current LWP could hold a vnode lock.
- kmutex_t mnt_updating. This is taken by threads updating the mount, for
example when going r/o -> r/w, and is only present to serialize updates.
In order to take this lock, a read hold must first be taken on
mnt_unmounting, and the two need to be held across the operation.
One effect of this change: previously if an unmount failed, we would make a
half hearted attempt to back out of it gracefully, but that was unlikely to
work in a lot of cases. Now while an unmount that will be aborted is in
progress, new file operations within the mount will fail instead of being
delayed. That is unlikely to be a problem though, because if the admin
requests unmount of a file system then s(he) has made a decision to deny
access to the resource.
2008-05-06 22:43:44 +04:00
|
|
|
if (vfs_busy(mp, NULL)) {
|
2007-10-11 00:42:20 +04:00
|
|
|
error = EPERM;
|
|
|
|
goto out;
|
|
|
|
}
|
2006-12-24 15:43:17 +03:00
|
|
|
|
PR kern/38141 lookup/vfs_busy acquire rwlock recursively
Simplify the mount locking. Remove all the crud to deal with recursion on
the mount lock, and crud to deal with unmount as another weirdo lock.
Hopefully this will once and for all fix the deadlocks with this. With this
commit there are two locks on each mount:
- krwlock_t mnt_unmounting. This is used to prevent unmount across critical
sections like getnewvnode(). It's only ever read locked with rw_tryenter(),
and is only ever write locked in dounmount(). A write hold can't be taken
on this lock if the current LWP could hold a vnode lock.
- kmutex_t mnt_updating. This is taken by threads updating the mount, for
example when going r/o -> r/w, and is only present to serialize updates.
In order to take this lock, a read hold must first be taken on
mnt_unmounting, and the two need to be held across the operation.
One effect of this change: previously if an unmount failed, we would make a
half hearted attempt to back out of it gracefully, but that was unlikely to
work in a lot of cases. Now while an unmount that will be aborted is in
progress, new file operations within the mount will fail instead of being
delayed. That is unlikely to be a problem though, because if the admin
requests unmount of a file system then s(he) has made a decision to deny
access to the resource.
2008-05-06 22:43:44 +04:00
|
|
|
mutex_enter(&mp->mnt_updating);
|
|
|
|
|
2006-12-26 15:39:01 +03:00
|
|
|
mp->mnt_flag &= ~MNT_OP_FLAGS;
|
2011-11-19 01:17:45 +04:00
|
|
|
mp->mnt_flag |= flags & MNT_OP_FLAGS;
|
2006-12-26 15:39:01 +03:00
|
|
|
|
2006-12-24 15:43:17 +03:00
|
|
|
/*
|
|
|
|
* Set the mount level flags.
|
|
|
|
*/
|
|
|
|
if (flags & MNT_RDONLY)
|
|
|
|
mp->mnt_flag |= MNT_RDONLY;
|
|
|
|
else if (mp->mnt_flag & MNT_RDONLY)
|
|
|
|
mp->mnt_iflag |= IMNT_WANTRDWR;
|
2011-11-19 01:17:45 +04:00
|
|
|
mp->mnt_flag &= ~MNT_BASIC_FLAGS;
|
|
|
|
mp->mnt_flag |= flags & MNT_BASIC_FLAGS;
|
2007-11-26 22:01:26 +03:00
|
|
|
error = VFS_MOUNT(mp, path, data, data_len);
|
2006-12-24 15:43:17 +03:00
|
|
|
|
2007-07-12 23:35:32 +04:00
|
|
|
if (error && data != NULL) {
|
2006-12-24 15:43:17 +03:00
|
|
|
int error2;
|
|
|
|
|
2008-11-15 02:10:57 +03:00
|
|
|
/*
|
|
|
|
* Update failed; let's try and see if it was an
|
2008-11-15 02:13:02 +03:00
|
|
|
* export request. For compat with 3.0 and earlier.
|
2008-11-15 02:10:57 +03:00
|
|
|
*/
|
2008-11-19 21:35:57 +03:00
|
|
|
error2 = vfs_hooks_reexport(mp, path, data);
|
2006-12-24 15:43:17 +03:00
|
|
|
|
2008-11-19 21:35:57 +03:00
|
|
|
/*
|
|
|
|
* Only update error code if the export request was
|
2006-12-24 15:43:17 +03:00
|
|
|
* understood but some problem occurred while
|
2008-11-19 21:35:57 +03:00
|
|
|
* processing it.
|
|
|
|
*/
|
2006-12-24 15:43:17 +03:00
|
|
|
if (error2 != EJUSTRETURN)
|
|
|
|
error = error2;
|
|
|
|
}
|
2008-11-19 21:35:57 +03:00
|
|
|
|
2006-12-24 15:43:17 +03:00
|
|
|
if (mp->mnt_iflag & IMNT_WANTRDWR)
|
|
|
|
mp->mnt_flag &= ~MNT_RDONLY;
|
|
|
|
if (error)
|
|
|
|
mp->mnt_flag = saved_flags;
|
2006-12-26 15:39:01 +03:00
|
|
|
mp->mnt_flag &= ~MNT_OP_FLAGS;
|
|
|
|
mp->mnt_iflag &= ~IMNT_WANTRDWR;
|
2006-12-24 15:43:17 +03:00
|
|
|
if ((mp->mnt_flag & (MNT_RDONLY | MNT_ASYNC)) == 0) {
|
|
|
|
if (mp->mnt_syncer == NULL)
|
|
|
|
error = vfs_allocate_syncvnode(mp);
|
1998-11-14 09:38:54 +03:00
|
|
|
} else {
|
2006-12-24 15:43:17 +03:00
|
|
|
if (mp->mnt_syncer != NULL)
|
|
|
|
vfs_deallocate_syncvnode(mp);
|
|
|
|
}
|
PR kern/38141 lookup/vfs_busy acquire rwlock recursively
Simplify the mount locking. Remove all the crud to deal with recursion on
the mount lock, and crud to deal with unmount as another weirdo lock.
Hopefully this will once and for all fix the deadlocks with this. With this
commit there are two locks on each mount:
- krwlock_t mnt_unmounting. This is used to prevent unmount across critical
sections like getnewvnode(). It's only ever read locked with rw_tryenter(),
and is only ever write locked in dounmount(). A write hold can't be taken
on this lock if the current LWP could hold a vnode lock.
- kmutex_t mnt_updating. This is taken by threads updating the mount, for
example when going r/o -> r/w, and is only present to serialize updates.
In order to take this lock, a read hold must first be taken on
mnt_unmounting, and the two need to be held across the operation.
One effect of this change: previously if an unmount failed, we would make a
half hearted attempt to back out of it gracefully, but that was unlikely to
work in a lot of cases. Now while an unmount that will be aborted is in
progress, new file operations within the mount will fail instead of being
delayed. That is unlikely to be a problem though, because if the admin
requests unmount of a file system then s(he) has made a decision to deny
access to the resource.
2008-05-06 22:43:44 +04:00
|
|
|
mutex_exit(&mp->mnt_updating);
|
2008-04-30 16:49:16 +04:00
|
|
|
vfs_unbusy(mp, false, NULL);
|
2006-12-24 15:43:17 +03:00
|
|
|
|
2011-06-17 18:23:50 +04:00
|
|
|
if ((error == 0) && !(saved_flags & MNT_EXTATTR) &&
|
|
|
|
(flags & MNT_EXTATTR)) {
|
2012-04-28 21:30:19 +04:00
|
|
|
if (VFS_EXTATTRCTL(mp, EXTATTR_CMD_START,
|
2011-06-17 18:23:50 +04:00
|
|
|
NULL, 0, NULL) != 0) {
|
|
|
|
printf("%s: failed to start extattr, error = %d",
|
2012-04-28 21:30:19 +04:00
|
|
|
mp->mnt_stat.f_mntonname, error);
|
2011-06-17 18:23:50 +04:00
|
|
|
mp->mnt_flag &= ~MNT_EXTATTR;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if ((error == 0) && (saved_flags & MNT_EXTATTR) &&
|
|
|
|
!(flags & MNT_EXTATTR)) {
|
2012-04-28 21:30:19 +04:00
|
|
|
if (VFS_EXTATTRCTL(mp, EXTATTR_CMD_STOP,
|
2011-06-17 18:23:50 +04:00
|
|
|
NULL, 0, NULL) != 0) {
|
|
|
|
printf("%s: failed to stop extattr, error = %d",
|
2012-04-28 21:30:19 +04:00
|
|
|
mp->mnt_stat.f_mntonname, error);
|
2011-06-17 18:23:50 +04:00
|
|
|
mp->mnt_flag |= MNT_RDONLY;
|
|
|
|
}
|
|
|
|
}
|
2007-10-11 00:42:20 +04:00
|
|
|
out:
|
2006-12-24 15:43:17 +03:00
|
|
|
return (error);
|
|
|
|
}
|
|
|
|
|
2006-12-26 01:03:42 +03:00
|
|
|
static int
|
2007-07-12 23:35:32 +04:00
|
|
|
mount_get_vfsops(const char *fstype, struct vfsops **vfsops)
|
2006-12-24 15:43:17 +03:00
|
|
|
{
|
2007-07-18 01:15:41 +04:00
|
|
|
char fstypename[sizeof(((struct statvfs *)NULL)->f_fstypename)];
|
2006-12-24 15:43:17 +03:00
|
|
|
int error;
|
|
|
|
|
2007-07-12 23:35:32 +04:00
|
|
|
/* Copy file-system type from userspace. */
|
2007-07-18 01:15:41 +04:00
|
|
|
error = copyinstr(fstype, fstypename, sizeof(fstypename), NULL);
|
1996-02-04 05:17:43 +03:00
|
|
|
if (error) {
|
1995-06-18 18:45:14 +04:00
|
|
|
/*
|
2005-08-05 17:22:23 +04:00
|
|
|
* Historically, filesystem types were identified by numbers.
|
1995-06-18 18:45:14 +04:00
|
|
|
* If we get an integer for the filesystem type instead of a
|
|
|
|
* string, we check to see if it matches one of the historic
|
|
|
|
* filesystem types.
|
2004-03-23 16:22:32 +03:00
|
|
|
*/
|
2006-12-24 15:43:17 +03:00
|
|
|
u_long fsindex = (u_long)fstype;
|
1997-10-06 13:19:11 +04:00
|
|
|
if (fsindex >= nmountcompatnames ||
|
2007-07-12 23:35:32 +04:00
|
|
|
mountcompatnames[fsindex] == NULL)
|
|
|
|
return ENODEV;
|
2007-10-24 19:28:55 +04:00
|
|
|
strlcpy(fstypename, mountcompatnames[fsindex],
|
|
|
|
sizeof(fstypename));
|
1994-06-29 10:29:24 +04:00
|
|
|
}
|
2006-12-24 15:43:17 +03:00
|
|
|
|
2008-11-15 02:10:57 +03:00
|
|
|
/* Accept `ufs' as an alias for `ffs', for compatibility. */
|
2007-07-12 23:35:32 +04:00
|
|
|
if (strcmp(fstypename, "ufs") == 0)
|
|
|
|
fstypename[0] = 'f';
|
2006-12-26 01:03:42 +03:00
|
|
|
|
2008-05-20 21:25:49 +04:00
|
|
|
if ((*vfsops = vfs_getopsbyname(fstypename)) != NULL)
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
/* If we can autoload a vfs module, try again */
|
2009-12-19 23:28:27 +03:00
|
|
|
(void)module_autoload(fstypename, MODULE_CLASS_VFS);
|
2008-05-20 21:25:49 +04:00
|
|
|
|
|
|
|
if ((*vfsops = vfs_getopsbyname(fstypename)) != NULL)
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
return ENODEV;
|
2007-07-12 23:35:32 +04:00
|
|
|
}
|
|
|
|
|
2006-12-24 15:43:17 +03:00
|
|
|
static int
|
|
|
|
mount_getargs(struct lwp *l, struct vnode *vp, const char *path, int flags,
|
2007-08-01 01:14:15 +04:00
|
|
|
void *data, size_t *data_len)
|
2006-12-24 15:43:17 +03:00
|
|
|
{
|
|
|
|
struct mount *mp;
|
|
|
|
int error;
|
|
|
|
|
2006-12-31 13:05:52 +03:00
|
|
|
/* If MNT_GETARGS is specified, it should be the only flag. */
|
2007-07-12 23:35:32 +04:00
|
|
|
if (flags & ~MNT_GETARGS)
|
|
|
|
return EINVAL;
|
2006-12-31 13:05:52 +03:00
|
|
|
|
2006-12-24 15:43:17 +03:00
|
|
|
mp = vp->v_mount;
|
|
|
|
|
2007-01-02 13:47:28 +03:00
|
|
|
/* XXX: probably some notion of "can see" here if we want isolation. */
|
|
|
|
error = kauth_authorize_system(l->l_cred, KAUTH_SYSTEM_MOUNT,
|
|
|
|
KAUTH_REQ_SYSTEM_MOUNT_GET, mp, data, NULL);
|
|
|
|
if (error)
|
2007-07-12 23:35:32 +04:00
|
|
|
return error;
|
2007-01-02 13:47:28 +03:00
|
|
|
|
2007-10-11 00:42:20 +04:00
|
|
|
if ((vp->v_vflag & VV_ROOT) == 0)
|
2007-07-12 23:35:32 +04:00
|
|
|
return EINVAL;
|
2006-12-24 15:43:17 +03:00
|
|
|
|
PR kern/38141 lookup/vfs_busy acquire rwlock recursively
Simplify the mount locking. Remove all the crud to deal with recursion on
the mount lock, and crud to deal with unmount as another weirdo lock.
Hopefully this will once and for all fix the deadlocks with this. With this
commit there are two locks on each mount:
- krwlock_t mnt_unmounting. This is used to prevent unmount across critical
sections like getnewvnode(). It's only ever read locked with rw_tryenter(),
and is only ever write locked in dounmount(). A write hold can't be taken
on this lock if the current LWP could hold a vnode lock.
- kmutex_t mnt_updating. This is taken by threads updating the mount, for
example when going r/o -> r/w, and is only present to serialize updates.
In order to take this lock, a read hold must first be taken on
mnt_unmounting, and the two need to be held across the operation.
One effect of this change: previously if an unmount failed, we would make a
half hearted attempt to back out of it gracefully, but that was unlikely to
work in a lot of cases. Now while an unmount that will be aborted is in
progress, new file operations within the mount will fail instead of being
delayed. That is unlikely to be a problem though, because if the admin
requests unmount of a file system then s(he) has made a decision to deny
access to the resource.
2008-05-06 22:43:44 +04:00
|
|
|
if (vfs_busy(mp, NULL))
|
2007-07-12 23:35:32 +04:00
|
|
|
return EPERM;
|
2006-12-24 15:43:17 +03:00
|
|
|
|
PR kern/38141 lookup/vfs_busy acquire rwlock recursively
Simplify the mount locking. Remove all the crud to deal with recursion on
the mount lock, and crud to deal with unmount as another weirdo lock.
Hopefully this will once and for all fix the deadlocks with this. With this
commit there are two locks on each mount:
- krwlock_t mnt_unmounting. This is used to prevent unmount across critical
sections like getnewvnode(). It's only ever read locked with rw_tryenter(),
and is only ever write locked in dounmount(). A write hold can't be taken
on this lock if the current LWP could hold a vnode lock.
- kmutex_t mnt_updating. This is taken by threads updating the mount, for
example when going r/o -> r/w, and is only present to serialize updates.
In order to take this lock, a read hold must first be taken on
mnt_unmounting, and the two need to be held across the operation.
One effect of this change: previously if an unmount failed, we would make a
half hearted attempt to back out of it gracefully, but that was unlikely to
work in a lot of cases. Now while an unmount that will be aborted is in
progress, new file operations within the mount will fail instead of being
delayed. That is unlikely to be a problem though, because if the admin
requests unmount of a file system then s(he) has made a decision to deny
access to the resource.
2008-05-06 22:43:44 +04:00
|
|
|
mutex_enter(&mp->mnt_updating);
|
2006-12-26 15:39:01 +03:00
|
|
|
mp->mnt_flag &= ~MNT_OP_FLAGS;
|
|
|
|
mp->mnt_flag |= MNT_GETARGS;
|
2007-11-26 22:01:26 +03:00
|
|
|
error = VFS_MOUNT(mp, path, data, data_len);
|
2006-12-26 15:39:01 +03:00
|
|
|
mp->mnt_flag &= ~MNT_OP_FLAGS;
|
PR kern/38141 lookup/vfs_busy acquire rwlock recursively
Simplify the mount locking. Remove all the crud to deal with recursion on
the mount lock, and crud to deal with unmount as another weirdo lock.
Hopefully this will once and for all fix the deadlocks with this. With this
commit there are two locks on each mount:
- krwlock_t mnt_unmounting. This is used to prevent unmount across critical
sections like getnewvnode(). It's only ever read locked with rw_tryenter(),
and is only ever write locked in dounmount(). A write hold can't be taken
on this lock if the current LWP could hold a vnode lock.
- kmutex_t mnt_updating. This is taken by threads updating the mount, for
example when going r/o -> r/w, and is only present to serialize updates.
In order to take this lock, a read hold must first be taken on
mnt_unmounting, and the two need to be held across the operation.
One effect of this change: previously if an unmount failed, we would make a
half hearted attempt to back out of it gracefully, but that was unlikely to
work in a lot of cases. Now while an unmount that will be aborted is in
progress, new file operations within the mount will fail instead of being
delayed. That is unlikely to be a problem though, because if the admin
requests unmount of a file system then s(he) has made a decision to deny
access to the resource.
2008-05-06 22:43:44 +04:00
|
|
|
mutex_exit(&mp->mnt_updating);
|
2006-12-24 15:43:17 +03:00
|
|
|
|
2008-04-30 16:49:16 +04:00
|
|
|
vfs_unbusy(mp, false, NULL);
|
2006-12-24 15:43:17 +03:00
|
|
|
return (error);
|
|
|
|
}
|
|
|
|
|
2007-07-14 19:41:30 +04:00
|
|
|
int
|
2007-12-21 02:02:38 +03:00
|
|
|
sys___mount50(struct lwp *l, const struct sys___mount50_args *uap, register_t *retval)
|
2007-07-14 19:41:30 +04:00
|
|
|
{
|
2007-12-21 02:02:38 +03:00
|
|
|
/* {
|
2007-07-14 19:41:30 +04:00
|
|
|
syscallarg(const char *) type;
|
|
|
|
syscallarg(const char *) path;
|
|
|
|
syscallarg(int) flags;
|
|
|
|
syscallarg(void *) data;
|
|
|
|
syscallarg(size_t) data_len;
|
2007-12-21 02:02:38 +03:00
|
|
|
} */
|
2007-07-14 19:41:30 +04:00
|
|
|
|
|
|
|
return do_sys_mount(l, NULL, SCARG(uap, type), SCARG(uap, path),
|
|
|
|
SCARG(uap, flags), SCARG(uap, data), UIO_USERSPACE,
|
|
|
|
SCARG(uap, data_len), retval);
|
|
|
|
}
|
2007-07-12 23:35:32 +04:00
|
|
|
|
|
|
|
int
|
|
|
|
do_sys_mount(struct lwp *l, struct vfsops *vfsops, const char *type,
|
|
|
|
const char *path, int flags, void *data, enum uio_seg data_seg,
|
|
|
|
size_t data_len, register_t *retval)
|
|
|
|
{
|
2006-12-24 15:43:17 +03:00
|
|
|
struct vnode *vp;
|
2007-07-12 23:35:32 +04:00
|
|
|
void *data_buf = data;
|
2010-01-15 04:00:46 +03:00
|
|
|
bool vfsopsrele = false;
|
2006-12-24 15:43:17 +03:00
|
|
|
int error;
|
|
|
|
|
2010-01-15 04:00:46 +03:00
|
|
|
/* XXX: The calling convention of this routine is totally bizarre */
|
|
|
|
if (vfsops)
|
|
|
|
vfsopsrele = true;
|
|
|
|
|
2006-12-24 15:43:17 +03:00
|
|
|
/*
|
|
|
|
* Get vnode to be covered
|
|
|
|
*/
|
Convert 67 namei call sites to use namei_simple, in these functions:
check_console, veriexecclose, veriexec_delete, veriexec_file_add,
emul_find_root, coff_load_shlib (sh3 version), coff_load_shlib,
compat_20_sys_statfs, compat_20_netbsd32_statfs,
ELFNAME2(netbsd32,probe_noteless), darwin_sys_statfs,
ibcs2_sys_statfs, ibcs2_sys_statvfs, linux_sys_uselib,
osf1_sys_statfs, sunos_sys_statfs, sunos32_sys_statfs,
ultrix_sys_statfs, do_sys_mount, fss_create_files (3 of 4),
adosfs_mount, cd9660_mount, coda_ioctl, coda_mount, ext2fs_mount,
ffs_mount, filecore_mount, hfs_mount, lfs_mount, msdosfs_mount,
ntfs_mount, sysvbfs_mount, udf_mount, union_mount, sys_chflags,
sys_lchflags, sys_chmod, sys_lchmod, sys_chown, sys_lchown,
sys___posix_chown, sys___posix_lchown, sys_link, do_sys_pstatvfs,
sys_quotactl, sys_revoke, sys_truncate, do_sys_utimes, sys_extattrctl,
sys_extattr_set_file, sys_extattr_set_link, sys_extattr_get_file,
sys_extattr_get_link, sys_extattr_delete_file,
sys_extattr_delete_link, sys_extattr_list_file, sys_extattr_list_link,
sys_setxattr, sys_lsetxattr, sys_getxattr, sys_lgetxattr,
sys_listxattr, sys_llistxattr, sys_removexattr, sys_lremovexattr
All have been scrutinized (several times, in fact) and compile-tested,
but not all have been explicitly tested in action.
XXX: While I haven't (intentionally) changed the use or nonuse of
XXX: TRYEMULROOT in any of these places, I'm not convinced all the
XXX: uses are correct; an audit might be desirable.
2009-06-29 09:08:15 +04:00
|
|
|
error = namei_simple_user(path, NSM_FOLLOW_TRYEMULROOT, &vp);
|
2010-01-15 04:00:46 +03:00
|
|
|
if (error != 0) {
|
|
|
|
vp = NULL;
|
|
|
|
goto done;
|
|
|
|
}
|
2006-12-24 15:43:17 +03:00
|
|
|
|
2007-07-12 23:35:32 +04:00
|
|
|
if (vfsops == NULL) {
|
2008-05-20 21:28:59 +04:00
|
|
|
if (flags & (MNT_GETARGS | MNT_UPDATE)) {
|
2007-07-12 23:35:32 +04:00
|
|
|
vfsops = vp->v_mount->mnt_op;
|
2008-05-20 21:28:59 +04:00
|
|
|
} else {
|
2007-07-12 23:35:32 +04:00
|
|
|
/* 'type' is userspace */
|
|
|
|
error = mount_get_vfsops(type, &vfsops);
|
|
|
|
if (error != 0)
|
|
|
|
goto done;
|
2010-01-15 04:00:46 +03:00
|
|
|
vfsopsrele = true;
|
2007-07-12 23:35:32 +04:00
|
|
|
}
|
|
|
|
}
|
2006-12-24 15:43:17 +03:00
|
|
|
|
2007-07-12 23:35:32 +04:00
|
|
|
if (data != NULL && data_seg == UIO_USERSPACE) {
|
|
|
|
if (data_len == 0) {
|
|
|
|
/* No length supplied, use default for filesystem */
|
|
|
|
data_len = vfsops->vfs_min_mount_data;
|
|
|
|
if (data_len > VFS_MAX_MOUNT_DATA) {
|
|
|
|
error = EINVAL;
|
|
|
|
goto done;
|
|
|
|
}
|
2008-11-15 02:10:57 +03:00
|
|
|
/*
|
|
|
|
* Hopefully a longer buffer won't make copyin() fail.
|
|
|
|
* For compatibility with 3.0 and earlier.
|
|
|
|
*/
|
2007-07-12 23:35:32 +04:00
|
|
|
if (flags & MNT_UPDATE
|
|
|
|
&& data_len < sizeof (struct mnt_export_args30))
|
|
|
|
data_len = sizeof (struct mnt_export_args30);
|
|
|
|
}
|
2009-01-17 10:02:35 +03:00
|
|
|
data_buf = kmem_alloc(data_len, KM_SLEEP);
|
2007-07-12 23:35:32 +04:00
|
|
|
|
|
|
|
/* NFS needs the buffer even for mnt_getargs .... */
|
|
|
|
error = copyin(data, data_buf, data_len);
|
|
|
|
if (error != 0)
|
|
|
|
goto done;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (flags & MNT_GETARGS) {
|
|
|
|
if (data_len == 0) {
|
|
|
|
error = EINVAL;
|
|
|
|
goto done;
|
|
|
|
}
|
2007-08-01 01:14:15 +04:00
|
|
|
error = mount_getargs(l, vp, path, flags, data_buf, &data_len);
|
2007-07-12 23:35:32 +04:00
|
|
|
if (error != 0)
|
|
|
|
goto done;
|
|
|
|
if (data_seg == UIO_USERSPACE)
|
|
|
|
error = copyout(data_buf, data, data_len);
|
|
|
|
*retval = data_len;
|
|
|
|
} else if (flags & MNT_UPDATE) {
|
2007-08-01 01:14:15 +04:00
|
|
|
error = mount_update(l, vp, path, flags, data_buf, &data_len);
|
2006-12-24 15:43:17 +03:00
|
|
|
} else {
|
|
|
|
/* Locking is handled internally in mount_domount(). */
|
2010-01-15 04:00:46 +03:00
|
|
|
KASSERT(vfsopsrele == true);
|
2007-07-12 23:35:32 +04:00
|
|
|
error = mount_domount(l, &vp, vfsops, path, flags, data_buf,
|
2010-06-15 13:43:36 +04:00
|
|
|
&data_len);
|
2010-01-15 04:00:46 +03:00
|
|
|
vfsopsrele = false;
|
2006-12-24 15:43:17 +03:00
|
|
|
}
|
|
|
|
|
2007-07-12 23:35:32 +04:00
|
|
|
done:
|
2010-01-15 04:00:46 +03:00
|
|
|
if (vfsopsrele)
|
|
|
|
vfs_delref(vfsops);
|
2007-12-26 19:01:34 +03:00
|
|
|
if (vp != NULL) {
|
2010-06-15 13:43:36 +04:00
|
|
|
vrele(vp);
|
2007-12-26 19:01:34 +03:00
|
|
|
}
|
2007-07-12 23:35:32 +04:00
|
|
|
if (data_buf != data)
|
2009-01-17 10:02:35 +03:00
|
|
|
kmem_free(data_buf, data_len);
|
1994-06-29 10:29:24 +04:00
|
|
|
return (error);
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Unmount a file system.
|
|
|
|
*
|
|
|
|
* Note: unmount takes a path to the vnode mounted on as argument,
|
|
|
|
* not special file (as before).
|
|
|
|
*/
|
|
|
|
/* ARGSUSED */
|
1996-02-04 05:17:43 +03:00
|
|
|
int
|
2007-12-21 02:02:38 +03:00
|
|
|
sys_unmount(struct lwp *l, const struct sys_unmount_args *uap, register_t *retval)
|
1995-09-20 01:40:36 +04:00
|
|
|
{
|
2007-12-21 02:02:38 +03:00
|
|
|
/* {
|
1996-12-22 13:21:06 +03:00
|
|
|
syscallarg(const char *) path;
|
1994-10-20 07:22:35 +03:00
|
|
|
syscallarg(int) flags;
|
2007-12-21 02:02:38 +03:00
|
|
|
} */
|
2000-03-30 13:27:11 +04:00
|
|
|
struct vnode *vp;
|
1994-06-29 10:29:24 +04:00
|
|
|
struct mount *mp;
|
|
|
|
int error;
|
2010-11-19 09:44:33 +03:00
|
|
|
struct pathbuf *pb;
|
1994-06-29 10:29:24 +04:00
|
|
|
struct nameidata nd;
|
|
|
|
|
2010-11-19 09:44:33 +03:00
|
|
|
error = pathbuf_copyin(SCARG(uap, path), &pb);
|
|
|
|
if (error) {
|
|
|
|
return error;
|
|
|
|
}
|
|
|
|
|
|
|
|
NDINIT(&nd, LOOKUP, FOLLOW | LOCKLEAF | TRYEMULROOT, pb);
|
|
|
|
if ((error = namei(&nd)) != 0) {
|
|
|
|
pathbuf_destroy(pb);
|
|
|
|
return error;
|
|
|
|
}
|
1994-06-29 10:29:24 +04:00
|
|
|
vp = nd.ni_vp;
|
2010-11-19 09:44:33 +03:00
|
|
|
pathbuf_destroy(pb);
|
|
|
|
|
1994-12-14 19:30:40 +03:00
|
|
|
mp = vp->v_mount;
|
PR kern/38141 lookup/vfs_busy acquire rwlock recursively
Simplify the mount locking. Remove all the crud to deal with recursion on
the mount lock, and crud to deal with unmount as another weirdo lock.
Hopefully this will once and for all fix the deadlocks with this. With this
commit there are two locks on each mount:
- krwlock_t mnt_unmounting. This is used to prevent unmount across critical
sections like getnewvnode(). It's only ever read locked with rw_tryenter(),
and is only ever write locked in dounmount(). A write hold can't be taken
on this lock if the current LWP could hold a vnode lock.
- kmutex_t mnt_updating. This is taken by threads updating the mount, for
example when going r/o -> r/w, and is only present to serialize updates.
In order to take this lock, a read hold must first be taken on
mnt_unmounting, and the two need to be held across the operation.
One effect of this change: previously if an unmount failed, we would make a
half hearted attempt to back out of it gracefully, but that was unlikely to
work in a lot of cases. Now while an unmount that will be aborted is in
progress, new file operations within the mount will fail instead of being
delayed. That is unlikely to be a problem though, because if the admin
requests unmount of a file system then s(he) has made a decision to deny
access to the resource.
2008-05-06 22:43:44 +04:00
|
|
|
atomic_inc_uint(&mp->mnt_refcnt);
|
2010-06-24 16:58:48 +04:00
|
|
|
VOP_UNLOCK(vp);
|
1994-06-29 10:29:24 +04:00
|
|
|
|
2007-01-05 16:34:17 +03:00
|
|
|
error = kauth_authorize_system(l->l_cred, KAUTH_SYSTEM_MOUNT,
|
|
|
|
KAUTH_REQ_SYSTEM_MOUNT_UNMOUNT, mp, NULL, NULL);
|
|
|
|
if (error) {
|
2008-01-30 14:46:59 +03:00
|
|
|
vrele(vp);
|
PR kern/38141 lookup/vfs_busy acquire rwlock recursively
Simplify the mount locking. Remove all the crud to deal with recursion on
the mount lock, and crud to deal with unmount as another weirdo lock.
Hopefully this will once and for all fix the deadlocks with this. With this
commit there are two locks on each mount:
- krwlock_t mnt_unmounting. This is used to prevent unmount across critical
sections like getnewvnode(). It's only ever read locked with rw_tryenter(),
and is only ever write locked in dounmount(). A write hold can't be taken
on this lock if the current LWP could hold a vnode lock.
- kmutex_t mnt_updating. This is taken by threads updating the mount, for
example when going r/o -> r/w, and is only present to serialize updates.
In order to take this lock, a read hold must first be taken on
mnt_unmounting, and the two need to be held across the operation.
One effect of this change: previously if an unmount failed, we would make a
half hearted attempt to back out of it gracefully, but that was unlikely to
work in a lot of cases. Now while an unmount that will be aborted is in
progress, new file operations within the mount will fail instead of being
delayed. That is unlikely to be a problem though, because if the admin
requests unmount of a file system then s(he) has made a decision to deny
access to the resource.
2008-05-06 22:43:44 +04:00
|
|
|
vfs_destroy(mp);
|
1994-06-29 10:29:24 +04:00
|
|
|
return (error);
|
|
|
|
}
|
|
|
|
|
1995-01-18 09:14:43 +03:00
|
|
|
/*
|
|
|
|
* Don't allow unmounting the root file system.
|
|
|
|
*/
|
|
|
|
if (mp->mnt_flag & MNT_ROOTFS) {
|
2008-01-30 14:46:59 +03:00
|
|
|
vrele(vp);
|
PR kern/38141 lookup/vfs_busy acquire rwlock recursively
Simplify the mount locking. Remove all the crud to deal with recursion on
the mount lock, and crud to deal with unmount as another weirdo lock.
Hopefully this will once and for all fix the deadlocks with this. With this
commit there are two locks on each mount:
- krwlock_t mnt_unmounting. This is used to prevent unmount across critical
sections like getnewvnode(). It's only ever read locked with rw_tryenter(),
and is only ever write locked in dounmount(). A write hold can't be taken
on this lock if the current LWP could hold a vnode lock.
- kmutex_t mnt_updating. This is taken by threads updating the mount, for
example when going r/o -> r/w, and is only present to serialize updates.
In order to take this lock, a read hold must first be taken on
mnt_unmounting, and the two need to be held across the operation.
One effect of this change: previously if an unmount failed, we would make a
half hearted attempt to back out of it gracefully, but that was unlikely to
work in a lot of cases. Now while an unmount that will be aborted is in
progress, new file operations within the mount will fail instead of being
delayed. That is unlikely to be a problem though, because if the admin
requests unmount of a file system then s(he) has made a decision to deny
access to the resource.
2008-05-06 22:43:44 +04:00
|
|
|
vfs_destroy(mp);
|
1995-01-18 09:14:43 +03:00
|
|
|
return (EINVAL);
|
|
|
|
}
|
|
|
|
|
1994-06-29 10:29:24 +04:00
|
|
|
/*
|
|
|
|
* Must be the root of the filesystem
|
|
|
|
*/
|
2007-10-11 00:42:20 +04:00
|
|
|
if ((vp->v_vflag & VV_ROOT) == 0) {
|
2008-01-30 14:46:59 +03:00
|
|
|
vrele(vp);
|
PR kern/38141 lookup/vfs_busy acquire rwlock recursively
Simplify the mount locking. Remove all the crud to deal with recursion on
the mount lock, and crud to deal with unmount as another weirdo lock.
Hopefully this will once and for all fix the deadlocks with this. With this
commit there are two locks on each mount:
- krwlock_t mnt_unmounting. This is used to prevent unmount across critical
sections like getnewvnode(). It's only ever read locked with rw_tryenter(),
and is only ever write locked in dounmount(). A write hold can't be taken
on this lock if the current LWP could hold a vnode lock.
- kmutex_t mnt_updating. This is taken by threads updating the mount, for
example when going r/o -> r/w, and is only present to serialize updates.
In order to take this lock, a read hold must first be taken on
mnt_unmounting, and the two need to be held across the operation.
One effect of this change: previously if an unmount failed, we would make a
half hearted attempt to back out of it gracefully, but that was unlikely to
work in a lot of cases. Now while an unmount that will be aborted is in
progress, new file operations within the mount will fail instead of being
delayed. That is unlikely to be a problem though, because if the admin
requests unmount of a file system then s(he) has made a decision to deny
access to the resource.
2008-05-06 22:43:44 +04:00
|
|
|
vfs_destroy(mp);
|
1994-06-29 10:29:24 +04:00
|
|
|
return (EINVAL);
|
|
|
|
}
|
1997-02-22 06:22:32 +03:00
|
|
|
|
2008-01-30 14:46:59 +03:00
|
|
|
vrele(vp);
|
2008-05-06 23:14:32 +04:00
|
|
|
error = dounmount(mp, SCARG(uap, flags), l);
|
2008-09-25 18:17:29 +04:00
|
|
|
vfs_destroy(mp);
|
PR kern/38141 lookup/vfs_busy acquire rwlock recursively
Simplify the mount locking. Remove all the crud to deal with recursion on
the mount lock, and crud to deal with unmount as another weirdo lock.
Hopefully this will once and for all fix the deadlocks with this. With this
commit there are two locks on each mount:
- krwlock_t mnt_unmounting. This is used to prevent unmount across critical
sections like getnewvnode(). It's only ever read locked with rw_tryenter(),
and is only ever write locked in dounmount(). A write hold can't be taken
on this lock if the current LWP could hold a vnode lock.
- kmutex_t mnt_updating. This is taken by threads updating the mount, for
example when going r/o -> r/w, and is only present to serialize updates.
In order to take this lock, a read hold must first be taken on
mnt_unmounting, and the two need to be held across the operation.
One effect of this change: previously if an unmount failed, we would make a
half hearted attempt to back out of it gracefully, but that was unlikely to
work in a lot of cases. Now while an unmount that will be aborted is in
progress, new file operations within the mount will fail instead of being
delayed. That is unlikely to be a problem though, because if the admin
requests unmount of a file system then s(he) has made a decision to deny
access to the resource.
2008-05-06 22:43:44 +04:00
|
|
|
return error;
|
2008-04-30 03:51:04 +04:00
|
|
|
}
|
|
|
|
|
1994-06-29 10:29:24 +04:00
|
|
|
/*
|
|
|
|
* Sync each mounted filesystem.
|
|
|
|
*/
|
|
|
|
#ifdef DEBUG
|
|
|
|
int syncprt = 0;
|
|
|
|
struct ctldebug debug0 = { "syncprt", &syncprt };
|
|
|
|
#endif
|
|
|
|
|
2011-06-05 13:04:22 +04:00
|
|
|
void
|
|
|
|
do_sys_sync(struct lwp *l)
|
1994-06-29 10:29:24 +04:00
|
|
|
{
|
2000-03-30 13:27:11 +04:00
|
|
|
struct mount *mp, *nmp;
|
1994-06-29 10:29:24 +04:00
|
|
|
int asyncflag;
|
2006-07-24 02:06:03 +04:00
|
|
|
|
2007-10-11 00:42:20 +04:00
|
|
|
mutex_enter(&mountlist_lock);
|
2008-04-30 03:51:04 +04:00
|
|
|
for (mp = CIRCLEQ_FIRST(&mountlist); mp != (void *)&mountlist;
|
|
|
|
mp = nmp) {
|
PR kern/38141 lookup/vfs_busy acquire rwlock recursively
Simplify the mount locking. Remove all the crud to deal with recursion on
the mount lock, and crud to deal with unmount as another weirdo lock.
Hopefully this will once and for all fix the deadlocks with this. With this
commit there are two locks on each mount:
- krwlock_t mnt_unmounting. This is used to prevent unmount across critical
sections like getnewvnode(). It's only ever read locked with rw_tryenter(),
and is only ever write locked in dounmount(). A write hold can't be taken
on this lock if the current LWP could hold a vnode lock.
- kmutex_t mnt_updating. This is taken by threads updating the mount, for
example when going r/o -> r/w, and is only present to serialize updates.
In order to take this lock, a read hold must first be taken on
mnt_unmounting, and the two need to be held across the operation.
One effect of this change: previously if an unmount failed, we would make a
half hearted attempt to back out of it gracefully, but that was unlikely to
work in a lot of cases. Now while an unmount that will be aborted is in
progress, new file operations within the mount will fail instead of being
delayed. That is unlikely to be a problem though, because if the admin
requests unmount of a file system then s(he) has made a decision to deny
access to the resource.
2008-05-06 22:43:44 +04:00
|
|
|
if (vfs_busy(mp, &nmp)) {
|
1998-03-01 05:20:01 +03:00
|
|
|
continue;
|
|
|
|
}
|
PR kern/38141 lookup/vfs_busy acquire rwlock recursively
Simplify the mount locking. Remove all the crud to deal with recursion on
the mount lock, and crud to deal with unmount as another weirdo lock.
Hopefully this will once and for all fix the deadlocks with this. With this
commit there are two locks on each mount:
- krwlock_t mnt_unmounting. This is used to prevent unmount across critical
sections like getnewvnode(). It's only ever read locked with rw_tryenter(),
and is only ever write locked in dounmount(). A write hold can't be taken
on this lock if the current LWP could hold a vnode lock.
- kmutex_t mnt_updating. This is taken by threads updating the mount, for
example when going r/o -> r/w, and is only present to serialize updates.
In order to take this lock, a read hold must first be taken on
mnt_unmounting, and the two need to be held across the operation.
One effect of this change: previously if an unmount failed, we would make a
half hearted attempt to back out of it gracefully, but that was unlikely to
work in a lot of cases. Now while an unmount that will be aborted is in
progress, new file operations within the mount will fail instead of being
delayed. That is unlikely to be a problem though, because if the admin
requests unmount of a file system then s(he) has made a decision to deny
access to the resource.
2008-05-06 22:43:44 +04:00
|
|
|
mutex_enter(&mp->mnt_updating);
|
2007-04-01 14:15:01 +04:00
|
|
|
if ((mp->mnt_flag & MNT_RDONLY) == 0) {
|
1994-06-29 10:29:24 +04:00
|
|
|
asyncflag = mp->mnt_flag & MNT_ASYNC;
|
|
|
|
mp->mnt_flag &= ~MNT_ASYNC;
|
2007-11-26 22:01:26 +03:00
|
|
|
VFS_SYNC(mp, MNT_NOWAIT, l->l_cred);
|
1994-06-29 10:29:24 +04:00
|
|
|
if (asyncflag)
|
1998-03-01 05:20:01 +03:00
|
|
|
mp->mnt_flag |= MNT_ASYNC;
|
1994-06-29 10:29:24 +04:00
|
|
|
}
|
PR kern/38141 lookup/vfs_busy acquire rwlock recursively
Simplify the mount locking. Remove all the crud to deal with recursion on
the mount lock, and crud to deal with unmount as another weirdo lock.
Hopefully this will once and for all fix the deadlocks with this. With this
commit there are two locks on each mount:
- krwlock_t mnt_unmounting. This is used to prevent unmount across critical
sections like getnewvnode(). It's only ever read locked with rw_tryenter(),
and is only ever write locked in dounmount(). A write hold can't be taken
on this lock if the current LWP could hold a vnode lock.
- kmutex_t mnt_updating. This is taken by threads updating the mount, for
example when going r/o -> r/w, and is only present to serialize updates.
In order to take this lock, a read hold must first be taken on
mnt_unmounting, and the two need to be held across the operation.
One effect of this change: previously if an unmount failed, we would make a
half hearted attempt to back out of it gracefully, but that was unlikely to
work in a lot of cases. Now while an unmount that will be aborted is in
progress, new file operations within the mount will fail instead of being
delayed. That is unlikely to be a problem though, because if the admin
requests unmount of a file system then s(he) has made a decision to deny
access to the resource.
2008-05-06 22:43:44 +04:00
|
|
|
mutex_exit(&mp->mnt_updating);
|
2008-04-30 16:49:16 +04:00
|
|
|
vfs_unbusy(mp, false, &nmp);
|
1994-06-29 10:29:24 +04:00
|
|
|
}
|
2007-10-11 00:42:20 +04:00
|
|
|
mutex_exit(&mountlist_lock);
|
1994-06-29 10:29:24 +04:00
|
|
|
#ifdef DEBUG
|
|
|
|
if (syncprt)
|
|
|
|
vfs_bufstats();
|
|
|
|
#endif /* DEBUG */
|
2011-06-05 13:04:22 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
/* ARGSUSED */
|
|
|
|
int
|
|
|
|
sys_sync(struct lwp *l, const void *v, register_t *retval)
|
|
|
|
{
|
|
|
|
do_sys_sync(l);
|
1994-06-29 10:29:24 +04:00
|
|
|
return (0);
|
|
|
|
}
|
|
|
|
|
2011-06-05 13:04:22 +04:00
|
|
|
|
1994-06-29 10:29:24 +04:00
|
|
|
/*
|
2012-02-01 09:34:38 +04:00
|
|
|
* Access or change filesystem quotas.
|
|
|
|
*
|
|
|
|
* (this is really 14 different calls bundled into one)
|
1994-06-29 10:29:24 +04:00
|
|
|
*/
|
2012-02-01 09:34:38 +04:00
|
|
|
|
|
|
|
static int
|
|
|
|
do_sys_quotactl_stat(struct mount *mp, struct quotastat *info_u)
|
|
|
|
{
|
|
|
|
struct quotastat info_k;
|
|
|
|
int error;
|
|
|
|
|
|
|
|
/* ensure any padding bytes are cleared */
|
|
|
|
memset(&info_k, 0, sizeof(info_k));
|
|
|
|
|
|
|
|
error = vfs_quotactl_stat(mp, &info_k);
|
|
|
|
if (error) {
|
|
|
|
return error;
|
|
|
|
}
|
|
|
|
|
|
|
|
return copyout(&info_k, info_u, sizeof(info_k));
|
|
|
|
}
|
|
|
|
|
|
|
|
static int
|
|
|
|
do_sys_quotactl_idtypestat(struct mount *mp, int idtype,
|
|
|
|
struct quotaidtypestat *info_u)
|
|
|
|
{
|
|
|
|
struct quotaidtypestat info_k;
|
|
|
|
int error;
|
|
|
|
|
|
|
|
/* ensure any padding bytes are cleared */
|
|
|
|
memset(&info_k, 0, sizeof(info_k));
|
|
|
|
|
|
|
|
error = vfs_quotactl_idtypestat(mp, idtype, &info_k);
|
|
|
|
if (error) {
|
|
|
|
return error;
|
|
|
|
}
|
|
|
|
|
|
|
|
return copyout(&info_k, info_u, sizeof(info_k));
|
|
|
|
}
|
|
|
|
|
|
|
|
static int
|
|
|
|
do_sys_quotactl_objtypestat(struct mount *mp, int objtype,
|
|
|
|
struct quotaobjtypestat *info_u)
|
|
|
|
{
|
|
|
|
struct quotaobjtypestat info_k;
|
|
|
|
int error;
|
|
|
|
|
|
|
|
/* ensure any padding bytes are cleared */
|
|
|
|
memset(&info_k, 0, sizeof(info_k));
|
|
|
|
|
|
|
|
error = vfs_quotactl_objtypestat(mp, objtype, &info_k);
|
|
|
|
if (error) {
|
|
|
|
return error;
|
|
|
|
}
|
|
|
|
|
|
|
|
return copyout(&info_k, info_u, sizeof(info_k));
|
|
|
|
}
|
|
|
|
|
|
|
|
static int
|
|
|
|
do_sys_quotactl_get(struct mount *mp, const struct quotakey *key_u,
|
|
|
|
struct quotaval *val_u)
|
|
|
|
{
|
|
|
|
struct quotakey key_k;
|
|
|
|
struct quotaval val_k;
|
|
|
|
int error;
|
|
|
|
|
|
|
|
/* ensure any padding bytes are cleared */
|
|
|
|
memset(&val_k, 0, sizeof(val_k));
|
|
|
|
|
|
|
|
error = copyin(key_u, &key_k, sizeof(key_k));
|
|
|
|
if (error) {
|
|
|
|
return error;
|
|
|
|
}
|
|
|
|
|
|
|
|
error = vfs_quotactl_get(mp, &key_k, &val_k);
|
|
|
|
if (error) {
|
|
|
|
return error;
|
|
|
|
}
|
|
|
|
|
|
|
|
return copyout(&val_k, val_u, sizeof(val_k));
|
|
|
|
}
|
|
|
|
|
|
|
|
static int
|
|
|
|
do_sys_quotactl_put(struct mount *mp, const struct quotakey *key_u,
|
|
|
|
const struct quotaval *val_u)
|
|
|
|
{
|
|
|
|
struct quotakey key_k;
|
|
|
|
struct quotaval val_k;
|
|
|
|
int error;
|
|
|
|
|
|
|
|
error = copyin(key_u, &key_k, sizeof(key_k));
|
|
|
|
if (error) {
|
|
|
|
return error;
|
|
|
|
}
|
|
|
|
|
|
|
|
error = copyin(val_u, &val_k, sizeof(val_k));
|
|
|
|
if (error) {
|
|
|
|
return error;
|
|
|
|
}
|
|
|
|
|
|
|
|
return vfs_quotactl_put(mp, &key_k, &val_k);
|
|
|
|
}
|
|
|
|
|
|
|
|
static int
|
|
|
|
do_sys_quotactl_delete(struct mount *mp, const struct quotakey *key_u)
|
|
|
|
{
|
|
|
|
struct quotakey key_k;
|
|
|
|
int error;
|
|
|
|
|
|
|
|
error = copyin(key_u, &key_k, sizeof(key_k));
|
|
|
|
if (error) {
|
|
|
|
return error;
|
|
|
|
}
|
|
|
|
|
|
|
|
return vfs_quotactl_delete(mp, &key_k);
|
|
|
|
}
|
|
|
|
|
|
|
|
static int
|
|
|
|
do_sys_quotactl_cursoropen(struct mount *mp, struct quotakcursor *cursor_u)
|
|
|
|
{
|
|
|
|
struct quotakcursor cursor_k;
|
|
|
|
int error;
|
|
|
|
|
|
|
|
/* ensure any padding bytes are cleared */
|
|
|
|
memset(&cursor_k, 0, sizeof(cursor_k));
|
|
|
|
|
|
|
|
error = vfs_quotactl_cursoropen(mp, &cursor_k);
|
|
|
|
if (error) {
|
|
|
|
return error;
|
|
|
|
}
|
|
|
|
|
|
|
|
return copyout(&cursor_k, cursor_u, sizeof(cursor_k));
|
|
|
|
}
|
|
|
|
|
|
|
|
static int
|
|
|
|
do_sys_quotactl_cursorclose(struct mount *mp, struct quotakcursor *cursor_u)
|
|
|
|
{
|
|
|
|
struct quotakcursor cursor_k;
|
|
|
|
int error;
|
|
|
|
|
|
|
|
error = copyin(cursor_u, &cursor_k, sizeof(cursor_k));
|
|
|
|
if (error) {
|
|
|
|
return error;
|
|
|
|
}
|
|
|
|
|
|
|
|
return vfs_quotactl_cursorclose(mp, &cursor_k);
|
|
|
|
}
|
|
|
|
|
|
|
|
static int
|
|
|
|
do_sys_quotactl_cursorskipidtype(struct mount *mp,
|
|
|
|
struct quotakcursor *cursor_u, int idtype)
|
|
|
|
{
|
|
|
|
struct quotakcursor cursor_k;
|
|
|
|
int error;
|
|
|
|
|
|
|
|
error = copyin(cursor_u, &cursor_k, sizeof(cursor_k));
|
|
|
|
if (error) {
|
|
|
|
return error;
|
|
|
|
}
|
|
|
|
|
|
|
|
error = vfs_quotactl_cursorskipidtype(mp, &cursor_k, idtype);
|
|
|
|
if (error) {
|
|
|
|
return error;
|
|
|
|
}
|
|
|
|
|
|
|
|
return copyout(&cursor_k, cursor_u, sizeof(cursor_k));
|
|
|
|
}
|
|
|
|
|
|
|
|
static int
|
|
|
|
do_sys_quotactl_cursorget(struct mount *mp, struct quotakcursor *cursor_u,
|
|
|
|
struct quotakey *keys_u, struct quotaval *vals_u, unsigned maxnum,
|
2012-02-01 09:46:45 +04:00
|
|
|
unsigned *ret_u)
|
2012-02-01 09:34:38 +04:00
|
|
|
{
|
|
|
|
#define CGET_STACK_MAX 8
|
|
|
|
struct quotakcursor cursor_k;
|
|
|
|
struct quotakey stackkeys[CGET_STACK_MAX];
|
|
|
|
struct quotaval stackvals[CGET_STACK_MAX];
|
|
|
|
struct quotakey *keys_k;
|
|
|
|
struct quotaval *vals_k;
|
2012-02-01 09:46:45 +04:00
|
|
|
unsigned ret_k;
|
2012-02-01 09:34:38 +04:00
|
|
|
int error;
|
|
|
|
|
|
|
|
if (maxnum > 128) {
|
|
|
|
maxnum = 128;
|
|
|
|
}
|
|
|
|
|
|
|
|
error = copyin(cursor_u, &cursor_k, sizeof(cursor_k));
|
|
|
|
if (error) {
|
|
|
|
return error;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (maxnum <= CGET_STACK_MAX) {
|
|
|
|
keys_k = stackkeys;
|
|
|
|
vals_k = stackvals;
|
|
|
|
/* ensure any padding bytes are cleared */
|
|
|
|
memset(keys_k, 0, maxnum * sizeof(keys_k[0]));
|
|
|
|
memset(vals_k, 0, maxnum * sizeof(vals_k[0]));
|
|
|
|
} else {
|
|
|
|
keys_k = kmem_zalloc(maxnum * sizeof(keys_k[0]), KM_SLEEP);
|
|
|
|
vals_k = kmem_zalloc(maxnum * sizeof(vals_k[0]), KM_SLEEP);
|
|
|
|
}
|
|
|
|
|
|
|
|
error = vfs_quotactl_cursorget(mp, &cursor_k, keys_k, vals_k, maxnum,
|
|
|
|
&ret_k);
|
|
|
|
if (error) {
|
|
|
|
goto fail;
|
|
|
|
}
|
|
|
|
|
|
|
|
error = copyout(keys_k, keys_u, ret_k * sizeof(keys_k[0]));
|
|
|
|
if (error) {
|
|
|
|
goto fail;
|
|
|
|
}
|
|
|
|
|
|
|
|
error = copyout(vals_k, vals_u, ret_k * sizeof(vals_k[0]));
|
|
|
|
if (error) {
|
|
|
|
goto fail;
|
|
|
|
}
|
|
|
|
|
|
|
|
error = copyout(&ret_k, ret_u, sizeof(ret_k));
|
|
|
|
if (error) {
|
|
|
|
goto fail;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* do last to maximize the chance of being able to recover a failure */
|
|
|
|
error = copyout(&cursor_k, cursor_u, sizeof(cursor_k));
|
|
|
|
|
|
|
|
fail:
|
|
|
|
if (keys_k != stackkeys) {
|
|
|
|
kmem_free(keys_k, maxnum * sizeof(keys_k[0]));
|
|
|
|
}
|
|
|
|
if (vals_k != stackvals) {
|
|
|
|
kmem_free(vals_k, maxnum * sizeof(vals_k[0]));
|
|
|
|
}
|
|
|
|
return error;
|
|
|
|
}
|
|
|
|
|
|
|
|
static int
|
|
|
|
do_sys_quotactl_cursoratend(struct mount *mp, struct quotakcursor *cursor_u,
|
|
|
|
int *ret_u)
|
|
|
|
{
|
|
|
|
struct quotakcursor cursor_k;
|
|
|
|
int ret_k;
|
|
|
|
int error;
|
|
|
|
|
|
|
|
error = copyin(cursor_u, &cursor_k, sizeof(cursor_k));
|
|
|
|
if (error) {
|
|
|
|
return error;
|
|
|
|
}
|
|
|
|
|
|
|
|
error = vfs_quotactl_cursoratend(mp, &cursor_k, &ret_k);
|
|
|
|
if (error) {
|
|
|
|
return error;
|
|
|
|
}
|
|
|
|
|
|
|
|
error = copyout(&ret_k, ret_u, sizeof(ret_k));
|
|
|
|
if (error) {
|
|
|
|
return error;
|
|
|
|
}
|
|
|
|
|
|
|
|
return copyout(&cursor_k, cursor_u, sizeof(cursor_k));
|
|
|
|
}
|
|
|
|
|
|
|
|
static int
|
|
|
|
do_sys_quotactl_cursorrewind(struct mount *mp, struct quotakcursor *cursor_u)
|
|
|
|
{
|
|
|
|
struct quotakcursor cursor_k;
|
|
|
|
int error;
|
|
|
|
|
|
|
|
error = copyin(cursor_u, &cursor_k, sizeof(cursor_k));
|
|
|
|
if (error) {
|
|
|
|
return error;
|
|
|
|
}
|
|
|
|
|
|
|
|
error = vfs_quotactl_cursorrewind(mp, &cursor_k);
|
|
|
|
if (error) {
|
|
|
|
return error;
|
|
|
|
}
|
|
|
|
|
|
|
|
return copyout(&cursor_k, cursor_u, sizeof(cursor_k));
|
|
|
|
}
|
|
|
|
|
|
|
|
static int
|
|
|
|
do_sys_quotactl_quotaon(struct mount *mp, int idtype, const char *path_u)
|
|
|
|
{
|
|
|
|
char *path_k;
|
|
|
|
int error;
|
|
|
|
|
|
|
|
/* XXX this should probably be a struct pathbuf */
|
|
|
|
path_k = PNBUF_GET();
|
|
|
|
error = copyin(path_u, path_k, PATH_MAX);
|
|
|
|
if (error) {
|
|
|
|
PNBUF_PUT(path_k);
|
|
|
|
return error;
|
|
|
|
}
|
|
|
|
|
|
|
|
error = vfs_quotactl_quotaon(mp, idtype, path_k);
|
|
|
|
|
|
|
|
PNBUF_PUT(path_k);
|
|
|
|
return error;
|
|
|
|
}
|
|
|
|
|
|
|
|
static int
|
|
|
|
do_sys_quotactl_quotaoff(struct mount *mp, int idtype)
|
|
|
|
{
|
|
|
|
return vfs_quotactl_quotaoff(mp, idtype);
|
|
|
|
}
|
|
|
|
|
1996-02-04 05:17:43 +03:00
|
|
|
int
|
2012-02-01 09:39:28 +04:00
|
|
|
do_sys_quotactl(const char *path_u, const struct quotactl_args *args)
|
1995-09-20 01:40:36 +04:00
|
|
|
{
|
2000-03-30 13:27:11 +04:00
|
|
|
struct mount *mp;
|
Convert 67 namei call sites to use namei_simple, in these functions:
check_console, veriexecclose, veriexec_delete, veriexec_file_add,
emul_find_root, coff_load_shlib (sh3 version), coff_load_shlib,
compat_20_sys_statfs, compat_20_netbsd32_statfs,
ELFNAME2(netbsd32,probe_noteless), darwin_sys_statfs,
ibcs2_sys_statfs, ibcs2_sys_statvfs, linux_sys_uselib,
osf1_sys_statfs, sunos_sys_statfs, sunos32_sys_statfs,
ultrix_sys_statfs, do_sys_mount, fss_create_files (3 of 4),
adosfs_mount, cd9660_mount, coda_ioctl, coda_mount, ext2fs_mount,
ffs_mount, filecore_mount, hfs_mount, lfs_mount, msdosfs_mount,
ntfs_mount, sysvbfs_mount, udf_mount, union_mount, sys_chflags,
sys_lchflags, sys_chmod, sys_lchmod, sys_chown, sys_lchown,
sys___posix_chown, sys___posix_lchown, sys_link, do_sys_pstatvfs,
sys_quotactl, sys_revoke, sys_truncate, do_sys_utimes, sys_extattrctl,
sys_extattr_set_file, sys_extattr_set_link, sys_extattr_get_file,
sys_extattr_get_link, sys_extattr_delete_file,
sys_extattr_delete_link, sys_extattr_list_file, sys_extattr_list_link,
sys_setxattr, sys_lsetxattr, sys_getxattr, sys_lgetxattr,
sys_listxattr, sys_llistxattr, sys_removexattr, sys_lremovexattr
All have been scrutinized (several times, in fact) and compile-tested,
but not all have been explicitly tested in action.
XXX: While I haven't (intentionally) changed the use or nonuse of
XXX: TRYEMULROOT in any of these places, I'm not convinced all the
XXX: uses are correct; an audit might be desirable.
2009-06-29 09:08:15 +04:00
|
|
|
struct vnode *vp;
|
2012-02-01 09:34:38 +04:00
|
|
|
int error;
|
1994-06-29 10:29:24 +04:00
|
|
|
|
2012-02-01 09:39:28 +04:00
|
|
|
error = namei_simple_user(path_u, NSM_FOLLOW_TRYEMULROOT, &vp);
|
Convert 67 namei call sites to use namei_simple, in these functions:
check_console, veriexecclose, veriexec_delete, veriexec_file_add,
emul_find_root, coff_load_shlib (sh3 version), coff_load_shlib,
compat_20_sys_statfs, compat_20_netbsd32_statfs,
ELFNAME2(netbsd32,probe_noteless), darwin_sys_statfs,
ibcs2_sys_statfs, ibcs2_sys_statvfs, linux_sys_uselib,
osf1_sys_statfs, sunos_sys_statfs, sunos32_sys_statfs,
ultrix_sys_statfs, do_sys_mount, fss_create_files (3 of 4),
adosfs_mount, cd9660_mount, coda_ioctl, coda_mount, ext2fs_mount,
ffs_mount, filecore_mount, hfs_mount, lfs_mount, msdosfs_mount,
ntfs_mount, sysvbfs_mount, udf_mount, union_mount, sys_chflags,
sys_lchflags, sys_chmod, sys_lchmod, sys_chown, sys_lchown,
sys___posix_chown, sys___posix_lchown, sys_link, do_sys_pstatvfs,
sys_quotactl, sys_revoke, sys_truncate, do_sys_utimes, sys_extattrctl,
sys_extattr_set_file, sys_extattr_set_link, sys_extattr_get_file,
sys_extattr_get_link, sys_extattr_delete_file,
sys_extattr_delete_link, sys_extattr_list_file, sys_extattr_list_link,
sys_setxattr, sys_lsetxattr, sys_getxattr, sys_lgetxattr,
sys_listxattr, sys_llistxattr, sys_removexattr, sys_lremovexattr
All have been scrutinized (several times, in fact) and compile-tested,
but not all have been explicitly tested in action.
XXX: While I haven't (intentionally) changed the use or nonuse of
XXX: TRYEMULROOT in any of these places, I'm not convinced all the
XXX: uses are correct; an audit might be desirable.
2009-06-29 09:08:15 +04:00
|
|
|
if (error != 0)
|
1994-06-29 10:29:24 +04:00
|
|
|
return (error);
|
Convert 67 namei call sites to use namei_simple, in these functions:
check_console, veriexecclose, veriexec_delete, veriexec_file_add,
emul_find_root, coff_load_shlib (sh3 version), coff_load_shlib,
compat_20_sys_statfs, compat_20_netbsd32_statfs,
ELFNAME2(netbsd32,probe_noteless), darwin_sys_statfs,
ibcs2_sys_statfs, ibcs2_sys_statvfs, linux_sys_uselib,
osf1_sys_statfs, sunos_sys_statfs, sunos32_sys_statfs,
ultrix_sys_statfs, do_sys_mount, fss_create_files (3 of 4),
adosfs_mount, cd9660_mount, coda_ioctl, coda_mount, ext2fs_mount,
ffs_mount, filecore_mount, hfs_mount, lfs_mount, msdosfs_mount,
ntfs_mount, sysvbfs_mount, udf_mount, union_mount, sys_chflags,
sys_lchflags, sys_chmod, sys_lchmod, sys_chown, sys_lchown,
sys___posix_chown, sys___posix_lchown, sys_link, do_sys_pstatvfs,
sys_quotactl, sys_revoke, sys_truncate, do_sys_utimes, sys_extattrctl,
sys_extattr_set_file, sys_extattr_set_link, sys_extattr_get_file,
sys_extattr_get_link, sys_extattr_delete_file,
sys_extattr_delete_link, sys_extattr_list_file, sys_extattr_list_link,
sys_setxattr, sys_lsetxattr, sys_getxattr, sys_lgetxattr,
sys_listxattr, sys_llistxattr, sys_removexattr, sys_lremovexattr
All have been scrutinized (several times, in fact) and compile-tested,
but not all have been explicitly tested in action.
XXX: While I haven't (intentionally) changed the use or nonuse of
XXX: TRYEMULROOT in any of these places, I'm not convinced all the
XXX: uses are correct; an audit might be desirable.
2009-06-29 09:08:15 +04:00
|
|
|
mp = vp->v_mount;
|
2012-02-01 09:34:38 +04:00
|
|
|
|
2012-02-01 09:39:28 +04:00
|
|
|
switch (args->qc_op) {
|
2012-02-01 09:34:38 +04:00
|
|
|
case QUOTACTL_STAT:
|
2012-02-01 09:43:53 +04:00
|
|
|
error = do_sys_quotactl_stat(mp, args->u.stat.qc_info);
|
2012-02-01 09:34:38 +04:00
|
|
|
break;
|
|
|
|
case QUOTACTL_IDTYPESTAT:
|
|
|
|
error = do_sys_quotactl_idtypestat(mp,
|
2012-02-01 09:39:28 +04:00
|
|
|
args->u.idtypestat.qc_idtype,
|
|
|
|
args->u.idtypestat.qc_info);
|
2012-02-01 09:34:38 +04:00
|
|
|
break;
|
|
|
|
case QUOTACTL_OBJTYPESTAT:
|
|
|
|
error = do_sys_quotactl_objtypestat(mp,
|
2012-02-01 09:39:28 +04:00
|
|
|
args->u.objtypestat.qc_objtype,
|
|
|
|
args->u.objtypestat.qc_info);
|
2012-02-01 09:34:38 +04:00
|
|
|
break;
|
|
|
|
case QUOTACTL_GET:
|
|
|
|
error = do_sys_quotactl_get(mp,
|
2012-02-01 09:39:28 +04:00
|
|
|
args->u.get.qc_key,
|
2012-02-01 09:43:53 +04:00
|
|
|
args->u.get.qc_val);
|
2012-02-01 09:34:38 +04:00
|
|
|
break;
|
|
|
|
case QUOTACTL_PUT:
|
|
|
|
error = do_sys_quotactl_put(mp,
|
2012-02-01 09:39:28 +04:00
|
|
|
args->u.put.qc_key,
|
|
|
|
args->u.put.qc_val);
|
2012-02-01 09:34:38 +04:00
|
|
|
break;
|
|
|
|
case QUOTACTL_DELETE:
|
2012-02-01 09:39:28 +04:00
|
|
|
error = do_sys_quotactl_delete(mp, args->u.delete.qc_key);
|
2012-02-01 09:34:38 +04:00
|
|
|
break;
|
|
|
|
case QUOTACTL_CURSOROPEN:
|
|
|
|
error = do_sys_quotactl_cursoropen(mp,
|
2012-02-01 09:39:28 +04:00
|
|
|
args->u.cursoropen.qc_cursor);
|
2012-02-01 09:34:38 +04:00
|
|
|
break;
|
|
|
|
case QUOTACTL_CURSORCLOSE:
|
|
|
|
error = do_sys_quotactl_cursorclose(mp,
|
2012-02-01 09:39:28 +04:00
|
|
|
args->u.cursorclose.qc_cursor);
|
2012-02-01 09:34:38 +04:00
|
|
|
break;
|
|
|
|
case QUOTACTL_CURSORSKIPIDTYPE:
|
|
|
|
error = do_sys_quotactl_cursorskipidtype(mp,
|
2012-02-01 09:39:28 +04:00
|
|
|
args->u.cursorskipidtype.qc_cursor,
|
|
|
|
args->u.cursorskipidtype.qc_idtype);
|
2012-02-01 09:34:38 +04:00
|
|
|
break;
|
|
|
|
case QUOTACTL_CURSORGET:
|
|
|
|
error = do_sys_quotactl_cursorget(mp,
|
2012-02-01 09:39:28 +04:00
|
|
|
args->u.cursorget.qc_cursor,
|
|
|
|
args->u.cursorget.qc_keys,
|
|
|
|
args->u.cursorget.qc_vals,
|
|
|
|
args->u.cursorget.qc_maxnum,
|
|
|
|
args->u.cursorget.qc_ret);
|
2012-02-01 09:34:38 +04:00
|
|
|
break;
|
|
|
|
case QUOTACTL_CURSORATEND:
|
|
|
|
error = do_sys_quotactl_cursoratend(mp,
|
2012-02-01 09:39:28 +04:00
|
|
|
args->u.cursoratend.qc_cursor,
|
|
|
|
args->u.cursoratend.qc_ret);
|
2012-02-01 09:34:38 +04:00
|
|
|
break;
|
|
|
|
case QUOTACTL_CURSORREWIND:
|
|
|
|
error = do_sys_quotactl_cursorrewind(mp,
|
2012-02-01 09:39:28 +04:00
|
|
|
args->u.cursorrewind.qc_cursor);
|
2012-02-01 09:34:38 +04:00
|
|
|
break;
|
|
|
|
case QUOTACTL_QUOTAON:
|
|
|
|
error = do_sys_quotactl_quotaon(mp,
|
2012-02-01 09:39:28 +04:00
|
|
|
args->u.quotaon.qc_idtype,
|
|
|
|
args->u.quotaon.qc_quotafile);
|
2012-02-01 09:34:38 +04:00
|
|
|
break;
|
|
|
|
case QUOTACTL_QUOTAOFF:
|
|
|
|
error = do_sys_quotactl_quotaoff(mp,
|
2012-02-01 09:39:28 +04:00
|
|
|
args->u.quotaoff.qc_idtype);
|
2012-02-01 09:34:38 +04:00
|
|
|
break;
|
|
|
|
default:
|
|
|
|
error = EINVAL;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
Convert 67 namei call sites to use namei_simple, in these functions:
check_console, veriexecclose, veriexec_delete, veriexec_file_add,
emul_find_root, coff_load_shlib (sh3 version), coff_load_shlib,
compat_20_sys_statfs, compat_20_netbsd32_statfs,
ELFNAME2(netbsd32,probe_noteless), darwin_sys_statfs,
ibcs2_sys_statfs, ibcs2_sys_statvfs, linux_sys_uselib,
osf1_sys_statfs, sunos_sys_statfs, sunos32_sys_statfs,
ultrix_sys_statfs, do_sys_mount, fss_create_files (3 of 4),
adosfs_mount, cd9660_mount, coda_ioctl, coda_mount, ext2fs_mount,
ffs_mount, filecore_mount, hfs_mount, lfs_mount, msdosfs_mount,
ntfs_mount, sysvbfs_mount, udf_mount, union_mount, sys_chflags,
sys_lchflags, sys_chmod, sys_lchmod, sys_chown, sys_lchown,
sys___posix_chown, sys___posix_lchown, sys_link, do_sys_pstatvfs,
sys_quotactl, sys_revoke, sys_truncate, do_sys_utimes, sys_extattrctl,
sys_extattr_set_file, sys_extattr_set_link, sys_extattr_get_file,
sys_extattr_get_link, sys_extattr_delete_file,
sys_extattr_delete_link, sys_extattr_list_file, sys_extattr_list_link,
sys_setxattr, sys_lsetxattr, sys_getxattr, sys_lgetxattr,
sys_listxattr, sys_llistxattr, sys_removexattr, sys_lremovexattr
All have been scrutinized (several times, in fact) and compile-tested,
but not all have been explicitly tested in action.
XXX: While I haven't (intentionally) changed the use or nonuse of
XXX: TRYEMULROOT in any of these places, I'm not convinced all the
XXX: uses are correct; an audit might be desirable.
2009-06-29 09:08:15 +04:00
|
|
|
vrele(vp);
|
2012-02-01 09:34:38 +04:00
|
|
|
return error;
|
1994-06-29 10:29:24 +04:00
|
|
|
}
|
|
|
|
|
2012-02-01 09:39:28 +04:00
|
|
|
/* ARGSUSED */
|
|
|
|
int
|
|
|
|
sys___quotactl(struct lwp *l, const struct sys___quotactl_args *uap,
|
|
|
|
register_t *retval)
|
|
|
|
{
|
|
|
|
/* {
|
|
|
|
syscallarg(const char *) path;
|
|
|
|
syscallarg(struct quotactl_args *) args;
|
|
|
|
} */
|
|
|
|
struct quotactl_args args;
|
|
|
|
int error;
|
|
|
|
|
|
|
|
error = copyin(SCARG(uap, args), &args, sizeof(args));
|
|
|
|
if (error) {
|
|
|
|
return error;
|
|
|
|
}
|
|
|
|
|
|
|
|
return do_sys_quotactl(SCARG(uap, path), &args);
|
|
|
|
}
|
|
|
|
|
2004-04-21 05:05:31 +04:00
|
|
|
int
|
2005-12-11 15:16:03 +03:00
|
|
|
dostatvfs(struct mount *mp, struct statvfs *sp, struct lwp *l, int flags,
|
2003-04-17 01:44:18 +04:00
|
|
|
int root)
|
|
|
|
{
|
2005-12-11 15:16:03 +03:00
|
|
|
struct cwdinfo *cwdi = l->l_proc->p_cwdi;
|
2003-04-17 01:44:18 +04:00
|
|
|
int error = 0;
|
|
|
|
|
|
|
|
/*
|
|
|
|
* If MNT_NOWAIT or MNT_LAZY is specified, do not
|
2004-02-25 07:10:28 +03:00
|
|
|
* refresh the fsstat cache. MNT_WAIT or MNT_LAZY
|
2003-04-17 01:44:18 +04:00
|
|
|
* overrides MNT_NOWAIT.
|
|
|
|
*/
|
|
|
|
if (flags == MNT_NOWAIT || flags == MNT_LAZY ||
|
|
|
|
(flags != MNT_WAIT && flags != 0)) {
|
|
|
|
memcpy(sp, &mp->mnt_stat, sizeof(*sp));
|
|
|
|
goto done;
|
|
|
|
}
|
2004-03-23 16:22:32 +03:00
|
|
|
|
2004-09-14 00:02:20 +04:00
|
|
|
/* Get the filesystem stats now */
|
|
|
|
memset(sp, 0, sizeof(*sp));
|
2007-11-26 22:01:26 +03:00
|
|
|
if ((error = VFS_STATVFS(mp, sp)) != 0) {
|
2003-04-17 01:44:18 +04:00
|
|
|
return error;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (cwdi->cwdi_rdir == NULL)
|
|
|
|
(void)memcpy(&mp->mnt_stat, sp, sizeof(mp->mnt_stat));
|
|
|
|
done:
|
|
|
|
if (cwdi->cwdi_rdir != NULL) {
|
|
|
|
size_t len;
|
|
|
|
char *bp;
|
2008-05-26 06:29:13 +04:00
|
|
|
char c;
|
2006-02-04 15:09:50 +03:00
|
|
|
char *path = PNBUF_GET();
|
2003-04-17 01:44:18 +04:00
|
|
|
|
|
|
|
bp = path + MAXPATHLEN;
|
|
|
|
*--bp = '\0';
|
2007-10-08 19:12:05 +04:00
|
|
|
rw_enter(&cwdi->cwdi_lock, RW_READER);
|
2003-04-17 01:44:18 +04:00
|
|
|
error = getcwd_common(cwdi->cwdi_rdir, rootvnode, &bp, path,
|
2005-12-11 15:16:03 +03:00
|
|
|
MAXPATHLEN / 2, 0, l);
|
2007-10-08 19:12:05 +04:00
|
|
|
rw_exit(&cwdi->cwdi_lock);
|
2003-04-17 01:44:18 +04:00
|
|
|
if (error) {
|
2006-02-04 15:09:50 +03:00
|
|
|
PNBUF_PUT(path);
|
2003-04-17 01:44:18 +04:00
|
|
|
return error;
|
|
|
|
}
|
|
|
|
len = strlen(bp);
|
2009-02-14 20:06:35 +03:00
|
|
|
if (len != 1) {
|
|
|
|
/*
|
|
|
|
* for mount points that are below our root, we can see
|
|
|
|
* them, so we fix up the pathname and return them. The
|
|
|
|
* rest we cannot see, so we don't allow viewing the
|
|
|
|
* data.
|
|
|
|
*/
|
|
|
|
if (strncmp(bp, sp->f_mntonname, len) == 0 &&
|
|
|
|
((c = sp->f_mntonname[len]) == '/' || c == '\0')) {
|
|
|
|
(void)strlcpy(sp->f_mntonname,
|
2009-02-15 06:52:49 +03:00
|
|
|
c == '\0' ? "/" : &sp->f_mntonname[len],
|
2003-05-16 18:25:02 +04:00
|
|
|
sizeof(sp->f_mntonname));
|
2009-02-14 20:06:35 +03:00
|
|
|
} else {
|
|
|
|
if (root)
|
|
|
|
(void)strlcpy(sp->f_mntonname, "/",
|
|
|
|
sizeof(sp->f_mntonname));
|
|
|
|
else
|
|
|
|
error = EPERM;
|
|
|
|
}
|
2003-04-17 01:44:18 +04:00
|
|
|
}
|
2006-02-04 15:09:50 +03:00
|
|
|
PNBUF_PUT(path);
|
2003-04-17 01:44:18 +04:00
|
|
|
}
|
2004-04-21 05:05:31 +04:00
|
|
|
sp->f_flag = mp->mnt_flag & MNT_VISFLAGMASK;
|
2003-04-17 01:44:18 +04:00
|
|
|
return error;
|
|
|
|
}
|
|
|
|
|
1994-06-29 10:29:24 +04:00
|
|
|
/*
|
2007-04-30 12:32:14 +04:00
|
|
|
* Get filesystem statistics by path.
|
1994-06-29 10:29:24 +04:00
|
|
|
*/
|
2007-04-30 12:32:14 +04:00
|
|
|
int
|
|
|
|
do_sys_pstatvfs(struct lwp *l, const char *path, int flags, struct statvfs *sb)
|
|
|
|
{
|
|
|
|
struct mount *mp;
|
|
|
|
int error;
|
Convert 67 namei call sites to use namei_simple, in these functions:
check_console, veriexecclose, veriexec_delete, veriexec_file_add,
emul_find_root, coff_load_shlib (sh3 version), coff_load_shlib,
compat_20_sys_statfs, compat_20_netbsd32_statfs,
ELFNAME2(netbsd32,probe_noteless), darwin_sys_statfs,
ibcs2_sys_statfs, ibcs2_sys_statvfs, linux_sys_uselib,
osf1_sys_statfs, sunos_sys_statfs, sunos32_sys_statfs,
ultrix_sys_statfs, do_sys_mount, fss_create_files (3 of 4),
adosfs_mount, cd9660_mount, coda_ioctl, coda_mount, ext2fs_mount,
ffs_mount, filecore_mount, hfs_mount, lfs_mount, msdosfs_mount,
ntfs_mount, sysvbfs_mount, udf_mount, union_mount, sys_chflags,
sys_lchflags, sys_chmod, sys_lchmod, sys_chown, sys_lchown,
sys___posix_chown, sys___posix_lchown, sys_link, do_sys_pstatvfs,
sys_quotactl, sys_revoke, sys_truncate, do_sys_utimes, sys_extattrctl,
sys_extattr_set_file, sys_extattr_set_link, sys_extattr_get_file,
sys_extattr_get_link, sys_extattr_delete_file,
sys_extattr_delete_link, sys_extattr_list_file, sys_extattr_list_link,
sys_setxattr, sys_lsetxattr, sys_getxattr, sys_lgetxattr,
sys_listxattr, sys_llistxattr, sys_removexattr, sys_lremovexattr
All have been scrutinized (several times, in fact) and compile-tested,
but not all have been explicitly tested in action.
XXX: While I haven't (intentionally) changed the use or nonuse of
XXX: TRYEMULROOT in any of these places, I'm not convinced all the
XXX: uses are correct; an audit might be desirable.
2009-06-29 09:08:15 +04:00
|
|
|
struct vnode *vp;
|
2007-04-30 12:32:14 +04:00
|
|
|
|
Convert 67 namei call sites to use namei_simple, in these functions:
check_console, veriexecclose, veriexec_delete, veriexec_file_add,
emul_find_root, coff_load_shlib (sh3 version), coff_load_shlib,
compat_20_sys_statfs, compat_20_netbsd32_statfs,
ELFNAME2(netbsd32,probe_noteless), darwin_sys_statfs,
ibcs2_sys_statfs, ibcs2_sys_statvfs, linux_sys_uselib,
osf1_sys_statfs, sunos_sys_statfs, sunos32_sys_statfs,
ultrix_sys_statfs, do_sys_mount, fss_create_files (3 of 4),
adosfs_mount, cd9660_mount, coda_ioctl, coda_mount, ext2fs_mount,
ffs_mount, filecore_mount, hfs_mount, lfs_mount, msdosfs_mount,
ntfs_mount, sysvbfs_mount, udf_mount, union_mount, sys_chflags,
sys_lchflags, sys_chmod, sys_lchmod, sys_chown, sys_lchown,
sys___posix_chown, sys___posix_lchown, sys_link, do_sys_pstatvfs,
sys_quotactl, sys_revoke, sys_truncate, do_sys_utimes, sys_extattrctl,
sys_extattr_set_file, sys_extattr_set_link, sys_extattr_get_file,
sys_extattr_get_link, sys_extattr_delete_file,
sys_extattr_delete_link, sys_extattr_list_file, sys_extattr_list_link,
sys_setxattr, sys_lsetxattr, sys_getxattr, sys_lgetxattr,
sys_listxattr, sys_llistxattr, sys_removexattr, sys_lremovexattr
All have been scrutinized (several times, in fact) and compile-tested,
but not all have been explicitly tested in action.
XXX: While I haven't (intentionally) changed the use or nonuse of
XXX: TRYEMULROOT in any of these places, I'm not convinced all the
XXX: uses are correct; an audit might be desirable.
2009-06-29 09:08:15 +04:00
|
|
|
error = namei_simple_user(path, NSM_FOLLOW_TRYEMULROOT, &vp);
|
|
|
|
if (error != 0)
|
2007-04-30 12:32:14 +04:00
|
|
|
return error;
|
Convert 67 namei call sites to use namei_simple, in these functions:
check_console, veriexecclose, veriexec_delete, veriexec_file_add,
emul_find_root, coff_load_shlib (sh3 version), coff_load_shlib,
compat_20_sys_statfs, compat_20_netbsd32_statfs,
ELFNAME2(netbsd32,probe_noteless), darwin_sys_statfs,
ibcs2_sys_statfs, ibcs2_sys_statvfs, linux_sys_uselib,
osf1_sys_statfs, sunos_sys_statfs, sunos32_sys_statfs,
ultrix_sys_statfs, do_sys_mount, fss_create_files (3 of 4),
adosfs_mount, cd9660_mount, coda_ioctl, coda_mount, ext2fs_mount,
ffs_mount, filecore_mount, hfs_mount, lfs_mount, msdosfs_mount,
ntfs_mount, sysvbfs_mount, udf_mount, union_mount, sys_chflags,
sys_lchflags, sys_chmod, sys_lchmod, sys_chown, sys_lchown,
sys___posix_chown, sys___posix_lchown, sys_link, do_sys_pstatvfs,
sys_quotactl, sys_revoke, sys_truncate, do_sys_utimes, sys_extattrctl,
sys_extattr_set_file, sys_extattr_set_link, sys_extattr_get_file,
sys_extattr_get_link, sys_extattr_delete_file,
sys_extattr_delete_link, sys_extattr_list_file, sys_extattr_list_link,
sys_setxattr, sys_lsetxattr, sys_getxattr, sys_lgetxattr,
sys_listxattr, sys_llistxattr, sys_removexattr, sys_lremovexattr
All have been scrutinized (several times, in fact) and compile-tested,
but not all have been explicitly tested in action.
XXX: While I haven't (intentionally) changed the use or nonuse of
XXX: TRYEMULROOT in any of these places, I'm not convinced all the
XXX: uses are correct; an audit might be desirable.
2009-06-29 09:08:15 +04:00
|
|
|
mp = vp->v_mount;
|
2007-04-30 12:32:14 +04:00
|
|
|
error = dostatvfs(mp, sb, l, flags, 1);
|
Convert 67 namei call sites to use namei_simple, in these functions:
check_console, veriexecclose, veriexec_delete, veriexec_file_add,
emul_find_root, coff_load_shlib (sh3 version), coff_load_shlib,
compat_20_sys_statfs, compat_20_netbsd32_statfs,
ELFNAME2(netbsd32,probe_noteless), darwin_sys_statfs,
ibcs2_sys_statfs, ibcs2_sys_statvfs, linux_sys_uselib,
osf1_sys_statfs, sunos_sys_statfs, sunos32_sys_statfs,
ultrix_sys_statfs, do_sys_mount, fss_create_files (3 of 4),
adosfs_mount, cd9660_mount, coda_ioctl, coda_mount, ext2fs_mount,
ffs_mount, filecore_mount, hfs_mount, lfs_mount, msdosfs_mount,
ntfs_mount, sysvbfs_mount, udf_mount, union_mount, sys_chflags,
sys_lchflags, sys_chmod, sys_lchmod, sys_chown, sys_lchown,
sys___posix_chown, sys___posix_lchown, sys_link, do_sys_pstatvfs,
sys_quotactl, sys_revoke, sys_truncate, do_sys_utimes, sys_extattrctl,
sys_extattr_set_file, sys_extattr_set_link, sys_extattr_get_file,
sys_extattr_get_link, sys_extattr_delete_file,
sys_extattr_delete_link, sys_extattr_list_file, sys_extattr_list_link,
sys_setxattr, sys_lsetxattr, sys_getxattr, sys_lgetxattr,
sys_listxattr, sys_llistxattr, sys_removexattr, sys_lremovexattr
All have been scrutinized (several times, in fact) and compile-tested,
but not all have been explicitly tested in action.
XXX: While I haven't (intentionally) changed the use or nonuse of
XXX: TRYEMULROOT in any of these places, I'm not convinced all the
XXX: uses are correct; an audit might be desirable.
2009-06-29 09:08:15 +04:00
|
|
|
vrele(vp);
|
2007-04-30 12:32:14 +04:00
|
|
|
return error;
|
|
|
|
}
|
|
|
|
|
1994-06-29 10:29:24 +04:00
|
|
|
/* ARGSUSED */
|
1996-02-04 05:17:43 +03:00
|
|
|
int
|
2007-12-21 02:02:38 +03:00
|
|
|
sys_statvfs1(struct lwp *l, const struct sys_statvfs1_args *uap, register_t *retval)
|
1995-09-20 01:40:36 +04:00
|
|
|
{
|
2007-12-21 02:02:38 +03:00
|
|
|
/* {
|
1996-12-22 13:21:06 +03:00
|
|
|
syscallarg(const char *) path;
|
2004-04-21 05:05:31 +04:00
|
|
|
syscallarg(struct statvfs *) buf;
|
|
|
|
syscallarg(int) flags;
|
2007-12-21 02:02:38 +03:00
|
|
|
} */
|
2006-05-10 15:02:29 +04:00
|
|
|
struct statvfs *sb;
|
1994-06-29 10:29:24 +04:00
|
|
|
int error;
|
|
|
|
|
2006-05-10 15:02:29 +04:00
|
|
|
sb = STATVFSBUF_GET();
|
2007-04-30 12:32:14 +04:00
|
|
|
error = do_sys_pstatvfs(l, SCARG(uap, path), SCARG(uap, flags), sb);
|
|
|
|
if (error == 0)
|
2006-05-10 15:02:29 +04:00
|
|
|
error = copyout(sb, SCARG(uap, buf), sizeof(*sb));
|
|
|
|
STATVFSBUF_PUT(sb);
|
|
|
|
return error;
|
1994-06-29 10:29:24 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
2007-04-30 12:32:14 +04:00
|
|
|
* Get filesystem statistics by fd.
|
1994-06-29 10:29:24 +04:00
|
|
|
*/
|
2007-04-30 12:32:14 +04:00
|
|
|
int
|
|
|
|
do_sys_fstatvfs(struct lwp *l, int fd, int flags, struct statvfs *sb)
|
|
|
|
{
|
2008-03-22 00:54:58 +03:00
|
|
|
file_t *fp;
|
2007-04-30 12:32:14 +04:00
|
|
|
struct mount *mp;
|
|
|
|
int error;
|
|
|
|
|
2008-03-22 00:54:58 +03:00
|
|
|
/* fd_getvnode() will use the descriptor for us */
|
|
|
|
if ((error = fd_getvnode(fd, &fp)) != 0)
|
2007-04-30 12:32:14 +04:00
|
|
|
return (error);
|
|
|
|
mp = ((struct vnode *)fp->f_data)->v_mount;
|
2008-03-22 00:54:58 +03:00
|
|
|
error = dostatvfs(mp, sb, curlwp, flags, 1);
|
|
|
|
fd_putfile(fd);
|
2007-04-30 12:32:14 +04:00
|
|
|
return error;
|
|
|
|
}
|
|
|
|
|
1994-06-29 10:29:24 +04:00
|
|
|
/* ARGSUSED */
|
1996-02-04 05:17:43 +03:00
|
|
|
int
|
2007-12-21 02:02:38 +03:00
|
|
|
sys_fstatvfs1(struct lwp *l, const struct sys_fstatvfs1_args *uap, register_t *retval)
|
1995-09-20 01:40:36 +04:00
|
|
|
{
|
2007-12-21 02:02:38 +03:00
|
|
|
/* {
|
1994-10-20 07:22:35 +03:00
|
|
|
syscallarg(int) fd;
|
2004-04-21 05:05:31 +04:00
|
|
|
syscallarg(struct statvfs *) buf;
|
|
|
|
syscallarg(int) flags;
|
2007-12-21 02:02:38 +03:00
|
|
|
} */
|
2006-05-10 15:02:29 +04:00
|
|
|
struct statvfs *sb;
|
1994-06-29 10:29:24 +04:00
|
|
|
int error;
|
|
|
|
|
2006-05-10 15:02:29 +04:00
|
|
|
sb = STATVFSBUF_GET();
|
2007-04-30 12:32:14 +04:00
|
|
|
error = do_sys_fstatvfs(l, SCARG(uap, fd), SCARG(uap, flags), sb);
|
2007-05-21 22:30:35 +04:00
|
|
|
if (error == 0)
|
2007-04-30 12:32:14 +04:00
|
|
|
error = copyout(sb, SCARG(uap, buf), sizeof(*sb));
|
2006-05-10 15:02:29 +04:00
|
|
|
STATVFSBUF_PUT(sb);
|
2003-04-17 01:44:18 +04:00
|
|
|
return error;
|
1994-06-29 10:29:24 +04:00
|
|
|
}
|
|
|
|
|
2003-04-17 01:44:18 +04:00
|
|
|
|
1994-06-29 10:29:24 +04:00
|
|
|
/*
|
|
|
|
* Get statistics on all filesystems.
|
|
|
|
*/
|
1996-02-04 05:17:43 +03:00
|
|
|
int
|
2007-04-30 12:32:14 +04:00
|
|
|
do_sys_getvfsstat(struct lwp *l, void *sfsp, size_t bufsize, int flags,
|
|
|
|
int (*copyfn)(const void *, void *, size_t), size_t entry_sz,
|
|
|
|
register_t *retval)
|
1995-09-20 01:40:36 +04:00
|
|
|
{
|
2003-04-17 01:44:18 +04:00
|
|
|
int root = 0;
|
2003-01-18 13:06:22 +03:00
|
|
|
struct proc *p = l->l_proc;
|
2000-03-30 13:27:11 +04:00
|
|
|
struct mount *mp, *nmp;
|
2006-05-10 15:02:29 +04:00
|
|
|
struct statvfs *sb;
|
2004-04-21 05:05:31 +04:00
|
|
|
size_t count, maxcount;
|
|
|
|
int error = 0;
|
1994-06-29 10:29:24 +04:00
|
|
|
|
2006-05-10 15:02:29 +04:00
|
|
|
sb = STATVFSBUF_GET();
|
2007-04-30 12:32:14 +04:00
|
|
|
maxcount = bufsize / entry_sz;
|
2007-10-11 00:42:20 +04:00
|
|
|
mutex_enter(&mountlist_lock);
|
1998-03-01 05:20:01 +03:00
|
|
|
count = 0;
|
2002-09-04 05:32:31 +04:00
|
|
|
for (mp = CIRCLEQ_FIRST(&mountlist); mp != (void *)&mountlist;
|
|
|
|
mp = nmp) {
|
PR kern/38141 lookup/vfs_busy acquire rwlock recursively
Simplify the mount locking. Remove all the crud to deal with recursion on
the mount lock, and crud to deal with unmount as another weirdo lock.
Hopefully this will once and for all fix the deadlocks with this. With this
commit there are two locks on each mount:
- krwlock_t mnt_unmounting. This is used to prevent unmount across critical
sections like getnewvnode(). It's only ever read locked with rw_tryenter(),
and is only ever write locked in dounmount(). A write hold can't be taken
on this lock if the current LWP could hold a vnode lock.
- kmutex_t mnt_updating. This is taken by threads updating the mount, for
example when going r/o -> r/w, and is only present to serialize updates.
In order to take this lock, a read hold must first be taken on
mnt_unmounting, and the two need to be held across the operation.
One effect of this change: previously if an unmount failed, we would make a
half hearted attempt to back out of it gracefully, but that was unlikely to
work in a lot of cases. Now while an unmount that will be aborted is in
progress, new file operations within the mount will fail instead of being
delayed. That is unlikely to be a problem though, because if the admin
requests unmount of a file system then s(he) has made a decision to deny
access to the resource.
2008-05-06 22:43:44 +04:00
|
|
|
if (vfs_busy(mp, &nmp)) {
|
1998-03-01 05:20:01 +03:00
|
|
|
continue;
|
|
|
|
}
|
|
|
|
if (sfsp && count < maxcount) {
|
2007-04-30 12:32:14 +04:00
|
|
|
error = dostatvfs(mp, sb, l, flags, 0);
|
2003-04-17 01:44:18 +04:00
|
|
|
if (error) {
|
2008-04-30 16:49:16 +04:00
|
|
|
vfs_unbusy(mp, false, &nmp);
|
2008-05-26 22:20:36 +04:00
|
|
|
error = 0;
|
1994-06-29 10:29:24 +04:00
|
|
|
continue;
|
1998-03-01 05:20:01 +03:00
|
|
|
}
|
2007-04-30 12:32:14 +04:00
|
|
|
error = copyfn(sb, sfsp, entry_sz);
|
1999-03-31 23:18:45 +04:00
|
|
|
if (error) {
|
2008-04-30 16:49:16 +04:00
|
|
|
vfs_unbusy(mp, false, NULL);
|
2006-05-10 15:02:29 +04:00
|
|
|
goto out;
|
1999-03-31 23:18:45 +04:00
|
|
|
}
|
2007-04-30 12:32:14 +04:00
|
|
|
sfsp = (char *)sfsp + entry_sz;
|
2006-05-10 15:02:29 +04:00
|
|
|
root |= strcmp(sb->f_mntonname, "/") == 0;
|
1994-06-29 10:29:24 +04:00
|
|
|
}
|
|
|
|
count++;
|
2008-04-30 16:49:16 +04:00
|
|
|
vfs_unbusy(mp, false, &nmp);
|
1994-06-29 10:29:24 +04:00
|
|
|
}
|
2007-10-11 00:42:20 +04:00
|
|
|
mutex_exit(&mountlist_lock);
|
PR kern/38141 lookup/vfs_busy acquire rwlock recursively
Simplify the mount locking. Remove all the crud to deal with recursion on
the mount lock, and crud to deal with unmount as another weirdo lock.
Hopefully this will once and for all fix the deadlocks with this. With this
commit there are two locks on each mount:
- krwlock_t mnt_unmounting. This is used to prevent unmount across critical
sections like getnewvnode(). It's only ever read locked with rw_tryenter(),
and is only ever write locked in dounmount(). A write hold can't be taken
on this lock if the current LWP could hold a vnode lock.
- kmutex_t mnt_updating. This is taken by threads updating the mount, for
example when going r/o -> r/w, and is only present to serialize updates.
In order to take this lock, a read hold must first be taken on
mnt_unmounting, and the two need to be held across the operation.
One effect of this change: previously if an unmount failed, we would make a
half hearted attempt to back out of it gracefully, but that was unlikely to
work in a lot of cases. Now while an unmount that will be aborted is in
progress, new file operations within the mount will fail instead of being
delayed. That is unlikely to be a problem though, because if the admin
requests unmount of a file system then s(he) has made a decision to deny
access to the resource.
2008-05-06 22:43:44 +04:00
|
|
|
|
2003-04-17 01:44:18 +04:00
|
|
|
if (root == 0 && p->p_cwdi->cwdi_rdir) {
|
|
|
|
/*
|
|
|
|
* fake a root entry
|
|
|
|
*/
|
2007-10-24 19:28:55 +04:00
|
|
|
error = dostatvfs(p->p_cwdi->cwdi_rdir->v_mount,
|
|
|
|
sb, l, flags, 1);
|
2007-04-30 12:32:14 +04:00
|
|
|
if (error != 0)
|
2006-05-10 15:02:29 +04:00
|
|
|
goto out;
|
2008-05-26 22:20:36 +04:00
|
|
|
if (sfsp) {
|
2007-04-30 12:32:14 +04:00
|
|
|
error = copyfn(sb, sfsp, entry_sz);
|
2008-05-26 22:20:36 +04:00
|
|
|
if (error != 0)
|
|
|
|
goto out;
|
|
|
|
}
|
2003-04-17 01:44:18 +04:00
|
|
|
count++;
|
|
|
|
}
|
1994-06-29 10:29:24 +04:00
|
|
|
if (sfsp && count > maxcount)
|
|
|
|
*retval = maxcount;
|
|
|
|
else
|
|
|
|
*retval = count;
|
2006-05-10 15:02:29 +04:00
|
|
|
out:
|
|
|
|
STATVFSBUF_PUT(sb);
|
2003-04-17 01:44:18 +04:00
|
|
|
return error;
|
1994-06-29 10:29:24 +04:00
|
|
|
}
|
|
|
|
|
2007-04-30 12:32:14 +04:00
|
|
|
int
|
2007-12-21 02:02:38 +03:00
|
|
|
sys_getvfsstat(struct lwp *l, const struct sys_getvfsstat_args *uap, register_t *retval)
|
2007-04-30 12:32:14 +04:00
|
|
|
{
|
2007-12-21 02:02:38 +03:00
|
|
|
/* {
|
2007-04-30 12:32:14 +04:00
|
|
|
syscallarg(struct statvfs *) buf;
|
|
|
|
syscallarg(size_t) bufsize;
|
|
|
|
syscallarg(int) flags;
|
2007-12-21 02:02:38 +03:00
|
|
|
} */
|
2007-04-30 12:32:14 +04:00
|
|
|
|
|
|
|
return do_sys_getvfsstat(l, SCARG(uap, buf), SCARG(uap, bufsize),
|
|
|
|
SCARG(uap, flags), copyout, sizeof (struct statvfs), retval);
|
|
|
|
}
|
|
|
|
|
1994-06-29 10:29:24 +04:00
|
|
|
/*
|
|
|
|
* Change current working directory to a given file descriptor.
|
|
|
|
*/
|
|
|
|
/* ARGSUSED */
|
1996-02-04 05:17:43 +03:00
|
|
|
int
|
2007-12-21 02:02:38 +03:00
|
|
|
sys_fchdir(struct lwp *l, const struct sys_fchdir_args *uap, register_t *retval)
|
1994-06-29 10:29:24 +04:00
|
|
|
{
|
2007-12-21 02:02:38 +03:00
|
|
|
/* {
|
1995-09-20 01:40:36 +04:00
|
|
|
syscallarg(int) fd;
|
2007-12-21 02:02:38 +03:00
|
|
|
} */
|
2003-01-18 13:06:22 +03:00
|
|
|
struct proc *p = l->l_proc;
|
2007-10-08 19:12:05 +04:00
|
|
|
struct cwdinfo *cwdi;
|
1994-12-14 19:30:40 +03:00
|
|
|
struct vnode *vp, *tdp;
|
|
|
|
struct mount *mp;
|
2008-03-22 00:54:58 +03:00
|
|
|
file_t *fp;
|
|
|
|
int error, fd;
|
1994-06-29 10:29:24 +04:00
|
|
|
|
2008-03-22 00:54:58 +03:00
|
|
|
/* fd_getvnode() will use the descriptor for us */
|
|
|
|
fd = SCARG(uap, fd);
|
|
|
|
if ((error = fd_getvnode(fd, &fp)) != 0)
|
1994-06-29 10:29:24 +04:00
|
|
|
return (error);
|
2008-03-22 00:54:58 +03:00
|
|
|
vp = fp->f_data;
|
1999-03-22 20:13:34 +03:00
|
|
|
|
2010-01-08 14:35:07 +03:00
|
|
|
vref(vp);
|
1998-03-01 05:20:01 +03:00
|
|
|
vn_lock(vp, LK_EXCLUSIVE | LK_RETRY);
|
1994-06-29 10:29:24 +04:00
|
|
|
if (vp->v_type != VDIR)
|
|
|
|
error = ENOTDIR;
|
|
|
|
else
|
2007-11-26 22:01:26 +03:00
|
|
|
error = VOP_ACCESS(vp, VEXEC, l->l_cred);
|
2007-02-28 23:39:06 +03:00
|
|
|
if (error) {
|
|
|
|
vput(vp);
|
|
|
|
goto out;
|
|
|
|
}
|
2007-03-01 13:02:31 +03:00
|
|
|
while ((mp = vp->v_mountedhere) != NULL) {
|
PR kern/38141 lookup/vfs_busy acquire rwlock recursively
Simplify the mount locking. Remove all the crud to deal with recursion on
the mount lock, and crud to deal with unmount as another weirdo lock.
Hopefully this will once and for all fix the deadlocks with this. With this
commit there are two locks on each mount:
- krwlock_t mnt_unmounting. This is used to prevent unmount across critical
sections like getnewvnode(). It's only ever read locked with rw_tryenter(),
and is only ever write locked in dounmount(). A write hold can't be taken
on this lock if the current LWP could hold a vnode lock.
- kmutex_t mnt_updating. This is taken by threads updating the mount, for
example when going r/o -> r/w, and is only present to serialize updates.
In order to take this lock, a read hold must first be taken on
mnt_unmounting, and the two need to be held across the operation.
One effect of this change: previously if an unmount failed, we would make a
half hearted attempt to back out of it gracefully, but that was unlikely to
work in a lot of cases. Now while an unmount that will be aborted is in
progress, new file operations within the mount will fail instead of being
delayed. That is unlikely to be a problem though, because if the admin
requests unmount of a file system then s(he) has made a decision to deny
access to the resource.
2008-05-06 22:43:44 +04:00
|
|
|
error = vfs_busy(mp, NULL);
|
2007-02-04 18:03:20 +03:00
|
|
|
vput(vp);
|
2008-05-06 17:31:02 +04:00
|
|
|
if (error != 0)
|
2008-05-06 16:54:25 +04:00
|
|
|
goto out;
|
2003-06-29 22:43:21 +04:00
|
|
|
error = VFS_ROOT(mp, &tdp);
|
2008-04-30 16:49:16 +04:00
|
|
|
vfs_unbusy(mp, false, NULL);
|
1998-03-01 05:20:01 +03:00
|
|
|
if (error)
|
2007-02-28 23:39:06 +03:00
|
|
|
goto out;
|
1994-12-14 19:30:40 +03:00
|
|
|
vp = tdp;
|
|
|
|
}
|
2010-06-24 16:58:48 +04:00
|
|
|
VOP_UNLOCK(vp);
|
1999-03-22 20:13:34 +03:00
|
|
|
|
|
|
|
/*
|
|
|
|
* Disallow changing to a directory not under the process's
|
|
|
|
* current root directory (if there is one).
|
|
|
|
*/
|
2007-10-08 19:12:05 +04:00
|
|
|
cwdi = p->p_cwdi;
|
|
|
|
rw_enter(&cwdi->cwdi_lock, RW_WRITER);
|
2005-12-11 15:16:03 +03:00
|
|
|
if (cwdi->cwdi_rdir && !vn_isunder(vp, NULL, l)) {
|
1999-03-22 20:13:34 +03:00
|
|
|
vrele(vp);
|
1999-05-06 00:01:01 +04:00
|
|
|
error = EPERM; /* operation not permitted */
|
2007-10-08 19:12:05 +04:00
|
|
|
} else {
|
|
|
|
vrele(cwdi->cwdi_cdir);
|
|
|
|
cwdi->cwdi_cdir = vp;
|
1999-03-22 20:13:34 +03:00
|
|
|
}
|
2007-10-08 19:12:05 +04:00
|
|
|
rw_exit(&cwdi->cwdi_lock);
|
2004-03-23 16:22:32 +03:00
|
|
|
|
1999-05-06 00:01:01 +04:00
|
|
|
out:
|
2008-03-22 00:54:58 +03:00
|
|
|
fd_putfile(fd);
|
1999-05-06 00:01:01 +04:00
|
|
|
return (error);
|
1994-06-29 10:29:24 +04:00
|
|
|
}
|
|
|
|
|
1999-03-22 20:13:34 +03:00
|
|
|
/*
|
2005-06-06 03:47:48 +04:00
|
|
|
* Change this process's notion of the root directory to a given file
|
|
|
|
* descriptor.
|
1999-03-22 20:13:34 +03:00
|
|
|
*/
|
|
|
|
int
|
2007-12-21 02:02:38 +03:00
|
|
|
sys_fchroot(struct lwp *l, const struct sys_fchroot_args *uap, register_t *retval)
|
1999-03-22 20:13:34 +03:00
|
|
|
{
|
2003-01-18 13:06:22 +03:00
|
|
|
struct proc *p = l->l_proc;
|
1999-03-22 20:13:34 +03:00
|
|
|
struct vnode *vp;
|
2008-03-22 00:54:58 +03:00
|
|
|
file_t *fp;
|
|
|
|
int error, fd = SCARG(uap, fd);
|
1999-03-22 20:13:34 +03:00
|
|
|
|
First take at security model abstraction.
- Add a few scopes to the kernel: system, network, and machdep.
- Add a few more actions/sub-actions (requests), and start using them as
opposed to the KAUTH_GENERIC_ISSUSER place-holders.
- Introduce a basic set of listeners that implement our "traditional"
security model, called "bsd44". This is the default (and only) model we
have at the moment.
- Update all relevant documentation.
- Add some code and docs to help folks who want to actually use this stuff:
* There's a sample overlay model, sitting on-top of "bsd44", for
fast experimenting with tweaking just a subset of an existing model.
This is pretty cool because it's *really* straightforward to do stuff
you had to use ugly hacks for until now...
* And of course, documentation describing how to do the above for quick
reference, including code samples.
All of these changes were tested for regressions using a Python-based
testsuite that will be (I hope) available soon via pkgsrc. Information
about the tests, and how to write new ones, can be found on:
http://kauth.linbsd.org/kauthwiki
NOTE FOR DEVELOPERS: *PLEASE* don't add any code that does any of the
following:
- Uses a KAUTH_GENERIC_ISSUSER kauth(9) request,
- Checks 'securelevel' directly,
- Checks a uid/gid directly.
(or if you feel you have to, contact me first)
This is still work in progress; It's far from being done, but now it'll
be a lot easier.
Relevant mailing list threads:
http://mail-index.netbsd.org/tech-security/2006/01/25/0011.html
http://mail-index.netbsd.org/tech-security/2006/03/24/0001.html
http://mail-index.netbsd.org/tech-security/2006/04/18/0000.html
http://mail-index.netbsd.org/tech-security/2006/05/15/0000.html
http://mail-index.netbsd.org/tech-security/2006/08/01/0000.html
http://mail-index.netbsd.org/tech-security/2006/08/25/0000.html
Many thanks to YAMAMOTO Takashi, Matt Thomas, and Christos Zoulas for help
stablizing kauth(9).
Full credit for the regression tests, making sure these changes didn't break
anything, goes to Matt Fleming and Jaime Fournier.
Happy birthday Randi! :)
2006-09-09 00:58:56 +04:00
|
|
|
if ((error = kauth_authorize_system(l->l_cred, KAUTH_SYSTEM_CHROOT,
|
|
|
|
KAUTH_REQ_SYSTEM_CHROOT_FCHROOT, NULL, NULL, NULL)) != 0)
|
1999-03-22 20:13:34 +03:00
|
|
|
return error;
|
2008-03-22 00:54:58 +03:00
|
|
|
/* fd_getvnode() will use the descriptor for us */
|
2009-08-02 01:17:11 +04:00
|
|
|
if ((error = fd_getvnode(fd, &fp)) != 0)
|
1999-03-22 20:13:34 +03:00
|
|
|
return error;
|
2008-03-22 00:54:58 +03:00
|
|
|
vp = fp->f_data;
|
1999-03-22 20:13:34 +03:00
|
|
|
vn_lock(vp, LK_EXCLUSIVE | LK_RETRY);
|
|
|
|
if (vp->v_type != VDIR)
|
|
|
|
error = ENOTDIR;
|
|
|
|
else
|
2007-11-26 22:01:26 +03:00
|
|
|
error = VOP_ACCESS(vp, VEXEC, l->l_cred);
|
2010-06-24 16:58:48 +04:00
|
|
|
VOP_UNLOCK(vp);
|
1999-03-22 20:13:34 +03:00
|
|
|
if (error)
|
1999-05-06 00:01:01 +04:00
|
|
|
goto out;
|
2010-01-08 14:35:07 +03:00
|
|
|
vref(vp);
|
1999-03-22 20:13:34 +03:00
|
|
|
|
2009-08-02 01:17:11 +04:00
|
|
|
change_root(p->p_cwdi, vp, l);
|
2007-10-08 19:12:05 +04:00
|
|
|
|
1999-05-06 00:01:01 +04:00
|
|
|
out:
|
2008-03-22 00:54:58 +03:00
|
|
|
fd_putfile(fd);
|
1999-05-06 00:01:01 +04:00
|
|
|
return (error);
|
1999-03-22 20:13:34 +03:00
|
|
|
}
|
|
|
|
|
1994-06-29 10:29:24 +04:00
|
|
|
/*
|
|
|
|
* Change current working directory (``.'').
|
|
|
|
*/
|
|
|
|
/* ARGSUSED */
|
1996-02-04 05:17:43 +03:00
|
|
|
int
|
2007-12-21 02:02:38 +03:00
|
|
|
sys_chdir(struct lwp *l, const struct sys_chdir_args *uap, register_t *retval)
|
1994-06-29 10:29:24 +04:00
|
|
|
{
|
2007-12-21 02:02:38 +03:00
|
|
|
/* {
|
1996-12-22 13:21:06 +03:00
|
|
|
syscallarg(const char *) path;
|
2007-12-21 02:02:38 +03:00
|
|
|
} */
|
2003-01-18 13:06:22 +03:00
|
|
|
struct proc *p = l->l_proc;
|
2007-10-08 19:12:05 +04:00
|
|
|
struct cwdinfo *cwdi;
|
1994-06-29 10:29:24 +04:00
|
|
|
int error;
|
2009-08-02 01:17:11 +04:00
|
|
|
struct vnode *vp;
|
1994-06-29 10:29:24 +04:00
|
|
|
|
2009-08-02 01:17:11 +04:00
|
|
|
if ((error = chdir_lookup(SCARG(uap, path), UIO_USERSPACE,
|
|
|
|
&vp, l)) != 0)
|
1994-06-29 10:29:24 +04:00
|
|
|
return (error);
|
2007-10-08 19:12:05 +04:00
|
|
|
cwdi = p->p_cwdi;
|
|
|
|
rw_enter(&cwdi->cwdi_lock, RW_WRITER);
|
1999-04-30 22:42:58 +04:00
|
|
|
vrele(cwdi->cwdi_cdir);
|
2009-08-02 01:17:11 +04:00
|
|
|
cwdi->cwdi_cdir = vp;
|
2007-10-08 19:12:05 +04:00
|
|
|
rw_exit(&cwdi->cwdi_lock);
|
1994-06-29 10:29:24 +04:00
|
|
|
return (0);
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Change notion of root (``/'') directory.
|
|
|
|
*/
|
|
|
|
/* ARGSUSED */
|
1996-02-04 05:17:43 +03:00
|
|
|
int
|
2007-12-21 02:02:38 +03:00
|
|
|
sys_chroot(struct lwp *l, const struct sys_chroot_args *uap, register_t *retval)
|
1994-06-29 10:29:24 +04:00
|
|
|
{
|
2007-12-21 02:02:38 +03:00
|
|
|
/* {
|
1996-12-22 13:21:06 +03:00
|
|
|
syscallarg(const char *) path;
|
2007-12-21 02:02:38 +03:00
|
|
|
} */
|
2003-01-18 13:06:22 +03:00
|
|
|
struct proc *p = l->l_proc;
|
1994-06-29 10:29:24 +04:00
|
|
|
int error;
|
2009-08-02 01:17:11 +04:00
|
|
|
struct vnode *vp;
|
1994-06-29 10:29:24 +04:00
|
|
|
|
First take at security model abstraction.
- Add a few scopes to the kernel: system, network, and machdep.
- Add a few more actions/sub-actions (requests), and start using them as
opposed to the KAUTH_GENERIC_ISSUSER place-holders.
- Introduce a basic set of listeners that implement our "traditional"
security model, called "bsd44". This is the default (and only) model we
have at the moment.
- Update all relevant documentation.
- Add some code and docs to help folks who want to actually use this stuff:
* There's a sample overlay model, sitting on-top of "bsd44", for
fast experimenting with tweaking just a subset of an existing model.
This is pretty cool because it's *really* straightforward to do stuff
you had to use ugly hacks for until now...
* And of course, documentation describing how to do the above for quick
reference, including code samples.
All of these changes were tested for regressions using a Python-based
testsuite that will be (I hope) available soon via pkgsrc. Information
about the tests, and how to write new ones, can be found on:
http://kauth.linbsd.org/kauthwiki
NOTE FOR DEVELOPERS: *PLEASE* don't add any code that does any of the
following:
- Uses a KAUTH_GENERIC_ISSUSER kauth(9) request,
- Checks 'securelevel' directly,
- Checks a uid/gid directly.
(or if you feel you have to, contact me first)
This is still work in progress; It's far from being done, but now it'll
be a lot easier.
Relevant mailing list threads:
http://mail-index.netbsd.org/tech-security/2006/01/25/0011.html
http://mail-index.netbsd.org/tech-security/2006/03/24/0001.html
http://mail-index.netbsd.org/tech-security/2006/04/18/0000.html
http://mail-index.netbsd.org/tech-security/2006/05/15/0000.html
http://mail-index.netbsd.org/tech-security/2006/08/01/0000.html
http://mail-index.netbsd.org/tech-security/2006/08/25/0000.html
Many thanks to YAMAMOTO Takashi, Matt Thomas, and Christos Zoulas for help
stablizing kauth(9).
Full credit for the regression tests, making sure these changes didn't break
anything, goes to Matt Fleming and Jaime Fournier.
Happy birthday Randi! :)
2006-09-09 00:58:56 +04:00
|
|
|
if ((error = kauth_authorize_system(l->l_cred, KAUTH_SYSTEM_CHROOT,
|
|
|
|
KAUTH_REQ_SYSTEM_CHROOT_CHROOT, NULL, NULL, NULL)) != 0)
|
1994-06-29 10:29:24 +04:00
|
|
|
return (error);
|
2009-08-02 01:17:11 +04:00
|
|
|
if ((error = chdir_lookup(SCARG(uap, path), UIO_USERSPACE,
|
|
|
|
&vp, l)) != 0)
|
1994-06-29 10:29:24 +04:00
|
|
|
return (error);
|
2007-10-08 19:12:05 +04:00
|
|
|
|
2009-08-02 01:17:11 +04:00
|
|
|
change_root(p->p_cwdi, vp, l);
|
|
|
|
|
|
|
|
return (0);
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Common routine for chroot and fchroot.
|
2009-08-03 00:44:55 +04:00
|
|
|
* NB: callers need to properly authorize the change root operation.
|
2009-08-02 01:17:11 +04:00
|
|
|
*/
|
|
|
|
void
|
|
|
|
change_root(struct cwdinfo *cwdi, struct vnode *vp, struct lwp *l)
|
|
|
|
{
|
2012-06-27 16:28:28 +04:00
|
|
|
struct proc *p = l->l_proc;
|
|
|
|
kauth_cred_t ncred;
|
|
|
|
|
|
|
|
ncred = kauth_cred_alloc();
|
2009-08-02 01:17:11 +04:00
|
|
|
|
2007-10-08 19:12:05 +04:00
|
|
|
rw_enter(&cwdi->cwdi_lock, RW_WRITER);
|
1999-04-30 22:42:58 +04:00
|
|
|
if (cwdi->cwdi_rdir != NULL)
|
|
|
|
vrele(cwdi->cwdi_rdir);
|
|
|
|
cwdi->cwdi_rdir = vp;
|
1999-03-22 20:13:34 +03:00
|
|
|
|
|
|
|
/*
|
|
|
|
* Prevent escaping from chroot by putting the root under
|
|
|
|
* the working directory. Silently chdir to / if we aren't
|
|
|
|
* already there.
|
|
|
|
*/
|
2005-12-11 15:16:03 +03:00
|
|
|
if (!vn_isunder(cwdi->cwdi_cdir, vp, l)) {
|
1999-03-22 20:13:34 +03:00
|
|
|
/*
|
|
|
|
* XXX would be more failsafe to change directory to a
|
|
|
|
* deadfs node here instead
|
|
|
|
*/
|
1999-04-30 22:42:58 +04:00
|
|
|
vrele(cwdi->cwdi_cdir);
|
2010-01-08 14:35:07 +03:00
|
|
|
vref(vp);
|
1999-04-30 22:42:58 +04:00
|
|
|
cwdi->cwdi_cdir = vp;
|
1999-03-22 20:13:34 +03:00
|
|
|
}
|
2007-10-08 19:12:05 +04:00
|
|
|
rw_exit(&cwdi->cwdi_lock);
|
2012-06-27 16:28:28 +04:00
|
|
|
|
|
|
|
/* Get a write lock on the process credential. */
|
|
|
|
proc_crmod_enter();
|
|
|
|
|
|
|
|
kauth_cred_clone(p->p_cred, ncred);
|
|
|
|
kauth_proc_chroot(ncred, p->p_cwdi);
|
|
|
|
|
|
|
|
/* Broadcast our credentials to the process and other LWPs. */
|
|
|
|
proc_crmod_leave(ncred, p->p_cred, true);
|
1994-06-29 10:29:24 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Common routine for chroot and chdir.
|
2010-11-19 09:44:33 +03:00
|
|
|
* XXX "where" should be enum uio_seg
|
1994-06-29 10:29:24 +04:00
|
|
|
*/
|
2009-08-02 01:17:11 +04:00
|
|
|
int
|
|
|
|
chdir_lookup(const char *path, int where, struct vnode **vpp, struct lwp *l)
|
1994-06-29 10:29:24 +04:00
|
|
|
{
|
2010-11-19 09:44:33 +03:00
|
|
|
struct pathbuf *pb;
|
2009-08-02 01:17:11 +04:00
|
|
|
struct nameidata nd;
|
1994-06-29 10:29:24 +04:00
|
|
|
int error;
|
|
|
|
|
2010-11-19 09:44:33 +03:00
|
|
|
error = pathbuf_maybe_copyin(path, where, &pb);
|
|
|
|
if (error) {
|
|
|
|
return error;
|
|
|
|
}
|
|
|
|
NDINIT(&nd, LOOKUP, FOLLOW | LOCKLEAF | TRYEMULROOT, pb);
|
|
|
|
if ((error = namei(&nd)) != 0) {
|
|
|
|
pathbuf_destroy(pb);
|
|
|
|
return error;
|
|
|
|
}
|
2009-08-02 01:17:11 +04:00
|
|
|
*vpp = nd.ni_vp;
|
2010-11-19 09:44:33 +03:00
|
|
|
pathbuf_destroy(pb);
|
|
|
|
|
2009-08-02 01:17:11 +04:00
|
|
|
if ((*vpp)->v_type != VDIR)
|
1994-06-29 10:29:24 +04:00
|
|
|
error = ENOTDIR;
|
|
|
|
else
|
2009-08-02 01:17:11 +04:00
|
|
|
error = VOP_ACCESS(*vpp, VEXEC, l->l_cred);
|
2004-03-23 16:22:32 +03:00
|
|
|
|
1994-06-29 10:29:24 +04:00
|
|
|
if (error)
|
2009-08-02 01:17:11 +04:00
|
|
|
vput(*vpp);
|
1998-03-01 05:20:01 +03:00
|
|
|
else
|
2010-06-24 16:58:48 +04:00
|
|
|
VOP_UNLOCK(*vpp);
|
1994-06-29 10:29:24 +04:00
|
|
|
return (error);
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
2012-02-12 03:16:15 +04:00
|
|
|
* Internals of sys_open - path has already been converted into a pathbuf
|
|
|
|
* (so we can easily reuse this function from other parts of the kernel,
|
|
|
|
* like posix_spawn post-processing).
|
1994-06-29 10:29:24 +04:00
|
|
|
*/
|
2012-02-12 03:16:15 +04:00
|
|
|
static int
|
Add most system calls for POSIX extended API set, part 2, with test cases:
faccessat(2), fchmodat(2), fchownat(2), fstatat(2), mkdirat(2), mkfifoat(2),
mknodat(2), linkat(2), readlinkat(2), symlinkat(2), renameat(2), unlinkat(2),
utimensat(2), openat(2).
Also implement O_SEARCH for openat(2)
Still missing:
- some flags for openat(2)
- fexecve(2) implementation
2012-11-18 21:41:51 +04:00
|
|
|
do_open(lwp_t *l, struct vnode *dvp, struct pathbuf *pb, int open_flags,
|
|
|
|
int open_mode, int *fd)
|
1995-09-20 01:40:36 +04:00
|
|
|
{
|
2003-01-18 13:06:22 +03:00
|
|
|
struct proc *p = l->l_proc;
|
1999-04-30 22:42:58 +04:00
|
|
|
struct cwdinfo *cwdi = p->p_cwdi;
|
2008-03-22 00:54:58 +03:00
|
|
|
file_t *fp;
|
1999-05-06 00:01:01 +04:00
|
|
|
struct vnode *vp;
|
1994-06-29 10:29:24 +04:00
|
|
|
int flags, cmode;
|
2011-04-10 19:45:33 +04:00
|
|
|
int indx, error;
|
1994-06-29 10:29:24 +04:00
|
|
|
struct nameidata nd;
|
|
|
|
|
2012-02-12 03:16:15 +04:00
|
|
|
flags = FFLAGS(open_flags);
|
1997-10-19 21:18:10 +04:00
|
|
|
if ((flags & (FREAD | FWRITE)) == 0)
|
2012-02-12 03:16:15 +04:00
|
|
|
return EINVAL;
|
2010-11-19 09:44:33 +03:00
|
|
|
|
|
|
|
if ((error = fd_allocfile(&fp, &indx)) != 0) {
|
|
|
|
return error;
|
|
|
|
}
|
2012-05-03 00:48:29 +04:00
|
|
|
|
2007-10-08 19:12:05 +04:00
|
|
|
/* We're going to read cwdi->cwdi_cmask unlocked here. */
|
2012-02-12 03:16:15 +04:00
|
|
|
cmode = ((open_mode &~ cwdi->cwdi_cmask) & ALLPERMS) &~ S_ISTXT;
|
2010-11-19 09:44:33 +03:00
|
|
|
NDINIT(&nd, LOOKUP, FOLLOW | TRYEMULROOT, pb);
|
Add most system calls for POSIX extended API set, part 2, with test cases:
faccessat(2), fchmodat(2), fchownat(2), fstatat(2), mkdirat(2), mkfifoat(2),
mknodat(2), linkat(2), readlinkat(2), symlinkat(2), renameat(2), unlinkat(2),
utimensat(2), openat(2).
Also implement O_SEARCH for openat(2)
Still missing:
- some flags for openat(2)
- fexecve(2) implementation
2012-11-18 21:41:51 +04:00
|
|
|
if (dvp != NULL)
|
|
|
|
NDAT(&nd, dvp);
|
|
|
|
|
2003-09-13 12:32:10 +04:00
|
|
|
l->l_dupfd = -indx - 1; /* XXX check for fdopen */
|
1996-02-04 05:17:43 +03:00
|
|
|
if ((error = vn_open(&nd, flags, cmode)) != 0) {
|
2008-03-22 00:54:58 +03:00
|
|
|
fd_abort(p, fp, indx);
|
2004-11-30 07:25:43 +03:00
|
|
|
if ((error == EDUPFD || error == EMOVEFD) &&
|
2003-09-13 12:32:10 +04:00
|
|
|
l->l_dupfd >= 0 && /* XXX from fdopen */
|
1994-12-14 22:36:15 +03:00
|
|
|
(error =
|
2008-03-22 00:54:58 +03:00
|
|
|
fd_dupopen(l->l_dupfd, &indx, flags, error)) == 0) {
|
2012-02-12 03:16:15 +04:00
|
|
|
*fd = indx;
|
2012-05-03 00:48:29 +04:00
|
|
|
return 0;
|
1994-12-14 22:08:07 +03:00
|
|
|
}
|
1994-12-14 22:36:15 +03:00
|
|
|
if (error == ERESTART)
|
|
|
|
error = EINTR;
|
2012-02-12 03:16:15 +04:00
|
|
|
return error;
|
1994-06-29 10:29:24 +04:00
|
|
|
}
|
2007-10-24 19:28:55 +04:00
|
|
|
|
2003-09-13 12:32:10 +04:00
|
|
|
l->l_dupfd = 0;
|
1994-06-29 10:29:24 +04:00
|
|
|
vp = nd.ni_vp;
|
2010-11-19 09:44:33 +03:00
|
|
|
|
2011-04-10 19:45:33 +04:00
|
|
|
if ((error = open_setfp(l, fp, vp, indx, flags)))
|
|
|
|
return error;
|
|
|
|
|
2010-06-24 16:58:48 +04:00
|
|
|
VOP_UNLOCK(vp);
|
2012-02-12 03:16:15 +04:00
|
|
|
*fd = indx;
|
2008-03-22 00:54:58 +03:00
|
|
|
fd_affix(p, fp, indx);
|
2012-02-12 03:16:15 +04:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
int
|
|
|
|
fd_open(const char *path, int open_flags, int open_mode, int *fd)
|
|
|
|
{
|
|
|
|
struct pathbuf *pb;
|
2012-05-03 00:48:29 +04:00
|
|
|
int error, oflags;
|
2012-02-12 03:16:15 +04:00
|
|
|
|
2012-02-12 17:12:45 +04:00
|
|
|
oflags = FFLAGS(open_flags);
|
|
|
|
if ((oflags & (FREAD | FWRITE)) == 0)
|
2012-02-12 03:16:15 +04:00
|
|
|
return EINVAL;
|
|
|
|
|
|
|
|
pb = pathbuf_create(path);
|
|
|
|
if (pb == NULL)
|
|
|
|
return ENOMEM;
|
|
|
|
|
Add most system calls for POSIX extended API set, part 2, with test cases:
faccessat(2), fchmodat(2), fchownat(2), fstatat(2), mkdirat(2), mkfifoat(2),
mknodat(2), linkat(2), readlinkat(2), symlinkat(2), renameat(2), unlinkat(2),
utimensat(2), openat(2).
Also implement O_SEARCH for openat(2)
Still missing:
- some flags for openat(2)
- fexecve(2) implementation
2012-11-18 21:41:51 +04:00
|
|
|
error = do_open(curlwp, NULL, pb, open_flags, open_mode, fd);
|
2012-05-03 00:48:29 +04:00
|
|
|
pathbuf_destroy(pb);
|
|
|
|
|
|
|
|
return error;
|
2012-02-12 03:16:15 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Check permissions, allocate an open file structure,
|
|
|
|
* and call the device open routine if any.
|
Add most system calls for POSIX extended API set, part 2, with test cases:
faccessat(2), fchmodat(2), fchownat(2), fstatat(2), mkdirat(2), mkfifoat(2),
mknodat(2), linkat(2), readlinkat(2), symlinkat(2), renameat(2), unlinkat(2),
utimensat(2), openat(2).
Also implement O_SEARCH for openat(2)
Still missing:
- some flags for openat(2)
- fexecve(2) implementation
2012-11-18 21:41:51 +04:00
|
|
|
* XXX implement O_SEARCH
|
2012-02-12 03:16:15 +04:00
|
|
|
*/
|
Add most system calls for POSIX extended API set, part 2, with test cases:
faccessat(2), fchmodat(2), fchownat(2), fstatat(2), mkdirat(2), mkfifoat(2),
mknodat(2), linkat(2), readlinkat(2), symlinkat(2), renameat(2), unlinkat(2),
utimensat(2), openat(2).
Also implement O_SEARCH for openat(2)
Still missing:
- some flags for openat(2)
- fexecve(2) implementation
2012-11-18 21:41:51 +04:00
|
|
|
static int
|
|
|
|
do_sys_openat(lwp_t *l, int fdat, const char *path, int flags,
|
|
|
|
int mode, int *fd)
|
|
|
|
{
|
|
|
|
file_t *dfp = NULL;
|
|
|
|
struct vnode *dvp = NULL;
|
|
|
|
struct pathbuf *pb;
|
|
|
|
int error;
|
|
|
|
|
|
|
|
error = pathbuf_copyin(path, &pb);
|
|
|
|
if (error)
|
|
|
|
return error;
|
|
|
|
|
|
|
|
if (fdat != AT_FDCWD) {
|
|
|
|
/* fd_getvnode() will use the descriptor for us */
|
|
|
|
if ((error = fd_getvnode(fdat, &dfp)) != 0)
|
|
|
|
goto out;
|
|
|
|
|
|
|
|
dvp = dfp->f_data;
|
|
|
|
|
|
|
|
if (!(dfp->f_flag & FSEARCH)) {
|
2012-11-30 17:26:37 +04:00
|
|
|
vn_lock(dfp->f_data, LK_EXCLUSIVE);
|
Add most system calls for POSIX extended API set, part 2, with test cases:
faccessat(2), fchmodat(2), fchownat(2), fstatat(2), mkdirat(2), mkfifoat(2),
mknodat(2), linkat(2), readlinkat(2), symlinkat(2), renameat(2), unlinkat(2),
utimensat(2), openat(2).
Also implement O_SEARCH for openat(2)
Still missing:
- some flags for openat(2)
- fexecve(2) implementation
2012-11-18 21:41:51 +04:00
|
|
|
error = VOP_ACCESS(dfp->f_data, VEXEC, l->l_cred);
|
2012-11-30 17:26:37 +04:00
|
|
|
VOP_UNLOCK(dfp->f_data);
|
Add most system calls for POSIX extended API set, part 2, with test cases:
faccessat(2), fchmodat(2), fchownat(2), fstatat(2), mkdirat(2), mkfifoat(2),
mknodat(2), linkat(2), readlinkat(2), symlinkat(2), renameat(2), unlinkat(2),
utimensat(2), openat(2).
Also implement O_SEARCH for openat(2)
Still missing:
- some flags for openat(2)
- fexecve(2) implementation
2012-11-18 21:41:51 +04:00
|
|
|
if (error)
|
|
|
|
goto cleanup;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
error = do_open(l, dvp, pb, flags, mode, fd);
|
|
|
|
|
|
|
|
cleanup:
|
|
|
|
if (dfp != NULL)
|
|
|
|
fd_putfile(fdat);
|
|
|
|
out:
|
|
|
|
pathbuf_destroy(pb);
|
|
|
|
return error;
|
|
|
|
}
|
|
|
|
|
2012-02-12 03:16:15 +04:00
|
|
|
int
|
|
|
|
sys_open(struct lwp *l, const struct sys_open_args *uap, register_t *retval)
|
|
|
|
{
|
|
|
|
/* {
|
|
|
|
syscallarg(const char *) path;
|
|
|
|
syscallarg(int) flags;
|
|
|
|
syscallarg(int) mode;
|
|
|
|
} */
|
Add most system calls for POSIX extended API set, part 2, with test cases:
faccessat(2), fchmodat(2), fchownat(2), fstatat(2), mkdirat(2), mkfifoat(2),
mknodat(2), linkat(2), readlinkat(2), symlinkat(2), renameat(2), unlinkat(2),
utimensat(2), openat(2).
Also implement O_SEARCH for openat(2)
Still missing:
- some flags for openat(2)
- fexecve(2) implementation
2012-11-18 21:41:51 +04:00
|
|
|
int error;
|
|
|
|
int fd;
|
2012-02-12 03:16:15 +04:00
|
|
|
|
Add most system calls for POSIX extended API set, part 2, with test cases:
faccessat(2), fchmodat(2), fchownat(2), fstatat(2), mkdirat(2), mkfifoat(2),
mknodat(2), linkat(2), readlinkat(2), symlinkat(2), renameat(2), unlinkat(2),
utimensat(2), openat(2).
Also implement O_SEARCH for openat(2)
Still missing:
- some flags for openat(2)
- fexecve(2) implementation
2012-11-18 21:41:51 +04:00
|
|
|
error = do_sys_openat(l, AT_FDCWD, SCARG(uap, path),
|
|
|
|
SCARG(uap, flags), SCARG(uap, mode), &fd);
|
2012-02-12 03:16:15 +04:00
|
|
|
|
Add most system calls for POSIX extended API set, part 2, with test cases:
faccessat(2), fchmodat(2), fchownat(2), fstatat(2), mkdirat(2), mkfifoat(2),
mknodat(2), linkat(2), readlinkat(2), symlinkat(2), renameat(2), unlinkat(2),
utimensat(2), openat(2).
Also implement O_SEARCH for openat(2)
Still missing:
- some flags for openat(2)
- fexecve(2) implementation
2012-11-18 21:41:51 +04:00
|
|
|
if (error == 0)
|
|
|
|
*retval = fd;
|
2012-02-12 03:16:15 +04:00
|
|
|
|
2012-05-03 00:48:29 +04:00
|
|
|
return error;
|
1994-06-29 10:29:24 +04:00
|
|
|
}
|
|
|
|
|
2011-08-08 16:08:52 +04:00
|
|
|
int
|
|
|
|
sys_openat(struct lwp *l, const struct sys_openat_args *uap, register_t *retval)
|
|
|
|
{
|
|
|
|
/* {
|
|
|
|
syscallarg(int) fd;
|
|
|
|
syscallarg(const char *) path;
|
Add most system calls for POSIX extended API set, part 2, with test cases:
faccessat(2), fchmodat(2), fchownat(2), fstatat(2), mkdirat(2), mkfifoat(2),
mknodat(2), linkat(2), readlinkat(2), symlinkat(2), renameat(2), unlinkat(2),
utimensat(2), openat(2).
Also implement O_SEARCH for openat(2)
Still missing:
- some flags for openat(2)
- fexecve(2) implementation
2012-11-18 21:41:51 +04:00
|
|
|
syscallarg(int) oflags;
|
2011-08-08 16:08:52 +04:00
|
|
|
syscallarg(int) mode;
|
|
|
|
} */
|
Add most system calls for POSIX extended API set, part 2, with test cases:
faccessat(2), fchmodat(2), fchownat(2), fstatat(2), mkdirat(2), mkfifoat(2),
mknodat(2), linkat(2), readlinkat(2), symlinkat(2), renameat(2), unlinkat(2),
utimensat(2), openat(2).
Also implement O_SEARCH for openat(2)
Still missing:
- some flags for openat(2)
- fexecve(2) implementation
2012-11-18 21:41:51 +04:00
|
|
|
int error;
|
|
|
|
int fd;
|
|
|
|
|
|
|
|
error = do_sys_openat(l, SCARG(uap, fd), SCARG(uap, path),
|
|
|
|
SCARG(uap, oflags), SCARG(uap, mode), &fd);
|
|
|
|
|
|
|
|
if (error == 0)
|
|
|
|
*retval = fd;
|
2011-08-08 16:08:52 +04:00
|
|
|
|
Add most system calls for POSIX extended API set, part 2, with test cases:
faccessat(2), fchmodat(2), fchownat(2), fstatat(2), mkdirat(2), mkfifoat(2),
mknodat(2), linkat(2), readlinkat(2), symlinkat(2), renameat(2), unlinkat(2),
utimensat(2), openat(2).
Also implement O_SEARCH for openat(2)
Still missing:
- some flags for openat(2)
- fexecve(2) implementation
2012-11-18 21:41:51 +04:00
|
|
|
return error;
|
2011-08-08 16:08:52 +04:00
|
|
|
}
|
|
|
|
|
2006-07-14 22:29:40 +04:00
|
|
|
static void
|
|
|
|
vfs__fhfree(fhandle_t *fhp)
|
|
|
|
{
|
|
|
|
size_t fhsize;
|
|
|
|
|
|
|
|
if (fhp == NULL) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
fhsize = FHANDLE_SIZE(fhp);
|
|
|
|
kmem_free(fhp, fhsize);
|
|
|
|
}
|
|
|
|
|
2006-06-17 11:06:50 +04:00
|
|
|
/*
|
|
|
|
* vfs_composefh: compose a filehandle.
|
|
|
|
*/
|
|
|
|
|
|
|
|
int
|
2006-07-13 16:00:24 +04:00
|
|
|
vfs_composefh(struct vnode *vp, fhandle_t *fhp, size_t *fh_size)
|
2006-06-17 11:06:50 +04:00
|
|
|
{
|
|
|
|
struct mount *mp;
|
2006-07-14 22:30:35 +04:00
|
|
|
struct fid *fidp;
|
2006-06-17 11:06:50 +04:00
|
|
|
int error;
|
2006-07-14 22:30:35 +04:00
|
|
|
size_t needfhsize;
|
|
|
|
size_t fidsize;
|
2006-06-17 11:06:50 +04:00
|
|
|
|
|
|
|
mp = vp->v_mount;
|
2006-07-14 22:30:35 +04:00
|
|
|
fidp = NULL;
|
2006-07-15 20:32:29 +04:00
|
|
|
if (*fh_size < FHANDLE_SIZE_MIN) {
|
2006-07-14 22:30:35 +04:00
|
|
|
fidsize = 0;
|
2006-07-13 16:00:24 +04:00
|
|
|
} else {
|
2006-07-14 22:30:35 +04:00
|
|
|
fidsize = *fh_size - offsetof(fhandle_t, fh_fid);
|
|
|
|
if (fhp != NULL) {
|
|
|
|
memset(fhp, 0, *fh_size);
|
|
|
|
fhp->fh_fsid = mp->mnt_stat.f_fsidx;
|
|
|
|
fidp = &fhp->fh_fid;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
error = VFS_VPTOFH(vp, fidp, &fidsize);
|
|
|
|
needfhsize = FHANDLE_SIZE_FROM_FILEID_SIZE(fidsize);
|
|
|
|
if (error == 0 && *fh_size < needfhsize) {
|
|
|
|
error = E2BIG;
|
2006-07-13 16:00:24 +04:00
|
|
|
}
|
2006-07-14 22:30:35 +04:00
|
|
|
*fh_size = needfhsize;
|
2006-06-17 11:06:50 +04:00
|
|
|
return error;
|
|
|
|
}
|
|
|
|
|
2006-07-14 22:29:40 +04:00
|
|
|
int
|
|
|
|
vfs_composefh_alloc(struct vnode *vp, fhandle_t **fhpp)
|
|
|
|
{
|
|
|
|
struct mount *mp;
|
|
|
|
fhandle_t *fhp;
|
|
|
|
size_t fhsize;
|
|
|
|
size_t fidsize;
|
|
|
|
int error;
|
|
|
|
|
|
|
|
*fhpp = NULL;
|
|
|
|
mp = vp->v_mount;
|
2006-07-20 20:18:14 +04:00
|
|
|
fidsize = 0;
|
2006-07-14 22:29:40 +04:00
|
|
|
error = VFS_VPTOFH(vp, NULL, &fidsize);
|
|
|
|
KASSERT(error != 0);
|
|
|
|
if (error != E2BIG) {
|
|
|
|
goto out;
|
|
|
|
}
|
2006-07-14 22:30:35 +04:00
|
|
|
fhsize = FHANDLE_SIZE_FROM_FILEID_SIZE(fidsize);
|
2006-07-14 22:29:40 +04:00
|
|
|
fhp = kmem_zalloc(fhsize, KM_SLEEP);
|
|
|
|
if (fhp == NULL) {
|
|
|
|
error = ENOMEM;
|
|
|
|
goto out;
|
|
|
|
}
|
|
|
|
fhp->fh_fsid = mp->mnt_stat.f_fsidx;
|
|
|
|
error = VFS_VPTOFH(vp, &fhp->fh_fid, &fidsize);
|
|
|
|
if (error == 0) {
|
|
|
|
KASSERT((FHANDLE_SIZE(fhp) == fhsize &&
|
|
|
|
FHANDLE_FILEID(fhp)->fid_len == fidsize));
|
|
|
|
*fhpp = fhp;
|
|
|
|
} else {
|
|
|
|
kmem_free(fhp, fhsize);
|
|
|
|
}
|
|
|
|
out:
|
|
|
|
return error;
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
vfs_composefh_free(fhandle_t *fhp)
|
|
|
|
{
|
|
|
|
|
|
|
|
vfs__fhfree(fhp);
|
|
|
|
}
|
|
|
|
|
2006-07-14 19:59:29 +04:00
|
|
|
/*
|
|
|
|
* vfs_fhtovp: lookup a vnode by a filehandle.
|
|
|
|
*/
|
|
|
|
|
|
|
|
int
|
|
|
|
vfs_fhtovp(fhandle_t *fhp, struct vnode **vpp)
|
|
|
|
{
|
|
|
|
struct mount *mp;
|
|
|
|
int error;
|
|
|
|
|
|
|
|
*vpp = NULL;
|
|
|
|
mp = vfs_getvfs(FHANDLE_FSID(fhp));
|
|
|
|
if (mp == NULL) {
|
|
|
|
error = ESTALE;
|
|
|
|
goto out;
|
|
|
|
}
|
|
|
|
if (mp->mnt_op->vfs_fhtovp == NULL) {
|
|
|
|
error = EOPNOTSUPP;
|
|
|
|
goto out;
|
|
|
|
}
|
|
|
|
error = VFS_FHTOVP(mp, FHANDLE_FILEID(fhp), vpp);
|
|
|
|
out:
|
|
|
|
return error;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
2006-08-04 20:29:51 +04:00
|
|
|
* vfs_copyinfh_alloc: allocate and copyin a filehandle, given
|
2006-07-31 20:34:42 +04:00
|
|
|
* the needed size.
|
|
|
|
*/
|
|
|
|
|
|
|
|
int
|
2006-08-04 20:29:51 +04:00
|
|
|
vfs_copyinfh_alloc(const void *ufhp, size_t fhsize, fhandle_t **fhpp)
|
2006-07-31 20:34:42 +04:00
|
|
|
{
|
|
|
|
fhandle_t *fhp;
|
|
|
|
int error;
|
|
|
|
|
|
|
|
*fhpp = NULL;
|
2006-07-14 22:30:35 +04:00
|
|
|
if (fhsize > FHANDLE_SIZE_MAX) {
|
|
|
|
return EINVAL;
|
|
|
|
}
|
2006-08-04 20:29:51 +04:00
|
|
|
if (fhsize < FHANDLE_SIZE_MIN) {
|
|
|
|
return EINVAL;
|
|
|
|
}
|
2006-08-08 17:08:08 +04:00
|
|
|
again:
|
2006-07-14 19:59:29 +04:00
|
|
|
fhp = kmem_alloc(fhsize, KM_SLEEP);
|
|
|
|
if (fhp == NULL) {
|
|
|
|
return ENOMEM;
|
|
|
|
}
|
|
|
|
error = copyin(ufhp, fhp, fhsize);
|
|
|
|
if (error == 0) {
|
2006-08-04 20:29:51 +04:00
|
|
|
/* XXX this check shouldn't be here */
|
|
|
|
if (FHANDLE_SIZE(fhp) == fhsize) {
|
2006-07-31 20:34:42 +04:00
|
|
|
*fhpp = fhp;
|
|
|
|
return 0;
|
2006-08-08 17:08:08 +04:00
|
|
|
} else if (fhsize == NFSX_V2FH && FHANDLE_SIZE(fhp) < fhsize) {
|
|
|
|
/*
|
|
|
|
* a kludge for nfsv2 padded handles.
|
|
|
|
*/
|
|
|
|
size_t sz;
|
|
|
|
|
|
|
|
sz = FHANDLE_SIZE(fhp);
|
|
|
|
kmem_free(fhp, fhsize);
|
|
|
|
fhsize = sz;
|
|
|
|
goto again;
|
2006-08-04 17:31:51 +04:00
|
|
|
} else {
|
2006-08-04 20:29:51 +04:00
|
|
|
/*
|
|
|
|
* userland told us wrong size.
|
|
|
|
*/
|
2006-07-31 20:34:42 +04:00
|
|
|
error = EINVAL;
|
2006-08-04 17:31:51 +04:00
|
|
|
}
|
2006-07-14 19:59:29 +04:00
|
|
|
}
|
2006-07-31 20:34:42 +04:00
|
|
|
kmem_free(fhp, fhsize);
|
2006-07-14 19:59:29 +04:00
|
|
|
return error;
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
vfs_copyinfh_free(fhandle_t *fhp)
|
|
|
|
{
|
|
|
|
|
2006-07-14 22:29:40 +04:00
|
|
|
vfs__fhfree(fhp);
|
2006-07-14 19:59:29 +04:00
|
|
|
}
|
|
|
|
|
1999-06-30 02:18:47 +04:00
|
|
|
/*
|
|
|
|
* Get file handle system call
|
|
|
|
*/
|
|
|
|
int
|
2007-12-21 02:02:38 +03:00
|
|
|
sys___getfh30(struct lwp *l, const struct sys___getfh30_args *uap, register_t *retval)
|
1999-06-30 02:18:47 +04:00
|
|
|
{
|
2007-12-21 02:02:38 +03:00
|
|
|
/* {
|
1999-06-30 02:18:47 +04:00
|
|
|
syscallarg(char *) fname;
|
|
|
|
syscallarg(fhandle_t *) fhp;
|
2006-07-13 16:00:24 +04:00
|
|
|
syscallarg(size_t *) fh_size;
|
2007-12-21 02:02:38 +03:00
|
|
|
} */
|
2000-03-30 13:27:11 +04:00
|
|
|
struct vnode *vp;
|
2006-07-13 16:00:24 +04:00
|
|
|
fhandle_t *fh;
|
1999-06-30 02:18:47 +04:00
|
|
|
int error;
|
2010-11-19 09:44:33 +03:00
|
|
|
struct pathbuf *pb;
|
1999-06-30 02:18:47 +04:00
|
|
|
struct nameidata nd;
|
2006-07-13 16:00:24 +04:00
|
|
|
size_t sz;
|
2006-07-14 22:29:40 +04:00
|
|
|
size_t usz;
|
1999-06-30 02:18:47 +04:00
|
|
|
|
|
|
|
/*
|
|
|
|
* Must be super user
|
|
|
|
*/
|
First take at security model abstraction.
- Add a few scopes to the kernel: system, network, and machdep.
- Add a few more actions/sub-actions (requests), and start using them as
opposed to the KAUTH_GENERIC_ISSUSER place-holders.
- Introduce a basic set of listeners that implement our "traditional"
security model, called "bsd44". This is the default (and only) model we
have at the moment.
- Update all relevant documentation.
- Add some code and docs to help folks who want to actually use this stuff:
* There's a sample overlay model, sitting on-top of "bsd44", for
fast experimenting with tweaking just a subset of an existing model.
This is pretty cool because it's *really* straightforward to do stuff
you had to use ugly hacks for until now...
* And of course, documentation describing how to do the above for quick
reference, including code samples.
All of these changes were tested for regressions using a Python-based
testsuite that will be (I hope) available soon via pkgsrc. Information
about the tests, and how to write new ones, can be found on:
http://kauth.linbsd.org/kauthwiki
NOTE FOR DEVELOPERS: *PLEASE* don't add any code that does any of the
following:
- Uses a KAUTH_GENERIC_ISSUSER kauth(9) request,
- Checks 'securelevel' directly,
- Checks a uid/gid directly.
(or if you feel you have to, contact me first)
This is still work in progress; It's far from being done, but now it'll
be a lot easier.
Relevant mailing list threads:
http://mail-index.netbsd.org/tech-security/2006/01/25/0011.html
http://mail-index.netbsd.org/tech-security/2006/03/24/0001.html
http://mail-index.netbsd.org/tech-security/2006/04/18/0000.html
http://mail-index.netbsd.org/tech-security/2006/05/15/0000.html
http://mail-index.netbsd.org/tech-security/2006/08/01/0000.html
http://mail-index.netbsd.org/tech-security/2006/08/25/0000.html
Many thanks to YAMAMOTO Takashi, Matt Thomas, and Christos Zoulas for help
stablizing kauth(9).
Full credit for the regression tests, making sure these changes didn't break
anything, goes to Matt Fleming and Jaime Fournier.
Happy birthday Randi! :)
2006-09-09 00:58:56 +04:00
|
|
|
error = kauth_authorize_system(l->l_cred, KAUTH_SYSTEM_FILEHANDLE,
|
|
|
|
0, NULL, NULL, NULL);
|
1999-06-30 02:18:47 +04:00
|
|
|
if (error)
|
|
|
|
return (error);
|
2010-11-19 09:44:33 +03:00
|
|
|
|
|
|
|
error = pathbuf_copyin(SCARG(uap, fname), &pb);
|
|
|
|
if (error) {
|
|
|
|
return error;
|
|
|
|
}
|
|
|
|
NDINIT(&nd, LOOKUP, FOLLOW | LOCKLEAF | TRYEMULROOT, pb);
|
1999-06-30 02:18:47 +04:00
|
|
|
error = namei(&nd);
|
2010-11-19 09:44:33 +03:00
|
|
|
if (error) {
|
|
|
|
pathbuf_destroy(pb);
|
|
|
|
return error;
|
|
|
|
}
|
1999-06-30 02:18:47 +04:00
|
|
|
vp = nd.ni_vp;
|
2010-11-19 09:44:33 +03:00
|
|
|
pathbuf_destroy(pb);
|
|
|
|
|
2006-07-14 22:29:40 +04:00
|
|
|
error = vfs_composefh_alloc(vp, &fh);
|
2006-07-14 18:28:58 +04:00
|
|
|
vput(vp);
|
2006-07-14 22:29:40 +04:00
|
|
|
if (error != 0) {
|
|
|
|
goto out;
|
2006-07-13 16:00:24 +04:00
|
|
|
}
|
2006-07-14 22:29:40 +04:00
|
|
|
error = copyin(SCARG(uap, fh_size), &usz, sizeof(size_t));
|
|
|
|
if (error != 0) {
|
|
|
|
goto out;
|
|
|
|
}
|
|
|
|
sz = FHANDLE_SIZE(fh);
|
|
|
|
error = copyout(&sz, SCARG(uap, fh_size), sizeof(size_t));
|
|
|
|
if (error != 0) {
|
|
|
|
goto out;
|
2006-07-13 16:00:24 +04:00
|
|
|
}
|
2006-07-14 22:29:40 +04:00
|
|
|
if (usz >= sz) {
|
|
|
|
error = copyout(fh, SCARG(uap, fhp), sz);
|
|
|
|
} else {
|
|
|
|
error = E2BIG;
|
|
|
|
}
|
|
|
|
out:
|
|
|
|
vfs_composefh_free(fh);
|
1999-06-30 02:18:47 +04:00
|
|
|
return (error);
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Open a file given a file handle.
|
|
|
|
*
|
|
|
|
* Check permissions, allocate an open file structure,
|
|
|
|
* and call the device open routine if any.
|
|
|
|
*/
|
2006-08-04 20:29:51 +04:00
|
|
|
|
1999-06-30 02:18:47 +04:00
|
|
|
int
|
2006-08-04 20:29:51 +04:00
|
|
|
dofhopen(struct lwp *l, const void *ufhp, size_t fhsize, int oflags,
|
|
|
|
register_t *retval)
|
1999-06-30 02:18:47 +04:00
|
|
|
{
|
2008-03-22 00:54:58 +03:00
|
|
|
file_t *fp;
|
1999-07-01 22:58:16 +04:00
|
|
|
struct vnode *vp = NULL;
|
2006-07-24 02:06:03 +04:00
|
|
|
kauth_cred_t cred = l->l_cred;
|
2008-03-22 00:54:58 +03:00
|
|
|
file_t *nfp;
|
2011-04-10 19:45:33 +04:00
|
|
|
int indx, error = 0;
|
1999-06-30 02:18:47 +04:00
|
|
|
struct vattr va;
|
2006-07-14 19:59:29 +04:00
|
|
|
fhandle_t *fh;
|
2006-08-04 20:29:51 +04:00
|
|
|
int flags;
|
2008-03-22 00:54:58 +03:00
|
|
|
proc_t *p;
|
|
|
|
|
|
|
|
p = curproc;
|
1999-06-30 02:18:47 +04:00
|
|
|
|
|
|
|
/*
|
|
|
|
* Must be super user
|
|
|
|
*/
|
2006-09-12 11:51:29 +04:00
|
|
|
if ((error = kauth_authorize_system(l->l_cred, KAUTH_SYSTEM_FILEHANDLE,
|
2006-09-13 14:07:42 +04:00
|
|
|
0, NULL, NULL, NULL)))
|
1999-06-30 02:18:47 +04:00
|
|
|
return (error);
|
|
|
|
|
2006-08-04 20:29:51 +04:00
|
|
|
flags = FFLAGS(oflags);
|
1999-06-30 02:18:47 +04:00
|
|
|
if ((flags & (FREAD | FWRITE)) == 0)
|
|
|
|
return (EINVAL);
|
|
|
|
if ((flags & O_CREAT))
|
|
|
|
return (EINVAL);
|
2008-03-22 00:54:58 +03:00
|
|
|
if ((error = fd_allocfile(&nfp, &indx)) != 0)
|
1999-06-30 02:18:47 +04:00
|
|
|
return (error);
|
|
|
|
fp = nfp;
|
2006-08-04 20:29:51 +04:00
|
|
|
error = vfs_copyinfh_alloc(ufhp, fhsize, &fh);
|
2006-07-14 19:59:29 +04:00
|
|
|
if (error != 0) {
|
Apply the NFS exports list rototill patch:
- Remove all NFS related stuff from file system specific code.
- Drop the vfs_checkexp hook and generalize it in the new nfs_check_export
function, thus removing redundancy from all file systems.
- Move all NFS export-related stuff from kern/vfs_subr.c to the new
file sys/nfs/nfs_export.c. The former was becoming large and its code
is always compiled, regardless of the build options. Using the latter,
the code is only compiled in when NFSSERVER is enabled. While doing this,
also make some functions in nfs_subs.c conditional to NFSSERVER.
- Add a new command in nfssvc(2), called NFSSVC_SETEXPORTSLIST, that takes a
path and a set of export entries. At the moment it can only clear the
exports list or append entries, one by one, but it is done in a way that
allows setting the whole set of entries atomically in the future (see the
comment in mountd_set_exports_list or in doc/TODO).
- Change mountd(8) to use the nfssvc(2) system call instead of mount(2) so
that it becomes file system agnostic. In fact, all this whole thing was
done to remove a 'XXX' block from this utility!
- Change the mount*, newfs and fsck* userland utilities to not deal with NFS
exports initialization; done internally by the kernel when initializing
the NFS support for each file system.
- Implement an interface for VFS (called VFS hooks) so that several kernel
subsystems can run arbitrary code upon receipt of specific VFS events.
At the moment, this only provides support for unmount and is used to
destroy NFS exports lists from the file systems being unmounted, though it
has room for extension.
Thanks go to yamt@, chs@, thorpej@, wrstuden@ and others for their comments
and advice in the development of this patch.
2005-09-23 16:10:31 +04:00
|
|
|
goto bad;
|
|
|
|
}
|
2006-07-14 19:59:29 +04:00
|
|
|
error = vfs_fhtovp(fh, &vp);
|
|
|
|
if (error != 0) {
|
1999-07-01 22:58:16 +04:00
|
|
|
goto bad;
|
|
|
|
}
|
1999-06-30 02:18:47 +04:00
|
|
|
|
|
|
|
/* Now do an effective vn_open */
|
|
|
|
|
|
|
|
if (vp->v_type == VSOCK) {
|
|
|
|
error = EOPNOTSUPP;
|
|
|
|
goto bad;
|
|
|
|
}
|
2007-11-30 19:52:19 +03:00
|
|
|
error = vn_openchk(vp, cred, flags);
|
|
|
|
if (error != 0)
|
|
|
|
goto bad;
|
1999-06-30 02:18:47 +04:00
|
|
|
if (flags & O_TRUNC) {
|
2010-06-24 16:58:48 +04:00
|
|
|
VOP_UNLOCK(vp); /* XXX */
|
1999-06-30 02:18:47 +04:00
|
|
|
vn_lock(vp, LK_EXCLUSIVE | LK_RETRY); /* XXX */
|
2010-01-08 14:35:07 +03:00
|
|
|
vattr_null(&va);
|
1999-06-30 02:18:47 +04:00
|
|
|
va.va_size = 0;
|
2007-11-26 22:01:26 +03:00
|
|
|
error = VOP_SETATTR(vp, &va, cred);
|
2003-10-15 15:28:59 +04:00
|
|
|
if (error)
|
1999-06-30 02:18:47 +04:00
|
|
|
goto bad;
|
|
|
|
}
|
2007-11-26 22:01:26 +03:00
|
|
|
if ((error = VOP_OPEN(vp, flags, cred)) != 0)
|
1999-06-30 02:18:47 +04:00
|
|
|
goto bad;
|
2008-03-22 00:54:58 +03:00
|
|
|
if (flags & FWRITE) {
|
2011-06-12 07:35:36 +04:00
|
|
|
mutex_enter(vp->v_interlock);
|
1999-06-30 02:18:47 +04:00
|
|
|
vp->v_writecount++;
|
2011-06-12 07:35:36 +04:00
|
|
|
mutex_exit(vp->v_interlock);
|
2008-03-22 00:54:58 +03:00
|
|
|
}
|
1999-06-30 02:18:47 +04:00
|
|
|
|
|
|
|
/* done with modified vn_open, now finish what sys_open does. */
|
2011-04-10 19:45:33 +04:00
|
|
|
if ((error = open_setfp(l, fp, vp, indx, flags)))
|
|
|
|
return error;
|
1999-06-30 02:18:47 +04:00
|
|
|
|
2010-06-24 16:58:48 +04:00
|
|
|
VOP_UNLOCK(vp);
|
1999-06-30 02:18:47 +04:00
|
|
|
*retval = indx;
|
2008-03-22 00:54:58 +03:00
|
|
|
fd_affix(p, fp, indx);
|
2006-07-14 19:59:29 +04:00
|
|
|
vfs_copyinfh_free(fh);
|
1999-06-30 02:18:47 +04:00
|
|
|
return (0);
|
1999-07-01 22:58:16 +04:00
|
|
|
|
1999-06-30 02:18:47 +04:00
|
|
|
bad:
|
2008-03-22 00:54:58 +03:00
|
|
|
fd_abort(p, fp, indx);
|
1999-07-01 22:58:16 +04:00
|
|
|
if (vp != NULL)
|
|
|
|
vput(vp);
|
2006-07-14 19:59:29 +04:00
|
|
|
vfs_copyinfh_free(fh);
|
1999-06-30 02:18:47 +04:00
|
|
|
return (error);
|
|
|
|
}
|
|
|
|
|
|
|
|
int
|
2007-12-21 02:02:38 +03:00
|
|
|
sys___fhopen40(struct lwp *l, const struct sys___fhopen40_args *uap, register_t *retval)
|
1999-06-30 02:18:47 +04:00
|
|
|
{
|
2007-12-21 02:02:38 +03:00
|
|
|
/* {
|
2006-07-31 20:34:42 +04:00
|
|
|
syscallarg(const void *) fhp;
|
|
|
|
syscallarg(size_t) fh_size;
|
2006-08-04 20:29:51 +04:00
|
|
|
syscallarg(int) flags;
|
2007-12-21 02:02:38 +03:00
|
|
|
} */
|
2006-08-04 20:29:51 +04:00
|
|
|
|
|
|
|
return dofhopen(l, SCARG(uap, fhp), SCARG(uap, fh_size),
|
|
|
|
SCARG(uap, flags), retval);
|
|
|
|
}
|
|
|
|
|
2007-03-10 19:50:01 +03:00
|
|
|
int
|
|
|
|
do_fhstat(struct lwp *l, const void *ufhp, size_t fhsize, struct stat *sb)
|
|
|
|
{
|
1999-06-30 02:18:47 +04:00
|
|
|
int error;
|
2006-07-14 19:59:29 +04:00
|
|
|
fhandle_t *fh;
|
1999-06-30 02:18:47 +04:00
|
|
|
struct vnode *vp;
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Must be super user
|
|
|
|
*/
|
First take at security model abstraction.
- Add a few scopes to the kernel: system, network, and machdep.
- Add a few more actions/sub-actions (requests), and start using them as
opposed to the KAUTH_GENERIC_ISSUSER place-holders.
- Introduce a basic set of listeners that implement our "traditional"
security model, called "bsd44". This is the default (and only) model we
have at the moment.
- Update all relevant documentation.
- Add some code and docs to help folks who want to actually use this stuff:
* There's a sample overlay model, sitting on-top of "bsd44", for
fast experimenting with tweaking just a subset of an existing model.
This is pretty cool because it's *really* straightforward to do stuff
you had to use ugly hacks for until now...
* And of course, documentation describing how to do the above for quick
reference, including code samples.
All of these changes were tested for regressions using a Python-based
testsuite that will be (I hope) available soon via pkgsrc. Information
about the tests, and how to write new ones, can be found on:
http://kauth.linbsd.org/kauthwiki
NOTE FOR DEVELOPERS: *PLEASE* don't add any code that does any of the
following:
- Uses a KAUTH_GENERIC_ISSUSER kauth(9) request,
- Checks 'securelevel' directly,
- Checks a uid/gid directly.
(or if you feel you have to, contact me first)
This is still work in progress; It's far from being done, but now it'll
be a lot easier.
Relevant mailing list threads:
http://mail-index.netbsd.org/tech-security/2006/01/25/0011.html
http://mail-index.netbsd.org/tech-security/2006/03/24/0001.html
http://mail-index.netbsd.org/tech-security/2006/04/18/0000.html
http://mail-index.netbsd.org/tech-security/2006/05/15/0000.html
http://mail-index.netbsd.org/tech-security/2006/08/01/0000.html
http://mail-index.netbsd.org/tech-security/2006/08/25/0000.html
Many thanks to YAMAMOTO Takashi, Matt Thomas, and Christos Zoulas for help
stablizing kauth(9).
Full credit for the regression tests, making sure these changes didn't break
anything, goes to Matt Fleming and Jaime Fournier.
Happy birthday Randi! :)
2006-09-09 00:58:56 +04:00
|
|
|
if ((error = kauth_authorize_system(l->l_cred, KAUTH_SYSTEM_FILEHANDLE,
|
2006-09-13 14:07:42 +04:00
|
|
|
0, NULL, NULL, NULL)))
|
1999-06-30 02:18:47 +04:00
|
|
|
return (error);
|
|
|
|
|
2006-08-04 20:29:51 +04:00
|
|
|
error = vfs_copyinfh_alloc(ufhp, fhsize, &fh);
|
2007-03-10 19:50:01 +03:00
|
|
|
if (error != 0)
|
|
|
|
return error;
|
|
|
|
|
2006-07-14 19:59:29 +04:00
|
|
|
error = vfs_fhtovp(fh, &vp);
|
|
|
|
vfs_copyinfh_free(fh);
|
2007-03-10 19:50:01 +03:00
|
|
|
if (error != 0)
|
|
|
|
return error;
|
|
|
|
|
2008-03-22 00:54:58 +03:00
|
|
|
error = vn_stat(vp, sb);
|
2007-03-10 19:50:01 +03:00
|
|
|
vput(vp);
|
2006-07-14 19:59:29 +04:00
|
|
|
return error;
|
1999-06-30 02:18:47 +04:00
|
|
|
}
|
|
|
|
|
2006-08-04 20:29:51 +04:00
|
|
|
|
1999-06-30 02:18:47 +04:00
|
|
|
/* ARGSUSED */
|
|
|
|
int
|
2009-01-11 05:45:45 +03:00
|
|
|
sys___fhstat50(struct lwp *l, const struct sys___fhstat50_args *uap, register_t *retval)
|
1999-06-30 02:18:47 +04:00
|
|
|
{
|
2007-12-21 02:02:38 +03:00
|
|
|
/* {
|
2006-08-04 20:29:51 +04:00
|
|
|
syscallarg(const void *) fhp;
|
2006-07-31 20:34:42 +04:00
|
|
|
syscallarg(size_t) fh_size;
|
2006-08-04 20:29:51 +04:00
|
|
|
syscallarg(struct stat *) sb;
|
2007-12-21 02:02:38 +03:00
|
|
|
} */
|
2007-03-10 19:50:01 +03:00
|
|
|
struct stat sb;
|
|
|
|
int error;
|
2006-08-04 20:29:51 +04:00
|
|
|
|
2007-03-10 19:50:01 +03:00
|
|
|
error = do_fhstat(l, SCARG(uap, fhp), SCARG(uap, fh_size), &sb);
|
|
|
|
if (error)
|
|
|
|
return error;
|
|
|
|
return copyout(&sb, SCARG(uap, sb), sizeof(sb));
|
2006-08-04 20:29:51 +04:00
|
|
|
}
|
|
|
|
|
2007-03-10 19:50:01 +03:00
|
|
|
int
|
|
|
|
do_fhstatvfs(struct lwp *l, const void *ufhp, size_t fhsize, struct statvfs *sb,
|
|
|
|
int flags)
|
|
|
|
{
|
2006-07-14 19:59:29 +04:00
|
|
|
fhandle_t *fh;
|
1999-06-30 02:18:47 +04:00
|
|
|
struct mount *mp;
|
|
|
|
struct vnode *vp;
|
|
|
|
int error;
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Must be super user
|
|
|
|
*/
|
First take at security model abstraction.
- Add a few scopes to the kernel: system, network, and machdep.
- Add a few more actions/sub-actions (requests), and start using them as
opposed to the KAUTH_GENERIC_ISSUSER place-holders.
- Introduce a basic set of listeners that implement our "traditional"
security model, called "bsd44". This is the default (and only) model we
have at the moment.
- Update all relevant documentation.
- Add some code and docs to help folks who want to actually use this stuff:
* There's a sample overlay model, sitting on-top of "bsd44", for
fast experimenting with tweaking just a subset of an existing model.
This is pretty cool because it's *really* straightforward to do stuff
you had to use ugly hacks for until now...
* And of course, documentation describing how to do the above for quick
reference, including code samples.
All of these changes were tested for regressions using a Python-based
testsuite that will be (I hope) available soon via pkgsrc. Information
about the tests, and how to write new ones, can be found on:
http://kauth.linbsd.org/kauthwiki
NOTE FOR DEVELOPERS: *PLEASE* don't add any code that does any of the
following:
- Uses a KAUTH_GENERIC_ISSUSER kauth(9) request,
- Checks 'securelevel' directly,
- Checks a uid/gid directly.
(or if you feel you have to, contact me first)
This is still work in progress; It's far from being done, but now it'll
be a lot easier.
Relevant mailing list threads:
http://mail-index.netbsd.org/tech-security/2006/01/25/0011.html
http://mail-index.netbsd.org/tech-security/2006/03/24/0001.html
http://mail-index.netbsd.org/tech-security/2006/04/18/0000.html
http://mail-index.netbsd.org/tech-security/2006/05/15/0000.html
http://mail-index.netbsd.org/tech-security/2006/08/01/0000.html
http://mail-index.netbsd.org/tech-security/2006/08/25/0000.html
Many thanks to YAMAMOTO Takashi, Matt Thomas, and Christos Zoulas for help
stablizing kauth(9).
Full credit for the regression tests, making sure these changes didn't break
anything, goes to Matt Fleming and Jaime Fournier.
Happy birthday Randi! :)
2006-09-09 00:58:56 +04:00
|
|
|
if ((error = kauth_authorize_system(l->l_cred, KAUTH_SYSTEM_FILEHANDLE,
|
2006-09-13 14:07:42 +04:00
|
|
|
0, NULL, NULL, NULL)))
|
2004-04-21 05:05:31 +04:00
|
|
|
return error;
|
1999-06-30 02:18:47 +04:00
|
|
|
|
2006-08-04 20:29:51 +04:00
|
|
|
error = vfs_copyinfh_alloc(ufhp, fhsize, &fh);
|
2007-03-10 19:50:01 +03:00
|
|
|
if (error != 0)
|
|
|
|
return error;
|
|
|
|
|
2006-07-14 19:59:29 +04:00
|
|
|
error = vfs_fhtovp(fh, &vp);
|
2007-03-10 19:50:01 +03:00
|
|
|
vfs_copyinfh_free(fh);
|
|
|
|
if (error != 0)
|
|
|
|
return error;
|
|
|
|
|
1999-06-30 02:18:47 +04:00
|
|
|
mp = vp->v_mount;
|
2007-03-10 19:50:01 +03:00
|
|
|
error = dostatvfs(mp, sb, l, flags, 1);
|
1999-06-30 02:18:47 +04:00
|
|
|
vput(vp);
|
2006-05-10 15:02:29 +04:00
|
|
|
return error;
|
1999-06-30 02:18:47 +04:00
|
|
|
}
|
|
|
|
|
2006-08-04 20:29:51 +04:00
|
|
|
/* ARGSUSED */
|
|
|
|
int
|
2007-12-21 02:02:38 +03:00
|
|
|
sys___fhstatvfs140(struct lwp *l, const struct sys___fhstatvfs140_args *uap, register_t *retval)
|
2006-08-04 20:29:51 +04:00
|
|
|
{
|
2007-12-21 02:02:38 +03:00
|
|
|
/* {
|
2006-08-04 21:07:32 +04:00
|
|
|
syscallarg(const void *) fhp;
|
2006-08-04 20:29:51 +04:00
|
|
|
syscallarg(size_t) fh_size;
|
|
|
|
syscallarg(struct statvfs *) buf;
|
|
|
|
syscallarg(int) flags;
|
2007-12-21 02:02:38 +03:00
|
|
|
} */
|
2007-03-10 19:50:01 +03:00
|
|
|
struct statvfs *sb = STATVFSBUF_GET();
|
|
|
|
int error;
|
2006-08-04 20:29:51 +04:00
|
|
|
|
2007-03-10 19:50:01 +03:00
|
|
|
error = do_fhstatvfs(l, SCARG(uap, fhp), SCARG(uap, fh_size), sb,
|
|
|
|
SCARG(uap, flags));
|
|
|
|
if (error == 0)
|
|
|
|
error = copyout(sb, SCARG(uap, buf), sizeof(*sb));
|
|
|
|
STATVFSBUF_PUT(sb);
|
|
|
|
return error;
|
2006-08-04 20:29:51 +04:00
|
|
|
}
|
|
|
|
|
1994-06-29 10:29:24 +04:00
|
|
|
/*
|
|
|
|
* Create a special file.
|
|
|
|
*/
|
|
|
|
/* ARGSUSED */
|
1996-02-04 05:17:43 +03:00
|
|
|
int
|
2009-01-11 05:45:45 +03:00
|
|
|
sys___mknod50(struct lwp *l, const struct sys___mknod50_args *uap,
|
|
|
|
register_t *retval)
|
1995-09-20 01:40:36 +04:00
|
|
|
{
|
2007-12-21 02:02:38 +03:00
|
|
|
/* {
|
1996-12-22 13:21:06 +03:00
|
|
|
syscallarg(const char *) path;
|
2009-01-11 05:45:45 +03:00
|
|
|
syscallarg(mode_t) mode;
|
|
|
|
syscallarg(dev_t) dev;
|
2007-12-21 02:02:38 +03:00
|
|
|
} */
|
Add most system calls for POSIX extended API set, part 2, with test cases:
faccessat(2), fchmodat(2), fchownat(2), fstatat(2), mkdirat(2), mkfifoat(2),
mknodat(2), linkat(2), readlinkat(2), symlinkat(2), renameat(2), unlinkat(2),
utimensat(2), openat(2).
Also implement O_SEARCH for openat(2)
Still missing:
- some flags for openat(2)
- fexecve(2) implementation
2012-11-18 21:41:51 +04:00
|
|
|
return do_sys_mknodat(l, AT_FDCWD, SCARG(uap, path), SCARG(uap, mode),
|
2009-08-10 02:49:00 +04:00
|
|
|
SCARG(uap, dev), retval, UIO_USERSPACE);
|
2009-01-11 05:45:45 +03:00
|
|
|
}
|
|
|
|
|
2011-08-08 16:08:52 +04:00
|
|
|
int
|
|
|
|
sys_mknodat(struct lwp *l, const struct sys_mknodat_args *uap,
|
|
|
|
register_t *retval)
|
|
|
|
{
|
|
|
|
/* {
|
|
|
|
syscallarg(int) fd;
|
|
|
|
syscallarg(const char *) path;
|
|
|
|
syscallarg(mode_t) mode;
|
|
|
|
syscallarg(uint32_t) dev;
|
|
|
|
} */
|
|
|
|
|
Add most system calls for POSIX extended API set, part 2, with test cases:
faccessat(2), fchmodat(2), fchownat(2), fstatat(2), mkdirat(2), mkfifoat(2),
mknodat(2), linkat(2), readlinkat(2), symlinkat(2), renameat(2), unlinkat(2),
utimensat(2), openat(2).
Also implement O_SEARCH for openat(2)
Still missing:
- some flags for openat(2)
- fexecve(2) implementation
2012-11-18 21:41:51 +04:00
|
|
|
return do_sys_mknodat(l, SCARG(uap, fd), SCARG(uap, path),
|
|
|
|
SCARG(uap, mode), SCARG(uap, dev), retval, UIO_USERSPACE);
|
2011-08-08 16:08:52 +04:00
|
|
|
}
|
|
|
|
|
2009-01-11 05:45:45 +03:00
|
|
|
int
|
|
|
|
do_sys_mknod(struct lwp *l, const char *pathname, mode_t mode, dev_t dev,
|
2009-08-10 02:49:00 +04:00
|
|
|
register_t *retval, enum uio_seg seg)
|
Add most system calls for POSIX extended API set, part 2, with test cases:
faccessat(2), fchmodat(2), fchownat(2), fstatat(2), mkdirat(2), mkfifoat(2),
mknodat(2), linkat(2), readlinkat(2), symlinkat(2), renameat(2), unlinkat(2),
utimensat(2), openat(2).
Also implement O_SEARCH for openat(2)
Still missing:
- some flags for openat(2)
- fexecve(2) implementation
2012-11-18 21:41:51 +04:00
|
|
|
{
|
|
|
|
return do_sys_mknodat(l, AT_FDCWD, pathname, mode, dev, retval, seg);
|
|
|
|
}
|
|
|
|
|
|
|
|
int
|
|
|
|
do_sys_mknodat(struct lwp *l, int fdat, const char *pathname, mode_t mode,
|
|
|
|
dev_t dev, register_t *retval, enum uio_seg seg)
|
2009-01-11 05:45:45 +03:00
|
|
|
{
|
2003-01-18 13:06:22 +03:00
|
|
|
struct proc *p = l->l_proc;
|
2000-03-30 13:27:11 +04:00
|
|
|
struct vnode *vp;
|
1994-06-29 10:29:24 +04:00
|
|
|
struct vattr vattr;
|
2007-02-18 22:57:29 +03:00
|
|
|
int error, optype;
|
2010-11-19 09:44:33 +03:00
|
|
|
struct pathbuf *pb;
|
1994-06-29 10:29:24 +04:00
|
|
|
struct nameidata nd;
|
2010-11-19 09:44:33 +03:00
|
|
|
const char *pathstring;
|
1994-06-29 10:29:24 +04:00
|
|
|
|
First take at security model abstraction.
- Add a few scopes to the kernel: system, network, and machdep.
- Add a few more actions/sub-actions (requests), and start using them as
opposed to the KAUTH_GENERIC_ISSUSER place-holders.
- Introduce a basic set of listeners that implement our "traditional"
security model, called "bsd44". This is the default (and only) model we
have at the moment.
- Update all relevant documentation.
- Add some code and docs to help folks who want to actually use this stuff:
* There's a sample overlay model, sitting on-top of "bsd44", for
fast experimenting with tweaking just a subset of an existing model.
This is pretty cool because it's *really* straightforward to do stuff
you had to use ugly hacks for until now...
* And of course, documentation describing how to do the above for quick
reference, including code samples.
All of these changes were tested for regressions using a Python-based
testsuite that will be (I hope) available soon via pkgsrc. Information
about the tests, and how to write new ones, can be found on:
http://kauth.linbsd.org/kauthwiki
NOTE FOR DEVELOPERS: *PLEASE* don't add any code that does any of the
following:
- Uses a KAUTH_GENERIC_ISSUSER kauth(9) request,
- Checks 'securelevel' directly,
- Checks a uid/gid directly.
(or if you feel you have to, contact me first)
This is still work in progress; It's far from being done, but now it'll
be a lot easier.
Relevant mailing list threads:
http://mail-index.netbsd.org/tech-security/2006/01/25/0011.html
http://mail-index.netbsd.org/tech-security/2006/03/24/0001.html
http://mail-index.netbsd.org/tech-security/2006/04/18/0000.html
http://mail-index.netbsd.org/tech-security/2006/05/15/0000.html
http://mail-index.netbsd.org/tech-security/2006/08/01/0000.html
http://mail-index.netbsd.org/tech-security/2006/08/25/0000.html
Many thanks to YAMAMOTO Takashi, Matt Thomas, and Christos Zoulas for help
stablizing kauth(9).
Full credit for the regression tests, making sure these changes didn't break
anything, goes to Matt Fleming and Jaime Fournier.
Happy birthday Randi! :)
2006-09-09 00:58:56 +04:00
|
|
|
if ((error = kauth_authorize_system(l->l_cred, KAUTH_SYSTEM_MKNOD,
|
|
|
|
0, NULL, NULL, NULL)) != 0)
|
1994-06-29 10:29:24 +04:00
|
|
|
return (error);
|
2007-02-18 22:57:29 +03:00
|
|
|
|
|
|
|
optype = VOP_MKNOD_DESCOFFSET;
|
2007-05-20 02:11:22 +04:00
|
|
|
|
2010-11-19 09:44:33 +03:00
|
|
|
error = pathbuf_maybe_copyin(pathname, seg, &pb);
|
|
|
|
if (error) {
|
|
|
|
return error;
|
|
|
|
}
|
|
|
|
pathstring = pathbuf_stringcopy_get(pb);
|
|
|
|
if (pathstring == NULL) {
|
|
|
|
pathbuf_destroy(pb);
|
|
|
|
return ENOMEM;
|
|
|
|
}
|
2007-05-20 02:11:22 +04:00
|
|
|
|
2010-11-19 09:44:33 +03:00
|
|
|
NDINIT(&nd, CREATE, LOCKPARENT | TRYEMULROOT, pb);
|
Add most system calls for POSIX extended API set, part 2, with test cases:
faccessat(2), fchmodat(2), fchownat(2), fstatat(2), mkdirat(2), mkfifoat(2),
mknodat(2), linkat(2), readlinkat(2), symlinkat(2), renameat(2), unlinkat(2),
utimensat(2), openat(2).
Also implement O_SEARCH for openat(2)
Still missing:
- some flags for openat(2)
- fexecve(2) implementation
2012-11-18 21:41:51 +04:00
|
|
|
|
|
|
|
if ((error = fd_nameiat(l, fdat, &nd)) != 0)
|
2007-05-17 04:46:30 +04:00
|
|
|
goto out;
|
1994-06-29 10:29:24 +04:00
|
|
|
vp = nd.ni_vp;
|
2010-11-19 09:44:33 +03:00
|
|
|
|
1994-12-14 19:30:40 +03:00
|
|
|
if (vp != NULL)
|
1994-06-29 10:29:24 +04:00
|
|
|
error = EEXIST;
|
1994-12-14 19:30:40 +03:00
|
|
|
else {
|
2010-01-08 14:35:07 +03:00
|
|
|
vattr_null(&vattr);
|
2007-10-08 19:12:05 +04:00
|
|
|
/* We will read cwdi->cwdi_cmask unlocked. */
|
2009-01-11 05:45:45 +03:00
|
|
|
vattr.va_mode = (mode & ALLPERMS) &~ p->p_cwdi->cwdi_cmask;
|
|
|
|
vattr.va_rdev = dev;
|
1994-06-29 10:29:24 +04:00
|
|
|
|
2009-01-11 05:45:45 +03:00
|
|
|
switch (mode & S_IFMT) {
|
1994-12-14 19:30:40 +03:00
|
|
|
case S_IFMT: /* used by badsect to flag bad sectors */
|
|
|
|
vattr.va_type = VBAD;
|
|
|
|
break;
|
|
|
|
case S_IFCHR:
|
|
|
|
vattr.va_type = VCHR;
|
|
|
|
break;
|
|
|
|
case S_IFBLK:
|
|
|
|
vattr.va_type = VBLK;
|
|
|
|
break;
|
|
|
|
case S_IFWHT:
|
2007-02-18 22:57:29 +03:00
|
|
|
optype = VOP_WHITEOUT_DESCOFFSET;
|
|
|
|
break;
|
|
|
|
case S_IFREG:
|
2007-05-17 04:46:30 +04:00
|
|
|
#if NVERIEXEC > 0
|
2010-11-19 09:44:33 +03:00
|
|
|
error = veriexec_openchk(l, nd.ni_vp, pathstring,
|
2007-05-17 04:46:30 +04:00
|
|
|
O_CREAT);
|
|
|
|
#endif /* NVERIEXEC > 0 */
|
2007-02-18 22:57:29 +03:00
|
|
|
vattr.va_type = VREG;
|
2007-02-18 23:36:36 +03:00
|
|
|
vattr.va_rdev = VNOVAL;
|
2007-02-18 22:57:29 +03:00
|
|
|
optype = VOP_CREATE_DESCOFFSET;
|
1994-12-14 19:30:40 +03:00
|
|
|
break;
|
|
|
|
default:
|
|
|
|
error = EINVAL;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
2011-07-24 13:40:10 +04:00
|
|
|
if (error == 0 && optype == VOP_MKNOD_DESCOFFSET
|
|
|
|
&& vattr.va_rdev == VNOVAL)
|
2011-07-03 19:25:09 +04:00
|
|
|
error = EINVAL;
|
1994-12-14 19:30:40 +03:00
|
|
|
if (!error) {
|
2007-02-18 22:57:29 +03:00
|
|
|
switch (optype) {
|
|
|
|
case VOP_WHITEOUT_DESCOFFSET:
|
1994-12-14 19:30:40 +03:00
|
|
|
error = VOP_WHITEOUT(nd.ni_dvp, &nd.ni_cnd, CREATE);
|
|
|
|
if (error)
|
|
|
|
VOP_ABORTOP(nd.ni_dvp, &nd.ni_cnd);
|
|
|
|
vput(nd.ni_dvp);
|
2007-02-18 22:57:29 +03:00
|
|
|
break;
|
|
|
|
|
|
|
|
case VOP_MKNOD_DESCOFFSET:
|
1994-12-14 19:30:40 +03:00
|
|
|
error = VOP_MKNOD(nd.ni_dvp, &nd.ni_vp,
|
|
|
|
&nd.ni_cnd, &vattr);
|
2001-07-24 19:39:30 +04:00
|
|
|
if (error == 0)
|
|
|
|
vput(nd.ni_vp);
|
2007-02-18 22:57:29 +03:00
|
|
|
break;
|
|
|
|
|
|
|
|
case VOP_CREATE_DESCOFFSET:
|
|
|
|
error = VOP_CREATE(nd.ni_dvp, &nd.ni_vp,
|
|
|
|
&nd.ni_cnd, &vattr);
|
|
|
|
if (error == 0)
|
|
|
|
vput(nd.ni_vp);
|
|
|
|
break;
|
1994-12-14 19:30:40 +03:00
|
|
|
}
|
|
|
|
} else {
|
|
|
|
VOP_ABORTOP(nd.ni_dvp, &nd.ni_cnd);
|
|
|
|
if (nd.ni_dvp == vp)
|
|
|
|
vrele(nd.ni_dvp);
|
|
|
|
else
|
|
|
|
vput(nd.ni_dvp);
|
|
|
|
if (vp)
|
|
|
|
vrele(vp);
|
1994-06-29 10:29:24 +04:00
|
|
|
}
|
2007-05-17 04:46:30 +04:00
|
|
|
out:
|
2010-11-19 09:44:33 +03:00
|
|
|
pathbuf_stringcopy_put(pb, pathstring);
|
|
|
|
pathbuf_destroy(pb);
|
1994-06-29 10:29:24 +04:00
|
|
|
return (error);
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Create a named pipe.
|
|
|
|
*/
|
|
|
|
/* ARGSUSED */
|
1996-02-04 05:17:43 +03:00
|
|
|
int
|
2007-12-21 02:02:38 +03:00
|
|
|
sys_mkfifo(struct lwp *l, const struct sys_mkfifo_args *uap, register_t *retval)
|
1995-09-20 01:40:36 +04:00
|
|
|
{
|
2007-12-21 02:02:38 +03:00
|
|
|
/* {
|
1996-12-22 13:21:06 +03:00
|
|
|
syscallarg(const char *) path;
|
1994-10-20 07:22:35 +03:00
|
|
|
syscallarg(int) mode;
|
2007-12-21 02:02:38 +03:00
|
|
|
} */
|
Add most system calls for POSIX extended API set, part 2, with test cases:
faccessat(2), fchmodat(2), fchownat(2), fstatat(2), mkdirat(2), mkfifoat(2),
mknodat(2), linkat(2), readlinkat(2), symlinkat(2), renameat(2), unlinkat(2),
utimensat(2), openat(2).
Also implement O_SEARCH for openat(2)
Still missing:
- some flags for openat(2)
- fexecve(2) implementation
2012-11-18 21:41:51 +04:00
|
|
|
return do_sys_mkfifoat(l, AT_FDCWD, SCARG(uap, path), SCARG(uap, mode));
|
|
|
|
}
|
|
|
|
|
|
|
|
int
|
|
|
|
sys_mkfifoat(struct lwp *l, const struct sys_mkfifoat_args *uap,
|
|
|
|
register_t *retval)
|
|
|
|
{
|
|
|
|
/* {
|
|
|
|
syscallarg(int) fd;
|
|
|
|
syscallarg(const char *) path;
|
|
|
|
syscallarg(int) mode;
|
|
|
|
} */
|
|
|
|
|
|
|
|
return do_sys_mkfifoat(l, SCARG(uap, fd), SCARG(uap, path),
|
|
|
|
SCARG(uap, mode));
|
|
|
|
}
|
|
|
|
|
|
|
|
static int
|
|
|
|
do_sys_mkfifoat(struct lwp *l, int fdat, const char *path, mode_t mode)
|
|
|
|
{
|
2003-01-18 13:06:22 +03:00
|
|
|
struct proc *p = l->l_proc;
|
1994-06-29 10:29:24 +04:00
|
|
|
struct vattr vattr;
|
|
|
|
int error;
|
2010-11-19 09:44:33 +03:00
|
|
|
struct pathbuf *pb;
|
1994-06-29 10:29:24 +04:00
|
|
|
struct nameidata nd;
|
|
|
|
|
Add most system calls for POSIX extended API set, part 2, with test cases:
faccessat(2), fchmodat(2), fchownat(2), fstatat(2), mkdirat(2), mkfifoat(2),
mknodat(2), linkat(2), readlinkat(2), symlinkat(2), renameat(2), unlinkat(2),
utimensat(2), openat(2).
Also implement O_SEARCH for openat(2)
Still missing:
- some flags for openat(2)
- fexecve(2) implementation
2012-11-18 21:41:51 +04:00
|
|
|
error = pathbuf_copyin(path, &pb);
|
2010-11-19 09:44:33 +03:00
|
|
|
if (error) {
|
|
|
|
return error;
|
|
|
|
}
|
|
|
|
NDINIT(&nd, CREATE, LOCKPARENT | TRYEMULROOT, pb);
|
Add most system calls for POSIX extended API set, part 2, with test cases:
faccessat(2), fchmodat(2), fchownat(2), fstatat(2), mkdirat(2), mkfifoat(2),
mknodat(2), linkat(2), readlinkat(2), symlinkat(2), renameat(2), unlinkat(2),
utimensat(2), openat(2).
Also implement O_SEARCH for openat(2)
Still missing:
- some flags for openat(2)
- fexecve(2) implementation
2012-11-18 21:41:51 +04:00
|
|
|
|
|
|
|
if ((error = fd_nameiat(l, fdat, &nd)) != 0) {
|
2010-11-19 09:44:33 +03:00
|
|
|
pathbuf_destroy(pb);
|
|
|
|
return error;
|
|
|
|
}
|
1994-06-29 10:29:24 +04:00
|
|
|
if (nd.ni_vp != NULL) {
|
|
|
|
VOP_ABORTOP(nd.ni_dvp, &nd.ni_cnd);
|
|
|
|
if (nd.ni_dvp == nd.ni_vp)
|
|
|
|
vrele(nd.ni_dvp);
|
|
|
|
else
|
|
|
|
vput(nd.ni_dvp);
|
|
|
|
vrele(nd.ni_vp);
|
2010-11-19 09:44:33 +03:00
|
|
|
pathbuf_destroy(pb);
|
1994-06-29 10:29:24 +04:00
|
|
|
return (EEXIST);
|
|
|
|
}
|
2010-01-08 14:35:07 +03:00
|
|
|
vattr_null(&vattr);
|
1994-06-29 10:29:24 +04:00
|
|
|
vattr.va_type = VFIFO;
|
2007-10-08 19:12:05 +04:00
|
|
|
/* We will read cwdi->cwdi_cmask unlocked. */
|
Add most system calls for POSIX extended API set, part 2, with test cases:
faccessat(2), fchmodat(2), fchownat(2), fstatat(2), mkdirat(2), mkfifoat(2),
mknodat(2), linkat(2), readlinkat(2), symlinkat(2), renameat(2), unlinkat(2),
utimensat(2), openat(2).
Also implement O_SEARCH for openat(2)
Still missing:
- some flags for openat(2)
- fexecve(2) implementation
2012-11-18 21:41:51 +04:00
|
|
|
vattr.va_mode = (mode & ALLPERMS) &~ p->p_cwdi->cwdi_cmask;
|
2001-07-24 19:39:30 +04:00
|
|
|
error = VOP_MKNOD(nd.ni_dvp, &nd.ni_vp, &nd.ni_cnd, &vattr);
|
|
|
|
if (error == 0)
|
|
|
|
vput(nd.ni_vp);
|
2010-11-19 09:44:33 +03:00
|
|
|
pathbuf_destroy(pb);
|
2001-07-24 19:39:30 +04:00
|
|
|
return (error);
|
1994-06-29 10:29:24 +04:00
|
|
|
}
|
|
|
|
|
2011-08-08 16:08:52 +04:00
|
|
|
/*
|
|
|
|
* Make a hard file link.
|
|
|
|
*/
|
|
|
|
/* ARGSUSED */
|
|
|
|
static int
|
Add most system calls for POSIX extended API set, part 2, with test cases:
faccessat(2), fchmodat(2), fchownat(2), fstatat(2), mkdirat(2), mkfifoat(2),
mknodat(2), linkat(2), readlinkat(2), symlinkat(2), renameat(2), unlinkat(2),
utimensat(2), openat(2).
Also implement O_SEARCH for openat(2)
Still missing:
- some flags for openat(2)
- fexecve(2) implementation
2012-11-18 21:41:51 +04:00
|
|
|
do_sys_linkat(struct lwp *l, int fdpath, const char *path, int fdlink,
|
|
|
|
const char *link, int follow, register_t *retval)
|
2011-08-08 16:08:52 +04:00
|
|
|
{
|
2000-03-30 13:27:11 +04:00
|
|
|
struct vnode *vp;
|
2010-11-19 09:44:33 +03:00
|
|
|
struct pathbuf *linkpb;
|
1994-06-29 10:29:24 +04:00
|
|
|
struct nameidata nd;
|
Add most system calls for POSIX extended API set, part 2, with test cases:
faccessat(2), fchmodat(2), fchownat(2), fstatat(2), mkdirat(2), mkfifoat(2),
mknodat(2), linkat(2), readlinkat(2), symlinkat(2), renameat(2), unlinkat(2),
utimensat(2), openat(2).
Also implement O_SEARCH for openat(2)
Still missing:
- some flags for openat(2)
- fexecve(2) implementation
2012-11-18 21:41:51 +04:00
|
|
|
namei_simple_flags_t ns_flags;
|
1994-06-29 10:29:24 +04:00
|
|
|
int error;
|
|
|
|
|
Add most system calls for POSIX extended API set, part 2, with test cases:
faccessat(2), fchmodat(2), fchownat(2), fstatat(2), mkdirat(2), mkfifoat(2),
mknodat(2), linkat(2), readlinkat(2), symlinkat(2), renameat(2), unlinkat(2),
utimensat(2), openat(2).
Also implement O_SEARCH for openat(2)
Still missing:
- some flags for openat(2)
- fexecve(2) implementation
2012-11-18 21:41:51 +04:00
|
|
|
if (follow & AT_SYMLINK_FOLLOW)
|
|
|
|
ns_flags = NSM_FOLLOW_TRYEMULROOT;
|
2011-08-08 16:08:52 +04:00
|
|
|
else
|
Add most system calls for POSIX extended API set, part 2, with test cases:
faccessat(2), fchmodat(2), fchownat(2), fstatat(2), mkdirat(2), mkfifoat(2),
mknodat(2), linkat(2), readlinkat(2), symlinkat(2), renameat(2), unlinkat(2),
utimensat(2), openat(2).
Also implement O_SEARCH for openat(2)
Still missing:
- some flags for openat(2)
- fexecve(2) implementation
2012-11-18 21:41:51 +04:00
|
|
|
ns_flags = NSM_NOFOLLOW_TRYEMULROOT;
|
2011-08-08 16:08:52 +04:00
|
|
|
|
Add most system calls for POSIX extended API set, part 2, with test cases:
faccessat(2), fchmodat(2), fchownat(2), fstatat(2), mkdirat(2), mkfifoat(2),
mknodat(2), linkat(2), readlinkat(2), symlinkat(2), renameat(2), unlinkat(2),
utimensat(2), openat(2).
Also implement O_SEARCH for openat(2)
Still missing:
- some flags for openat(2)
- fexecve(2) implementation
2012-11-18 21:41:51 +04:00
|
|
|
error = fd_nameiat_simple_user(l, fdpath, path, ns_flags, &vp);
|
Convert 67 namei call sites to use namei_simple, in these functions:
check_console, veriexecclose, veriexec_delete, veriexec_file_add,
emul_find_root, coff_load_shlib (sh3 version), coff_load_shlib,
compat_20_sys_statfs, compat_20_netbsd32_statfs,
ELFNAME2(netbsd32,probe_noteless), darwin_sys_statfs,
ibcs2_sys_statfs, ibcs2_sys_statvfs, linux_sys_uselib,
osf1_sys_statfs, sunos_sys_statfs, sunos32_sys_statfs,
ultrix_sys_statfs, do_sys_mount, fss_create_files (3 of 4),
adosfs_mount, cd9660_mount, coda_ioctl, coda_mount, ext2fs_mount,
ffs_mount, filecore_mount, hfs_mount, lfs_mount, msdosfs_mount,
ntfs_mount, sysvbfs_mount, udf_mount, union_mount, sys_chflags,
sys_lchflags, sys_chmod, sys_lchmod, sys_chown, sys_lchown,
sys___posix_chown, sys___posix_lchown, sys_link, do_sys_pstatvfs,
sys_quotactl, sys_revoke, sys_truncate, do_sys_utimes, sys_extattrctl,
sys_extattr_set_file, sys_extattr_set_link, sys_extattr_get_file,
sys_extattr_get_link, sys_extattr_delete_file,
sys_extattr_delete_link, sys_extattr_list_file, sys_extattr_list_link,
sys_setxattr, sys_lsetxattr, sys_getxattr, sys_lgetxattr,
sys_listxattr, sys_llistxattr, sys_removexattr, sys_lremovexattr
All have been scrutinized (several times, in fact) and compile-tested,
but not all have been explicitly tested in action.
XXX: While I haven't (intentionally) changed the use or nonuse of
XXX: TRYEMULROOT in any of these places, I'm not convinced all the
XXX: uses are correct; an audit might be desirable.
2009-06-29 09:08:15 +04:00
|
|
|
if (error != 0)
|
1994-06-29 10:29:24 +04:00
|
|
|
return (error);
|
2011-08-08 16:08:52 +04:00
|
|
|
error = pathbuf_copyin(link, &linkpb);
|
2010-11-19 09:44:33 +03:00
|
|
|
if (error) {
|
|
|
|
goto out1;
|
|
|
|
}
|
|
|
|
NDINIT(&nd, CREATE, LOCKPARENT | TRYEMULROOT, linkpb);
|
Add most system calls for POSIX extended API set, part 2, with test cases:
faccessat(2), fchmodat(2), fchownat(2), fstatat(2), mkdirat(2), mkfifoat(2),
mknodat(2), linkat(2), readlinkat(2), symlinkat(2), renameat(2), unlinkat(2),
utimensat(2), openat(2).
Also implement O_SEARCH for openat(2)
Still missing:
- some flags for openat(2)
- fexecve(2) implementation
2012-11-18 21:41:51 +04:00
|
|
|
if ((error = fd_nameiat(l, fdlink, &nd)) != 0)
|
2010-11-19 09:44:33 +03:00
|
|
|
goto out2;
|
1996-02-09 17:45:36 +03:00
|
|
|
if (nd.ni_vp) {
|
|
|
|
error = EEXIST;
|
2011-03-12 10:16:50 +03:00
|
|
|
goto abortop;
|
|
|
|
}
|
2011-04-25 01:35:29 +04:00
|
|
|
/* Prevent hard links on directories. */
|
|
|
|
if (vp->v_type == VDIR) {
|
|
|
|
error = EPERM;
|
|
|
|
goto abortop;
|
|
|
|
}
|
|
|
|
/* Prevent cross-mount operation. */
|
2011-03-12 10:16:50 +03:00
|
|
|
if (nd.ni_dvp->v_mount != vp->v_mount) {
|
|
|
|
error = EXDEV;
|
|
|
|
goto abortop;
|
1994-06-29 10:29:24 +04:00
|
|
|
}
|
1996-02-09 17:45:36 +03:00
|
|
|
error = VOP_LINK(nd.ni_dvp, vp, &nd.ni_cnd);
|
2010-11-19 09:44:33 +03:00
|
|
|
out2:
|
|
|
|
pathbuf_destroy(linkpb);
|
|
|
|
out1:
|
1994-06-29 10:29:24 +04:00
|
|
|
vrele(vp);
|
|
|
|
return (error);
|
2011-03-12 10:16:50 +03:00
|
|
|
abortop:
|
|
|
|
VOP_ABORTOP(nd.ni_dvp, &nd.ni_cnd);
|
|
|
|
if (nd.ni_dvp == nd.ni_vp)
|
|
|
|
vrele(nd.ni_dvp);
|
|
|
|
else
|
|
|
|
vput(nd.ni_dvp);
|
|
|
|
if (nd.ni_vp != NULL)
|
|
|
|
vrele(nd.ni_vp);
|
|
|
|
goto out2;
|
1994-06-29 10:29:24 +04:00
|
|
|
}
|
|
|
|
|
2011-08-08 16:08:52 +04:00
|
|
|
int
|
|
|
|
sys_link(struct lwp *l, const struct sys_link_args *uap, register_t *retval)
|
|
|
|
{
|
|
|
|
/* {
|
|
|
|
syscallarg(const char *) path;
|
|
|
|
syscallarg(const char *) link;
|
|
|
|
} */
|
|
|
|
const char *path = SCARG(uap, path);
|
|
|
|
const char *link = SCARG(uap, link);
|
|
|
|
|
Add most system calls for POSIX extended API set, part 2, with test cases:
faccessat(2), fchmodat(2), fchownat(2), fstatat(2), mkdirat(2), mkfifoat(2),
mknodat(2), linkat(2), readlinkat(2), symlinkat(2), renameat(2), unlinkat(2),
utimensat(2), openat(2).
Also implement O_SEARCH for openat(2)
Still missing:
- some flags for openat(2)
- fexecve(2) implementation
2012-11-18 21:41:51 +04:00
|
|
|
return do_sys_linkat(l, AT_FDCWD, path, AT_FDCWD, link,
|
|
|
|
AT_SYMLINK_FOLLOW, retval);
|
2011-08-08 16:08:52 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
int
|
|
|
|
sys_linkat(struct lwp *l, const struct sys_linkat_args *uap,
|
|
|
|
register_t *retval)
|
|
|
|
{
|
|
|
|
/* {
|
|
|
|
syscallarg(int) fd1;
|
|
|
|
syscallarg(const char *) name1;
|
|
|
|
syscallarg(int) fd2;
|
|
|
|
syscallarg(const char *) name2;
|
|
|
|
syscallarg(int) flags;
|
|
|
|
} */
|
Add most system calls for POSIX extended API set, part 2, with test cases:
faccessat(2), fchmodat(2), fchownat(2), fstatat(2), mkdirat(2), mkfifoat(2),
mknodat(2), linkat(2), readlinkat(2), symlinkat(2), renameat(2), unlinkat(2),
utimensat(2), openat(2).
Also implement O_SEARCH for openat(2)
Still missing:
- some flags for openat(2)
- fexecve(2) implementation
2012-11-18 21:41:51 +04:00
|
|
|
int fd1 = SCARG(uap, fd1);
|
2011-08-08 16:08:52 +04:00
|
|
|
const char *name1 = SCARG(uap, name1);
|
Add most system calls for POSIX extended API set, part 2, with test cases:
faccessat(2), fchmodat(2), fchownat(2), fstatat(2), mkdirat(2), mkfifoat(2),
mknodat(2), linkat(2), readlinkat(2), symlinkat(2), renameat(2), unlinkat(2),
utimensat(2), openat(2).
Also implement O_SEARCH for openat(2)
Still missing:
- some flags for openat(2)
- fexecve(2) implementation
2012-11-18 21:41:51 +04:00
|
|
|
int fd2 = SCARG(uap, fd2);
|
2011-08-08 16:08:52 +04:00
|
|
|
const char *name2 = SCARG(uap, name2);
|
|
|
|
int follow;
|
|
|
|
|
|
|
|
follow = SCARG(uap, flags) & AT_SYMLINK_FOLLOW;
|
|
|
|
|
Add most system calls for POSIX extended API set, part 2, with test cases:
faccessat(2), fchmodat(2), fchownat(2), fstatat(2), mkdirat(2), mkfifoat(2),
mknodat(2), linkat(2), readlinkat(2), symlinkat(2), renameat(2), unlinkat(2),
utimensat(2), openat(2).
Also implement O_SEARCH for openat(2)
Still missing:
- some flags for openat(2)
- fexecve(2) implementation
2012-11-18 21:41:51 +04:00
|
|
|
return do_sys_linkat(l, fd1, name1, fd2, name2, follow, retval);
|
2011-08-08 16:08:52 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
|
1996-02-04 05:17:43 +03:00
|
|
|
int
|
2010-06-30 19:44:54 +04:00
|
|
|
do_sys_symlink(const char *patharg, const char *link, enum uio_seg seg)
|
Add most system calls for POSIX extended API set, part 2, with test cases:
faccessat(2), fchmodat(2), fchownat(2), fstatat(2), mkdirat(2), mkfifoat(2),
mknodat(2), linkat(2), readlinkat(2), symlinkat(2), renameat(2), unlinkat(2),
utimensat(2), openat(2).
Also implement O_SEARCH for openat(2)
Still missing:
- some flags for openat(2)
- fexecve(2) implementation
2012-11-18 21:41:51 +04:00
|
|
|
{
|
|
|
|
return do_sys_symlinkat(NULL, patharg, AT_FDCWD, link, seg);
|
|
|
|
}
|
|
|
|
|
|
|
|
static int
|
|
|
|
do_sys_symlinkat(struct lwp *l, const char *patharg, int fdat,
|
|
|
|
const char *link, enum uio_seg seg)
|
1995-09-20 01:40:36 +04:00
|
|
|
{
|
2010-06-30 19:44:54 +04:00
|
|
|
struct proc *p = curproc;
|
1994-06-29 10:29:24 +04:00
|
|
|
struct vattr vattr;
|
|
|
|
char *path;
|
|
|
|
int error;
|
2010-11-19 09:44:33 +03:00
|
|
|
struct pathbuf *linkpb;
|
1994-06-29 10:29:24 +04:00
|
|
|
struct nameidata nd;
|
|
|
|
|
Add most system calls for POSIX extended API set, part 2, with test cases:
faccessat(2), fchmodat(2), fchownat(2), fstatat(2), mkdirat(2), mkfifoat(2),
mknodat(2), linkat(2), readlinkat(2), symlinkat(2), renameat(2), unlinkat(2),
utimensat(2), openat(2).
Also implement O_SEARCH for openat(2)
Still missing:
- some flags for openat(2)
- fexecve(2) implementation
2012-11-18 21:41:51 +04:00
|
|
|
KASSERT(l != NULL || fdat == AT_FDCWD);
|
|
|
|
|
2000-08-04 00:41:05 +04:00
|
|
|
path = PNBUF_GET();
|
2010-06-30 19:44:54 +04:00
|
|
|
if (seg == UIO_USERSPACE) {
|
|
|
|
if ((error = copyinstr(patharg, path, MAXPATHLEN, NULL)) != 0)
|
2010-11-19 09:44:33 +03:00
|
|
|
goto out1;
|
|
|
|
if ((error = pathbuf_copyin(link, &linkpb)) != 0)
|
|
|
|
goto out1;
|
2010-06-30 19:44:54 +04:00
|
|
|
} else {
|
|
|
|
KASSERT(strlen(patharg) < MAXPATHLEN);
|
|
|
|
strcpy(path, patharg);
|
2010-11-19 09:44:33 +03:00
|
|
|
linkpb = pathbuf_create(link);
|
|
|
|
if (linkpb == NULL) {
|
|
|
|
error = ENOMEM;
|
|
|
|
goto out1;
|
|
|
|
}
|
2010-06-30 19:44:54 +04:00
|
|
|
}
|
2011-08-08 16:08:52 +04:00
|
|
|
ktrkuser("symlink-target", path, strlen(path));
|
|
|
|
|
2010-11-19 09:44:33 +03:00
|
|
|
NDINIT(&nd, CREATE, LOCKPARENT | TRYEMULROOT, linkpb);
|
Add most system calls for POSIX extended API set, part 2, with test cases:
faccessat(2), fchmodat(2), fchownat(2), fstatat(2), mkdirat(2), mkfifoat(2),
mknodat(2), linkat(2), readlinkat(2), symlinkat(2), renameat(2), unlinkat(2),
utimensat(2), openat(2).
Also implement O_SEARCH for openat(2)
Still missing:
- some flags for openat(2)
- fexecve(2) implementation
2012-11-18 21:41:51 +04:00
|
|
|
if ((error = fd_nameiat(l, fdat, &nd)) != 0)
|
2010-11-19 09:44:33 +03:00
|
|
|
goto out2;
|
1994-06-29 10:29:24 +04:00
|
|
|
if (nd.ni_vp) {
|
|
|
|
VOP_ABORTOP(nd.ni_dvp, &nd.ni_cnd);
|
|
|
|
if (nd.ni_dvp == nd.ni_vp)
|
|
|
|
vrele(nd.ni_dvp);
|
|
|
|
else
|
|
|
|
vput(nd.ni_dvp);
|
|
|
|
vrele(nd.ni_vp);
|
|
|
|
error = EEXIST;
|
2010-11-19 09:44:33 +03:00
|
|
|
goto out2;
|
1994-06-29 10:29:24 +04:00
|
|
|
}
|
2010-01-08 14:35:07 +03:00
|
|
|
vattr_null(&vattr);
|
2005-08-30 13:37:41 +04:00
|
|
|
vattr.va_type = VLNK;
|
2007-10-08 19:12:05 +04:00
|
|
|
/* We will read cwdi->cwdi_cmask unlocked. */
|
1999-04-30 22:42:58 +04:00
|
|
|
vattr.va_mode = ACCESSPERMS &~ p->p_cwdi->cwdi_cmask;
|
1994-06-29 10:29:24 +04:00
|
|
|
error = VOP_SYMLINK(nd.ni_dvp, &nd.ni_vp, &nd.ni_cnd, &vattr, path);
|
2001-07-24 19:39:30 +04:00
|
|
|
if (error == 0)
|
|
|
|
vput(nd.ni_vp);
|
2010-11-19 09:44:33 +03:00
|
|
|
out2:
|
|
|
|
pathbuf_destroy(linkpb);
|
|
|
|
out1:
|
2000-08-04 00:41:05 +04:00
|
|
|
PNBUF_PUT(path);
|
1994-06-29 10:29:24 +04:00
|
|
|
return (error);
|
|
|
|
}
|
|
|
|
|
2010-06-30 19:44:54 +04:00
|
|
|
/*
|
|
|
|
* Make a symbolic link.
|
|
|
|
*/
|
|
|
|
/* ARGSUSED */
|
|
|
|
int
|
|
|
|
sys_symlink(struct lwp *l, const struct sys_symlink_args *uap, register_t *retval)
|
|
|
|
{
|
|
|
|
/* {
|
|
|
|
syscallarg(const char *) path;
|
|
|
|
syscallarg(const char *) link;
|
|
|
|
} */
|
|
|
|
|
Add most system calls for POSIX extended API set, part 2, with test cases:
faccessat(2), fchmodat(2), fchownat(2), fstatat(2), mkdirat(2), mkfifoat(2),
mknodat(2), linkat(2), readlinkat(2), symlinkat(2), renameat(2), unlinkat(2),
utimensat(2), openat(2).
Also implement O_SEARCH for openat(2)
Still missing:
- some flags for openat(2)
- fexecve(2) implementation
2012-11-18 21:41:51 +04:00
|
|
|
return do_sys_symlinkat(l, SCARG(uap, path), AT_FDCWD, SCARG(uap, link),
|
2010-06-30 19:44:54 +04:00
|
|
|
UIO_USERSPACE);
|
|
|
|
}
|
|
|
|
|
2011-08-08 16:08:52 +04:00
|
|
|
int
|
|
|
|
sys_symlinkat(struct lwp *l, const struct sys_symlinkat_args *uap,
|
|
|
|
register_t *retval)
|
|
|
|
{
|
|
|
|
/* {
|
Add most system calls for POSIX extended API set, part 2, with test cases:
faccessat(2), fchmodat(2), fchownat(2), fstatat(2), mkdirat(2), mkfifoat(2),
mknodat(2), linkat(2), readlinkat(2), symlinkat(2), renameat(2), unlinkat(2),
utimensat(2), openat(2).
Also implement O_SEARCH for openat(2)
Still missing:
- some flags for openat(2)
- fexecve(2) implementation
2012-11-18 21:41:51 +04:00
|
|
|
syscallarg(const char *) path1;
|
2011-08-08 16:08:52 +04:00
|
|
|
syscallarg(int) fd;
|
Add most system calls for POSIX extended API set, part 2, with test cases:
faccessat(2), fchmodat(2), fchownat(2), fstatat(2), mkdirat(2), mkfifoat(2),
mknodat(2), linkat(2), readlinkat(2), symlinkat(2), renameat(2), unlinkat(2),
utimensat(2), openat(2).
Also implement O_SEARCH for openat(2)
Still missing:
- some flags for openat(2)
- fexecve(2) implementation
2012-11-18 21:41:51 +04:00
|
|
|
syscallarg(const char *) path2;
|
2011-08-08 16:08:52 +04:00
|
|
|
} */
|
|
|
|
|
Add most system calls for POSIX extended API set, part 2, with test cases:
faccessat(2), fchmodat(2), fchownat(2), fstatat(2), mkdirat(2), mkfifoat(2),
mknodat(2), linkat(2), readlinkat(2), symlinkat(2), renameat(2), unlinkat(2),
utimensat(2), openat(2).
Also implement O_SEARCH for openat(2)
Still missing:
- some flags for openat(2)
- fexecve(2) implementation
2012-11-18 21:41:51 +04:00
|
|
|
return do_sys_symlinkat(l, SCARG(uap, path1), SCARG(uap, fd),
|
|
|
|
SCARG(uap, path2), UIO_USERSPACE);
|
2011-08-08 16:08:52 +04:00
|
|
|
}
|
|
|
|
|
1994-12-14 19:30:40 +03:00
|
|
|
/*
|
|
|
|
* Delete a whiteout from the filesystem.
|
|
|
|
*/
|
|
|
|
/* ARGSUSED */
|
1996-02-04 05:17:43 +03:00
|
|
|
int
|
2007-12-21 02:02:38 +03:00
|
|
|
sys_undelete(struct lwp *l, const struct sys_undelete_args *uap, register_t *retval)
|
1994-12-14 19:30:40 +03:00
|
|
|
{
|
2007-12-21 02:02:38 +03:00
|
|
|
/* {
|
1996-12-22 13:21:06 +03:00
|
|
|
syscallarg(const char *) path;
|
2007-12-21 02:02:38 +03:00
|
|
|
} */
|
1994-12-14 19:30:40 +03:00
|
|
|
int error;
|
2010-11-19 09:44:33 +03:00
|
|
|
struct pathbuf *pb;
|
1994-12-14 19:30:40 +03:00
|
|
|
struct nameidata nd;
|
|
|
|
|
2010-11-19 09:44:33 +03:00
|
|
|
error = pathbuf_copyin(SCARG(uap, path), &pb);
|
|
|
|
if (error) {
|
|
|
|
return error;
|
|
|
|
}
|
|
|
|
|
|
|
|
NDINIT(&nd, DELETE, LOCKPARENT | DOWHITEOUT | TRYEMULROOT, pb);
|
1994-12-14 19:30:40 +03:00
|
|
|
error = namei(&nd);
|
2010-11-19 09:44:33 +03:00
|
|
|
if (error) {
|
|
|
|
pathbuf_destroy(pb);
|
1994-12-14 19:30:40 +03:00
|
|
|
return (error);
|
2010-11-19 09:44:33 +03:00
|
|
|
}
|
1994-12-14 19:30:40 +03:00
|
|
|
|
|
|
|
if (nd.ni_vp != NULLVP || !(nd.ni_cnd.cn_flags & ISWHITEOUT)) {
|
|
|
|
VOP_ABORTOP(nd.ni_dvp, &nd.ni_cnd);
|
|
|
|
if (nd.ni_dvp == nd.ni_vp)
|
|
|
|
vrele(nd.ni_dvp);
|
|
|
|
else
|
|
|
|
vput(nd.ni_dvp);
|
|
|
|
if (nd.ni_vp)
|
|
|
|
vrele(nd.ni_vp);
|
2010-11-19 09:44:33 +03:00
|
|
|
pathbuf_destroy(pb);
|
1994-12-14 19:30:40 +03:00
|
|
|
return (EEXIST);
|
|
|
|
}
|
1996-02-04 05:17:43 +03:00
|
|
|
if ((error = VOP_WHITEOUT(nd.ni_dvp, &nd.ni_cnd, DELETE)) != 0)
|
1994-12-14 19:30:40 +03:00
|
|
|
VOP_ABORTOP(nd.ni_dvp, &nd.ni_cnd);
|
|
|
|
vput(nd.ni_dvp);
|
2010-11-19 09:44:33 +03:00
|
|
|
pathbuf_destroy(pb);
|
1994-12-14 19:30:40 +03:00
|
|
|
return (error);
|
|
|
|
}
|
|
|
|
|
1994-06-29 10:29:24 +04:00
|
|
|
/*
|
|
|
|
* Delete a name from the filesystem.
|
|
|
|
*/
|
|
|
|
/* ARGSUSED */
|
1996-02-04 05:17:43 +03:00
|
|
|
int
|
2007-12-21 02:02:38 +03:00
|
|
|
sys_unlink(struct lwp *l, const struct sys_unlink_args *uap, register_t *retval)
|
1994-06-29 10:29:24 +04:00
|
|
|
{
|
2007-12-21 02:02:38 +03:00
|
|
|
/* {
|
1996-12-22 13:21:06 +03:00
|
|
|
syscallarg(const char *) path;
|
2007-12-21 02:02:38 +03:00
|
|
|
} */
|
2007-12-24 18:04:19 +03:00
|
|
|
|
Add most system calls for POSIX extended API set, part 2, with test cases:
faccessat(2), fchmodat(2), fchownat(2), fstatat(2), mkdirat(2), mkfifoat(2),
mknodat(2), linkat(2), readlinkat(2), symlinkat(2), renameat(2), unlinkat(2),
utimensat(2), openat(2).
Also implement O_SEARCH for openat(2)
Still missing:
- some flags for openat(2)
- fexecve(2) implementation
2012-11-18 21:41:51 +04:00
|
|
|
return do_sys_unlinkat(l, AT_FDCWD, SCARG(uap, path), 0, UIO_USERSPACE);
|
2007-12-24 18:04:19 +03:00
|
|
|
}
|
|
|
|
|
2011-08-08 16:08:52 +04:00
|
|
|
int
|
|
|
|
sys_unlinkat(struct lwp *l, const struct sys_unlinkat_args *uap,
|
|
|
|
register_t *retval)
|
|
|
|
{
|
|
|
|
/* {
|
|
|
|
syscallarg(int) fd;
|
|
|
|
syscallarg(const char *) path;
|
Add most system calls for POSIX extended API set, part 2, with test cases:
faccessat(2), fchmodat(2), fchownat(2), fstatat(2), mkdirat(2), mkfifoat(2),
mknodat(2), linkat(2), readlinkat(2), symlinkat(2), renameat(2), unlinkat(2),
utimensat(2), openat(2).
Also implement O_SEARCH for openat(2)
Still missing:
- some flags for openat(2)
- fexecve(2) implementation
2012-11-18 21:41:51 +04:00
|
|
|
syscallarg(int) flag;
|
2011-08-08 16:08:52 +04:00
|
|
|
} */
|
|
|
|
|
Add most system calls for POSIX extended API set, part 2, with test cases:
faccessat(2), fchmodat(2), fchownat(2), fstatat(2), mkdirat(2), mkfifoat(2),
mknodat(2), linkat(2), readlinkat(2), symlinkat(2), renameat(2), unlinkat(2),
utimensat(2), openat(2).
Also implement O_SEARCH for openat(2)
Still missing:
- some flags for openat(2)
- fexecve(2) implementation
2012-11-18 21:41:51 +04:00
|
|
|
return do_sys_unlinkat(l, SCARG(uap, fd), SCARG(uap, path),
|
|
|
|
SCARG(uap, flag), UIO_USERSPACE);
|
2011-08-08 16:08:52 +04:00
|
|
|
}
|
|
|
|
|
2007-12-24 18:04:19 +03:00
|
|
|
int
|
|
|
|
do_sys_unlink(const char *arg, enum uio_seg seg)
|
Add most system calls for POSIX extended API set, part 2, with test cases:
faccessat(2), fchmodat(2), fchownat(2), fstatat(2), mkdirat(2), mkfifoat(2),
mknodat(2), linkat(2), readlinkat(2), symlinkat(2), renameat(2), unlinkat(2),
utimensat(2), openat(2).
Also implement O_SEARCH for openat(2)
Still missing:
- some flags for openat(2)
- fexecve(2) implementation
2012-11-18 21:41:51 +04:00
|
|
|
{
|
|
|
|
return do_sys_unlinkat(NULL, AT_FDCWD, arg, 0, seg);
|
|
|
|
}
|
|
|
|
|
|
|
|
static int
|
|
|
|
do_sys_unlinkat(struct lwp *l, int fdat, const char *arg, int flags,
|
|
|
|
enum uio_seg seg)
|
2007-12-24 18:04:19 +03:00
|
|
|
{
|
2000-03-30 13:27:11 +04:00
|
|
|
struct vnode *vp;
|
1994-06-29 10:29:24 +04:00
|
|
|
int error;
|
2010-11-19 09:44:33 +03:00
|
|
|
struct pathbuf *pb;
|
1994-06-29 10:29:24 +04:00
|
|
|
struct nameidata nd;
|
2010-11-19 09:44:33 +03:00
|
|
|
const char *pathstring;
|
Some Veriexec stuff that's been rotting in my tree for months.
Bug fixes:
- Fix crash reported by Scott Ellis on current-users@.
- Fix race conditions in enforcing the Veriexec rename and remove
policies. These are NOT security issues.
- Fix memory leak in rename handling when overwriting a monitored
file.
- Fix table deletion logic.
- Don't prevent query requests if not in learning mode.
KPI updates:
- fileassoc_table_run() now takes a cookie to pass to the callback.
- veriexec_table_add() was removed, it is now done internally. As a
result, there's no longer a need for VERIEXEC_TABLESIZE.
- veriexec_report() was removed, it is now internal.
- Perform sanity checks on the entry type, and enforce default type
in veriexec_file_add() rather than in veriexecctl.
- Add veriexec_flush(), used to delete all Veriexec tables, and
veriexec_dump(), used to fill an array with all Veriexec entries.
New features:
- Add a '-k' flag to veriexecctl, to keep the filenames in the kernel
database. This allows Veriexec to produce slightly more accurate
logs under certain circumstances. In the future, this can be either
replaced by vnode->pathname translation, or combined with it.
- Add a VERIEXEC_DUMP ioctl, to dump the entire Veriexec database.
This can be used to recover a database if the file was lost.
Example usage:
# veriexecctl dump > /etc/signatures
Note that only entries with the filename kept (that is, were loaded
with the '-k' flag) will be dumped.
Idea from Brett Lymn.
- Add a VERIEXEC_FLUSH ioctl, to delete all Veriexec entries. Sample
usage:
# veriexecctl flush
- Add a 'veriexec_flags' rc(8) variable, and make its default have
the '-k' flag. On systems using the default signatures file
(generaetd from running 'veriexecgen' with no arguments), this will
use additional 32kb of kernel memory on average.
- Add a '-e' flag to veriexecctl, to evaluate the fingerprint during
load. This is done automatically for files marked as 'untrusted'.
Misc. stuff:
- The code for veriexecctl was massively simplified as a result of
eliminating the need for VERIEXEC_TABLESIZE, and now uses a single
pass of the signatures file, making the loading somewhat faster.
- Lots of minor fixes found using the (still under development)
Veriexec regression testsuite.
- Some of the messages Veriexec prints were improved.
- Various documentation fixes.
All relevant man-pages were updated to reflect the above changes.
Binary compatibility with existing veriexecctl binaries is maintained.
2007-05-15 23:47:43 +04:00
|
|
|
|
Add most system calls for POSIX extended API set, part 2, with test cases:
faccessat(2), fchmodat(2), fchownat(2), fstatat(2), mkdirat(2), mkfifoat(2),
mknodat(2), linkat(2), readlinkat(2), symlinkat(2), renameat(2), unlinkat(2),
utimensat(2), openat(2).
Also implement O_SEARCH for openat(2)
Still missing:
- some flags for openat(2)
- fexecve(2) implementation
2012-11-18 21:41:51 +04:00
|
|
|
KASSERT(l != NULL || fdat == AT_FDCWD);
|
|
|
|
|
2010-11-19 09:44:33 +03:00
|
|
|
error = pathbuf_maybe_copyin(arg, seg, &pb);
|
|
|
|
if (error) {
|
|
|
|
return error;
|
|
|
|
}
|
|
|
|
pathstring = pathbuf_stringcopy_get(pb);
|
|
|
|
if (pathstring == NULL) {
|
|
|
|
pathbuf_destroy(pb);
|
|
|
|
return ENOMEM;
|
|
|
|
}
|
Some Veriexec stuff that's been rotting in my tree for months.
Bug fixes:
- Fix crash reported by Scott Ellis on current-users@.
- Fix race conditions in enforcing the Veriexec rename and remove
policies. These are NOT security issues.
- Fix memory leak in rename handling when overwriting a monitored
file.
- Fix table deletion logic.
- Don't prevent query requests if not in learning mode.
KPI updates:
- fileassoc_table_run() now takes a cookie to pass to the callback.
- veriexec_table_add() was removed, it is now done internally. As a
result, there's no longer a need for VERIEXEC_TABLESIZE.
- veriexec_report() was removed, it is now internal.
- Perform sanity checks on the entry type, and enforce default type
in veriexec_file_add() rather than in veriexecctl.
- Add veriexec_flush(), used to delete all Veriexec tables, and
veriexec_dump(), used to fill an array with all Veriexec entries.
New features:
- Add a '-k' flag to veriexecctl, to keep the filenames in the kernel
database. This allows Veriexec to produce slightly more accurate
logs under certain circumstances. In the future, this can be either
replaced by vnode->pathname translation, or combined with it.
- Add a VERIEXEC_DUMP ioctl, to dump the entire Veriexec database.
This can be used to recover a database if the file was lost.
Example usage:
# veriexecctl dump > /etc/signatures
Note that only entries with the filename kept (that is, were loaded
with the '-k' flag) will be dumped.
Idea from Brett Lymn.
- Add a VERIEXEC_FLUSH ioctl, to delete all Veriexec entries. Sample
usage:
# veriexecctl flush
- Add a 'veriexec_flags' rc(8) variable, and make its default have
the '-k' flag. On systems using the default signatures file
(generaetd from running 'veriexecgen' with no arguments), this will
use additional 32kb of kernel memory on average.
- Add a '-e' flag to veriexecctl, to evaluate the fingerprint during
load. This is done automatically for files marked as 'untrusted'.
Misc. stuff:
- The code for veriexecctl was massively simplified as a result of
eliminating the need for VERIEXEC_TABLESIZE, and now uses a single
pass of the signatures file, making the loading somewhat faster.
- Lots of minor fixes found using the (still under development)
Veriexec regression testsuite.
- Some of the messages Veriexec prints were improved.
- Various documentation fixes.
All relevant man-pages were updated to reflect the above changes.
Binary compatibility with existing veriexecctl binaries is maintained.
2007-05-15 23:47:43 +04:00
|
|
|
|
2010-11-19 09:44:33 +03:00
|
|
|
NDINIT(&nd, DELETE, LOCKPARENT | LOCKLEAF | TRYEMULROOT, pb);
|
Add most system calls for POSIX extended API set, part 2, with test cases:
faccessat(2), fchmodat(2), fchownat(2), fstatat(2), mkdirat(2), mkfifoat(2),
mknodat(2), linkat(2), readlinkat(2), symlinkat(2), renameat(2), unlinkat(2),
utimensat(2), openat(2).
Also implement O_SEARCH for openat(2)
Still missing:
- some flags for openat(2)
- fexecve(2) implementation
2012-11-18 21:41:51 +04:00
|
|
|
if ((error = fd_nameiat(l, fdat, &nd)) != 0)
|
Some Veriexec stuff that's been rotting in my tree for months.
Bug fixes:
- Fix crash reported by Scott Ellis on current-users@.
- Fix race conditions in enforcing the Veriexec rename and remove
policies. These are NOT security issues.
- Fix memory leak in rename handling when overwriting a monitored
file.
- Fix table deletion logic.
- Don't prevent query requests if not in learning mode.
KPI updates:
- fileassoc_table_run() now takes a cookie to pass to the callback.
- veriexec_table_add() was removed, it is now done internally. As a
result, there's no longer a need for VERIEXEC_TABLESIZE.
- veriexec_report() was removed, it is now internal.
- Perform sanity checks on the entry type, and enforce default type
in veriexec_file_add() rather than in veriexecctl.
- Add veriexec_flush(), used to delete all Veriexec tables, and
veriexec_dump(), used to fill an array with all Veriexec entries.
New features:
- Add a '-k' flag to veriexecctl, to keep the filenames in the kernel
database. This allows Veriexec to produce slightly more accurate
logs under certain circumstances. In the future, this can be either
replaced by vnode->pathname translation, or combined with it.
- Add a VERIEXEC_DUMP ioctl, to dump the entire Veriexec database.
This can be used to recover a database if the file was lost.
Example usage:
# veriexecctl dump > /etc/signatures
Note that only entries with the filename kept (that is, were loaded
with the '-k' flag) will be dumped.
Idea from Brett Lymn.
- Add a VERIEXEC_FLUSH ioctl, to delete all Veriexec entries. Sample
usage:
# veriexecctl flush
- Add a 'veriexec_flags' rc(8) variable, and make its default have
the '-k' flag. On systems using the default signatures file
(generaetd from running 'veriexecgen' with no arguments), this will
use additional 32kb of kernel memory on average.
- Add a '-e' flag to veriexecctl, to evaluate the fingerprint during
load. This is done automatically for files marked as 'untrusted'.
Misc. stuff:
- The code for veriexecctl was massively simplified as a result of
eliminating the need for VERIEXEC_TABLESIZE, and now uses a single
pass of the signatures file, making the loading somewhat faster.
- Lots of minor fixes found using the (still under development)
Veriexec regression testsuite.
- Some of the messages Veriexec prints were improved.
- Various documentation fixes.
All relevant man-pages were updated to reflect the above changes.
Binary compatibility with existing veriexecctl binaries is maintained.
2007-05-15 23:47:43 +04:00
|
|
|
goto out;
|
1994-06-29 10:29:24 +04:00
|
|
|
vp = nd.ni_vp;
|
|
|
|
|
1996-02-09 17:45:36 +03:00
|
|
|
/*
|
|
|
|
* The root of a mounted filesystem cannot be deleted.
|
|
|
|
*/
|
Add most system calls for POSIX extended API set, part 2, with test cases:
faccessat(2), fchmodat(2), fchownat(2), fstatat(2), mkdirat(2), mkfifoat(2),
mknodat(2), linkat(2), readlinkat(2), symlinkat(2), renameat(2), unlinkat(2),
utimensat(2), openat(2).
Also implement O_SEARCH for openat(2)
Still missing:
- some flags for openat(2)
- fexecve(2) implementation
2012-11-18 21:41:51 +04:00
|
|
|
if ((vp->v_vflag & VV_ROOT) != 0) {
|
1996-02-09 17:45:36 +03:00
|
|
|
error = EBUSY;
|
Add most system calls for POSIX extended API set, part 2, with test cases:
faccessat(2), fchmodat(2), fchownat(2), fstatat(2), mkdirat(2), mkfifoat(2),
mknodat(2), linkat(2), readlinkat(2), symlinkat(2), renameat(2), unlinkat(2),
utimensat(2), openat(2).
Also implement O_SEARCH for openat(2)
Still missing:
- some flags for openat(2)
- fexecve(2) implementation
2012-11-18 21:41:51 +04:00
|
|
|
goto abort;
|
|
|
|
}
|
|
|
|
|
|
|
|
if ((vp->v_type == VDIR) && (vp->v_mountedhere != NULL)) {
|
|
|
|
error = EBUSY;
|
|
|
|
goto abort;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* No rmdir "." please.
|
|
|
|
*/
|
|
|
|
if (nd.ni_dvp == vp) {
|
|
|
|
error = EINVAL;
|
|
|
|
goto abort;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* AT_REMOVEDIR is required to remove a directory
|
|
|
|
*/
|
|
|
|
if (vp->v_type == VDIR) {
|
|
|
|
if (!(flags & AT_REMOVEDIR)) {
|
|
|
|
error = EPERM;
|
|
|
|
goto abort;
|
|
|
|
} else {
|
|
|
|
error = VOP_RMDIR(nd.ni_dvp, nd.ni_vp, &nd.ni_cnd);
|
|
|
|
goto out;
|
|
|
|
}
|
1994-06-29 10:29:24 +04:00
|
|
|
}
|
2005-04-20 17:44:45 +04:00
|
|
|
|
Add most system calls for POSIX extended API set, part 2, with test cases:
faccessat(2), fchmodat(2), fchownat(2), fstatat(2), mkdirat(2), mkfifoat(2),
mknodat(2), linkat(2), readlinkat(2), symlinkat(2), renameat(2), unlinkat(2),
utimensat(2), openat(2).
Also implement O_SEARCH for openat(2)
Still missing:
- some flags for openat(2)
- fexecve(2) implementation
2012-11-18 21:41:51 +04:00
|
|
|
/*
|
|
|
|
* Starting here we only deal with non directories.
|
|
|
|
*/
|
|
|
|
if (flags & AT_REMOVEDIR) {
|
|
|
|
error = ENOTDIR;
|
|
|
|
goto abort;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2006-07-22 14:34:26 +04:00
|
|
|
#if NVERIEXEC > 0
|
2005-06-17 21:46:18 +04:00
|
|
|
/* Handle remove requests for veriexec entries. */
|
2010-11-19 09:44:33 +03:00
|
|
|
if ((error = veriexec_removechk(curlwp, nd.ni_vp, pathstring)) != 0) {
|
2005-04-20 17:44:45 +04:00
|
|
|
VOP_ABORTOP(nd.ni_dvp, &nd.ni_cnd);
|
|
|
|
if (nd.ni_dvp == vp)
|
|
|
|
vrele(nd.ni_dvp);
|
|
|
|
else
|
|
|
|
vput(nd.ni_dvp);
|
|
|
|
vput(vp);
|
|
|
|
goto out;
|
|
|
|
}
|
2006-07-22 14:34:26 +04:00
|
|
|
#endif /* NVERIEXEC > 0 */
|
|
|
|
|
okay, since there was no way to divide this to two commits, here it goes..
introduce fileassoc(9), a kernel interface for associating meta-data with
files using in-kernel memory. this is very similar to what we had in
veriexec till now, only abstracted so it can be used more easily by more
consumers.
this also prompted the redesign of the interface, making it work on vnodes
and mounts and not directly on devices and inodes. internally, we still
use file-id but that's gonna change soon... the interface will remain
consistent.
as a result, veriexec went under some heavy changes to conform to the new
interface. since we no longer use device numbers to identify file-systems,
the veriexec sysctl stuff changed too: kern.veriexec.count.dev_N is now
kern.veriexec.tableN.* where 'N' is NOT the device number but rather a
way to distinguish several mounts.
also worth noting is the plugging of unmount/delete operations
wrt/fileassoc and veriexec.
tons of input from yamt@, wrstuden@, martin@, and christos@.
2006-07-14 22:41:40 +04:00
|
|
|
#ifdef FILEASSOC
|
2006-11-22 02:52:41 +03:00
|
|
|
(void)fileassoc_file_delete(vp);
|
okay, since there was no way to divide this to two commits, here it goes..
introduce fileassoc(9), a kernel interface for associating meta-data with
files using in-kernel memory. this is very similar to what we had in
veriexec till now, only abstracted so it can be used more easily by more
consumers.
this also prompted the redesign of the interface, making it work on vnodes
and mounts and not directly on devices and inodes. internally, we still
use file-id but that's gonna change soon... the interface will remain
consistent.
as a result, veriexec went under some heavy changes to conform to the new
interface. since we no longer use device numbers to identify file-systems,
the veriexec sysctl stuff changed too: kern.veriexec.count.dev_N is now
kern.veriexec.tableN.* where 'N' is NOT the device number but rather a
way to distinguish several mounts.
also worth noting is the plugging of unmount/delete operations
wrt/fileassoc and veriexec.
tons of input from yamt@, wrstuden@, martin@, and christos@.
2006-07-14 22:41:40 +04:00
|
|
|
#endif /* FILEASSOC */
|
2006-07-17 23:05:36 +04:00
|
|
|
error = VOP_REMOVE(nd.ni_dvp, nd.ni_vp, &nd.ni_cnd);
|
Add most system calls for POSIX extended API set, part 2, with test cases:
faccessat(2), fchmodat(2), fchownat(2), fstatat(2), mkdirat(2), mkfifoat(2),
mknodat(2), linkat(2), readlinkat(2), symlinkat(2), renameat(2), unlinkat(2),
utimensat(2), openat(2).
Also implement O_SEARCH for openat(2)
Still missing:
- some flags for openat(2)
- fexecve(2) implementation
2012-11-18 21:41:51 +04:00
|
|
|
goto out;
|
|
|
|
|
|
|
|
abort:
|
|
|
|
VOP_ABORTOP(nd.ni_dvp, &nd.ni_cnd);
|
|
|
|
if (nd.ni_dvp == vp)
|
|
|
|
vrele(nd.ni_dvp);
|
|
|
|
else
|
|
|
|
vput(nd.ni_dvp);
|
|
|
|
vput(vp);
|
|
|
|
|
1996-02-09 17:45:36 +03:00
|
|
|
out:
|
2010-11-19 09:44:33 +03:00
|
|
|
pathbuf_stringcopy_put(pb, pathstring);
|
|
|
|
pathbuf_destroy(pb);
|
1994-06-29 10:29:24 +04:00
|
|
|
return (error);
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Reposition read/write file offset.
|
|
|
|
*/
|
1996-02-04 05:17:43 +03:00
|
|
|
int
|
2007-12-21 02:02:38 +03:00
|
|
|
sys_lseek(struct lwp *l, const struct sys_lseek_args *uap, register_t *retval)
|
1995-09-20 01:40:36 +04:00
|
|
|
{
|
2007-12-21 02:02:38 +03:00
|
|
|
/* {
|
1994-10-20 07:22:35 +03:00
|
|
|
syscallarg(int) fd;
|
|
|
|
syscallarg(int) pad;
|
|
|
|
syscallarg(off_t) offset;
|
|
|
|
syscallarg(int) whence;
|
2007-12-21 02:02:38 +03:00
|
|
|
} */
|
2006-07-24 02:06:03 +04:00
|
|
|
kauth_cred_t cred = l->l_cred;
|
2008-03-22 00:54:58 +03:00
|
|
|
file_t *fp;
|
1997-04-12 02:03:58 +04:00
|
|
|
struct vnode *vp;
|
1994-06-29 10:29:24 +04:00
|
|
|
struct vattr vattr;
|
2000-03-30 13:27:11 +04:00
|
|
|
off_t newoff;
|
2008-03-22 00:54:58 +03:00
|
|
|
int error, fd;
|
1994-06-29 10:29:24 +04:00
|
|
|
|
2008-03-22 00:54:58 +03:00
|
|
|
fd = SCARG(uap, fd);
|
|
|
|
|
|
|
|
if ((fp = fd_getfile(fd)) == NULL)
|
1994-06-29 10:29:24 +04:00
|
|
|
return (EBADF);
|
1997-04-12 02:03:58 +04:00
|
|
|
|
2008-03-22 00:54:58 +03:00
|
|
|
vp = fp->f_data;
|
1999-05-06 00:01:01 +04:00
|
|
|
if (fp->f_type != DTYPE_VNODE || vp->v_type == VFIFO) {
|
|
|
|
error = ESPIPE;
|
|
|
|
goto out;
|
|
|
|
}
|
1997-04-12 02:03:58 +04:00
|
|
|
|
1994-10-20 07:22:35 +03:00
|
|
|
switch (SCARG(uap, whence)) {
|
1997-08-25 23:31:43 +04:00
|
|
|
case SEEK_CUR:
|
1997-04-12 02:03:58 +04:00
|
|
|
newoff = fp->f_offset + SCARG(uap, offset);
|
1994-06-29 10:29:24 +04:00
|
|
|
break;
|
1997-08-25 23:31:43 +04:00
|
|
|
case SEEK_END:
|
2011-10-14 13:23:28 +04:00
|
|
|
vn_lock(vp, LK_SHARED | LK_RETRY);
|
2007-11-26 22:01:26 +03:00
|
|
|
error = VOP_GETATTR(vp, &vattr, cred);
|
2011-10-14 13:23:28 +04:00
|
|
|
VOP_UNLOCK(vp);
|
2007-10-08 19:12:05 +04:00
|
|
|
if (error) {
|
1999-05-06 00:01:01 +04:00
|
|
|
goto out;
|
2007-10-08 19:12:05 +04:00
|
|
|
}
|
1997-04-12 02:03:58 +04:00
|
|
|
newoff = SCARG(uap, offset) + vattr.va_size;
|
1994-06-29 10:29:24 +04:00
|
|
|
break;
|
1997-08-25 23:31:43 +04:00
|
|
|
case SEEK_SET:
|
1997-04-12 02:03:58 +04:00
|
|
|
newoff = SCARG(uap, offset);
|
1994-06-29 10:29:24 +04:00
|
|
|
break;
|
|
|
|
default:
|
1999-05-06 00:01:01 +04:00
|
|
|
error = EINVAL;
|
|
|
|
goto out;
|
1994-06-29 10:29:24 +04:00
|
|
|
}
|
2007-10-08 19:12:05 +04:00
|
|
|
if ((error = VOP_SEEK(vp, fp->f_offset, newoff, cred)) == 0) {
|
|
|
|
*(off_t *)retval = fp->f_offset = newoff;
|
|
|
|
}
|
|
|
|
out:
|
2008-03-22 00:54:58 +03:00
|
|
|
fd_putfile(fd);
|
1999-05-06 00:01:01 +04:00
|
|
|
return (error);
|
1994-06-29 10:29:24 +04:00
|
|
|
}
|
|
|
|
|
1998-06-30 23:36:24 +04:00
|
|
|
/*
|
|
|
|
* Positional read system call.
|
|
|
|
*/
|
|
|
|
int
|
2007-12-21 02:02:38 +03:00
|
|
|
sys_pread(struct lwp *l, const struct sys_pread_args *uap, register_t *retval)
|
1998-06-30 23:36:24 +04:00
|
|
|
{
|
2007-12-21 02:02:38 +03:00
|
|
|
/* {
|
1998-06-30 23:36:24 +04:00
|
|
|
syscallarg(int) fd;
|
|
|
|
syscallarg(void *) buf;
|
|
|
|
syscallarg(size_t) nbyte;
|
|
|
|
syscallarg(off_t) offset;
|
2007-12-21 02:02:38 +03:00
|
|
|
} */
|
2008-03-22 00:54:58 +03:00
|
|
|
file_t *fp;
|
1998-06-30 23:36:24 +04:00
|
|
|
struct vnode *vp;
|
|
|
|
off_t offset;
|
|
|
|
int error, fd = SCARG(uap, fd);
|
|
|
|
|
2008-03-22 00:54:58 +03:00
|
|
|
if ((fp = fd_getfile(fd)) == NULL)
|
2001-06-15 00:32:41 +04:00
|
|
|
return (EBADF);
|
|
|
|
|
2003-02-23 17:37:32 +03:00
|
|
|
if ((fp->f_flag & FREAD) == 0) {
|
2008-03-22 00:54:58 +03:00
|
|
|
fd_putfile(fd);
|
1998-06-30 23:36:24 +04:00
|
|
|
return (EBADF);
|
2003-02-23 17:37:32 +03:00
|
|
|
}
|
1998-06-30 23:36:24 +04:00
|
|
|
|
2008-03-22 00:54:58 +03:00
|
|
|
vp = fp->f_data;
|
1999-05-06 00:01:01 +04:00
|
|
|
if (fp->f_type != DTYPE_VNODE || vp->v_type == VFIFO) {
|
|
|
|
error = ESPIPE;
|
|
|
|
goto out;
|
|
|
|
}
|
1998-06-30 23:36:24 +04:00
|
|
|
|
|
|
|
offset = SCARG(uap, offset);
|
|
|
|
|
|
|
|
/*
|
|
|
|
* XXX This works because no file systems actually
|
|
|
|
* XXX take any action on the seek operation.
|
|
|
|
*/
|
|
|
|
if ((error = VOP_SEEK(vp, fp->f_offset, offset, fp->f_cred)) != 0)
|
1999-05-06 00:01:01 +04:00
|
|
|
goto out;
|
1998-06-30 23:36:24 +04:00
|
|
|
|
1999-05-06 00:01:01 +04:00
|
|
|
/* dofileread() will unuse the descriptor for us */
|
2007-10-08 19:12:05 +04:00
|
|
|
return (dofileread(fd, fp, SCARG(uap, buf), SCARG(uap, nbyte),
|
1998-06-30 23:36:24 +04:00
|
|
|
&offset, 0, retval));
|
1999-05-06 00:01:01 +04:00
|
|
|
|
|
|
|
out:
|
2008-03-22 00:54:58 +03:00
|
|
|
fd_putfile(fd);
|
1999-05-06 00:01:01 +04:00
|
|
|
return (error);
|
1998-06-30 23:36:24 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Positional scatter read system call.
|
|
|
|
*/
|
|
|
|
int
|
2007-12-21 02:02:38 +03:00
|
|
|
sys_preadv(struct lwp *l, const struct sys_preadv_args *uap, register_t *retval)
|
1998-06-30 23:36:24 +04:00
|
|
|
{
|
2007-12-21 02:02:38 +03:00
|
|
|
/* {
|
1998-06-30 23:36:24 +04:00
|
|
|
syscallarg(int) fd;
|
|
|
|
syscallarg(const struct iovec *) iovp;
|
|
|
|
syscallarg(int) iovcnt;
|
|
|
|
syscallarg(off_t) offset;
|
2007-12-21 02:02:38 +03:00
|
|
|
} */
|
|
|
|
off_t offset = SCARG(uap, offset);
|
1998-06-30 23:36:24 +04:00
|
|
|
|
2007-10-08 19:12:05 +04:00
|
|
|
return do_filereadv(SCARG(uap, fd), SCARG(uap, iovp),
|
2007-12-21 02:02:38 +03:00
|
|
|
SCARG(uap, iovcnt), &offset, 0, retval);
|
1998-06-30 23:36:24 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Positional write system call.
|
|
|
|
*/
|
|
|
|
int
|
2007-12-21 02:02:38 +03:00
|
|
|
sys_pwrite(struct lwp *l, const struct sys_pwrite_args *uap, register_t *retval)
|
1998-06-30 23:36:24 +04:00
|
|
|
{
|
2007-12-21 02:02:38 +03:00
|
|
|
/* {
|
1998-06-30 23:36:24 +04:00
|
|
|
syscallarg(int) fd;
|
|
|
|
syscallarg(const void *) buf;
|
|
|
|
syscallarg(size_t) nbyte;
|
|
|
|
syscallarg(off_t) offset;
|
2007-12-21 02:02:38 +03:00
|
|
|
} */
|
2008-03-22 00:54:58 +03:00
|
|
|
file_t *fp;
|
1998-06-30 23:36:24 +04:00
|
|
|
struct vnode *vp;
|
|
|
|
off_t offset;
|
|
|
|
int error, fd = SCARG(uap, fd);
|
|
|
|
|
2008-03-22 00:54:58 +03:00
|
|
|
if ((fp = fd_getfile(fd)) == NULL)
|
2001-06-15 00:32:41 +04:00
|
|
|
return (EBADF);
|
|
|
|
|
2003-02-23 17:37:32 +03:00
|
|
|
if ((fp->f_flag & FWRITE) == 0) {
|
2008-03-22 00:54:58 +03:00
|
|
|
fd_putfile(fd);
|
1998-06-30 23:36:24 +04:00
|
|
|
return (EBADF);
|
2003-02-23 17:37:32 +03:00
|
|
|
}
|
1998-06-30 23:36:24 +04:00
|
|
|
|
2008-03-22 00:54:58 +03:00
|
|
|
vp = fp->f_data;
|
1999-05-06 00:01:01 +04:00
|
|
|
if (fp->f_type != DTYPE_VNODE || vp->v_type == VFIFO) {
|
|
|
|
error = ESPIPE;
|
|
|
|
goto out;
|
|
|
|
}
|
1998-06-30 23:36:24 +04:00
|
|
|
|
|
|
|
offset = SCARG(uap, offset);
|
|
|
|
|
|
|
|
/*
|
|
|
|
* XXX This works because no file systems actually
|
|
|
|
* XXX take any action on the seek operation.
|
|
|
|
*/
|
|
|
|
if ((error = VOP_SEEK(vp, fp->f_offset, offset, fp->f_cred)) != 0)
|
1999-05-06 00:01:01 +04:00
|
|
|
goto out;
|
1998-06-30 23:36:24 +04:00
|
|
|
|
1999-05-06 00:01:01 +04:00
|
|
|
/* dofilewrite() will unuse the descriptor for us */
|
2007-10-08 19:12:05 +04:00
|
|
|
return (dofilewrite(fd, fp, SCARG(uap, buf), SCARG(uap, nbyte),
|
1998-06-30 23:36:24 +04:00
|
|
|
&offset, 0, retval));
|
1999-05-06 00:01:01 +04:00
|
|
|
|
|
|
|
out:
|
2008-03-22 00:54:58 +03:00
|
|
|
fd_putfile(fd);
|
1999-05-06 00:01:01 +04:00
|
|
|
return (error);
|
1998-06-30 23:36:24 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Positional gather write system call.
|
|
|
|
*/
|
|
|
|
int
|
2007-12-21 02:02:38 +03:00
|
|
|
sys_pwritev(struct lwp *l, const struct sys_pwritev_args *uap, register_t *retval)
|
1998-06-30 23:36:24 +04:00
|
|
|
{
|
2007-12-21 02:02:38 +03:00
|
|
|
/* {
|
1998-06-30 23:36:24 +04:00
|
|
|
syscallarg(int) fd;
|
|
|
|
syscallarg(const struct iovec *) iovp;
|
|
|
|
syscallarg(int) iovcnt;
|
|
|
|
syscallarg(off_t) offset;
|
2007-12-21 02:02:38 +03:00
|
|
|
} */
|
|
|
|
off_t offset = SCARG(uap, offset);
|
1998-06-30 23:36:24 +04:00
|
|
|
|
2007-10-08 19:12:05 +04:00
|
|
|
return do_filewritev(SCARG(uap, fd), SCARG(uap, iovp),
|
2007-12-21 02:02:38 +03:00
|
|
|
SCARG(uap, iovcnt), &offset, 0, retval);
|
1998-06-30 23:36:24 +04:00
|
|
|
}
|
|
|
|
|
1994-06-29 10:29:24 +04:00
|
|
|
/*
|
|
|
|
* Check access permissions.
|
|
|
|
*/
|
1996-02-04 05:17:43 +03:00
|
|
|
int
|
2007-12-21 02:02:38 +03:00
|
|
|
sys_access(struct lwp *l, const struct sys_access_args *uap, register_t *retval)
|
1995-09-20 01:40:36 +04:00
|
|
|
{
|
2007-12-21 02:02:38 +03:00
|
|
|
/* {
|
1996-12-22 13:21:06 +03:00
|
|
|
syscallarg(const char *) path;
|
1994-10-20 07:22:35 +03:00
|
|
|
syscallarg(int) flags;
|
2007-12-21 02:02:38 +03:00
|
|
|
} */
|
Add most system calls for POSIX extended API set, part 2, with test cases:
faccessat(2), fchmodat(2), fchownat(2), fstatat(2), mkdirat(2), mkfifoat(2),
mknodat(2), linkat(2), readlinkat(2), symlinkat(2), renameat(2), unlinkat(2),
utimensat(2), openat(2).
Also implement O_SEARCH for openat(2)
Still missing:
- some flags for openat(2)
- fexecve(2) implementation
2012-11-18 21:41:51 +04:00
|
|
|
|
|
|
|
return do_sys_accessat(l, AT_FDCWD, SCARG(uap, path),
|
|
|
|
SCARG(uap, flags), 0);
|
|
|
|
}
|
|
|
|
|
|
|
|
static int
|
|
|
|
do_sys_accessat(struct lwp *l, int fdat, const char *path,
|
|
|
|
int mode, int flags)
|
|
|
|
{
|
2006-05-15 01:15:11 +04:00
|
|
|
kauth_cred_t cred;
|
2000-03-30 13:27:11 +04:00
|
|
|
struct vnode *vp;
|
Add most system calls for POSIX extended API set, part 2, with test cases:
faccessat(2), fchmodat(2), fchownat(2), fstatat(2), mkdirat(2), mkfifoat(2),
mknodat(2), linkat(2), readlinkat(2), symlinkat(2), renameat(2), unlinkat(2),
utimensat(2), openat(2).
Also implement O_SEARCH for openat(2)
Still missing:
- some flags for openat(2)
- fexecve(2) implementation
2012-11-18 21:41:51 +04:00
|
|
|
int error, nd_flag, vmode;
|
2010-11-19 09:44:33 +03:00
|
|
|
struct pathbuf *pb;
|
1994-06-29 10:29:24 +04:00
|
|
|
struct nameidata nd;
|
|
|
|
|
2011-02-28 06:23:44 +03:00
|
|
|
CTASSERT(F_OK == 0);
|
Add most system calls for POSIX extended API set, part 2, with test cases:
faccessat(2), fchmodat(2), fchownat(2), fstatat(2), mkdirat(2), mkfifoat(2),
mknodat(2), linkat(2), readlinkat(2), symlinkat(2), renameat(2), unlinkat(2),
utimensat(2), openat(2).
Also implement O_SEARCH for openat(2)
Still missing:
- some flags for openat(2)
- fexecve(2) implementation
2012-11-18 21:41:51 +04:00
|
|
|
if ((mode & ~(R_OK | W_OK | X_OK)) != 0) {
|
|
|
|
/* nonsense mode */
|
2011-02-28 02:06:40 +03:00
|
|
|
return EINVAL;
|
|
|
|
}
|
|
|
|
|
Add most system calls for POSIX extended API set, part 2, with test cases:
faccessat(2), fchmodat(2), fchownat(2), fstatat(2), mkdirat(2), mkfifoat(2),
mknodat(2), linkat(2), readlinkat(2), symlinkat(2), renameat(2), unlinkat(2),
utimensat(2), openat(2).
Also implement O_SEARCH for openat(2)
Still missing:
- some flags for openat(2)
- fexecve(2) implementation
2012-11-18 21:41:51 +04:00
|
|
|
nd_flag = FOLLOW | LOCKLEAF | TRYEMULROOT;
|
|
|
|
if (flags & AT_SYMLINK_NOFOLLOW)
|
|
|
|
nd_flag &= ~FOLLOW;
|
|
|
|
|
|
|
|
error = pathbuf_copyin(path, &pb);
|
|
|
|
if (error)
|
2010-11-19 09:44:33 +03:00
|
|
|
return error;
|
Add most system calls for POSIX extended API set, part 2, with test cases:
faccessat(2), fchmodat(2), fchownat(2), fstatat(2), mkdirat(2), mkfifoat(2),
mknodat(2), linkat(2), readlinkat(2), symlinkat(2), renameat(2), unlinkat(2),
utimensat(2), openat(2).
Also implement O_SEARCH for openat(2)
Still missing:
- some flags for openat(2)
- fexecve(2) implementation
2012-11-18 21:41:51 +04:00
|
|
|
|
|
|
|
NDINIT(&nd, LOOKUP, nd_flag, pb);
|
2010-11-19 09:44:33 +03:00
|
|
|
|
|
|
|
/* Override default credentials */
|
2006-07-24 02:06:03 +04:00
|
|
|
cred = kauth_cred_dup(l->l_cred);
|
Add most system calls for POSIX extended API set, part 2, with test cases:
faccessat(2), fchmodat(2), fchownat(2), fstatat(2), mkdirat(2), mkfifoat(2),
mknodat(2), linkat(2), readlinkat(2), symlinkat(2), renameat(2), unlinkat(2),
utimensat(2), openat(2).
Also implement O_SEARCH for openat(2)
Still missing:
- some flags for openat(2)
- fexecve(2) implementation
2012-11-18 21:41:51 +04:00
|
|
|
if (!(flags & AT_EACCESS)) {
|
|
|
|
kauth_cred_seteuid(cred, kauth_cred_getuid(l->l_cred));
|
|
|
|
kauth_cred_setegid(cred, kauth_cred_getgid(l->l_cred));
|
|
|
|
}
|
2001-09-08 06:05:39 +04:00
|
|
|
nd.ni_cnd.cn_cred = cred;
|
2010-11-19 09:44:33 +03:00
|
|
|
|
Add most system calls for POSIX extended API set, part 2, with test cases:
faccessat(2), fchmodat(2), fchownat(2), fstatat(2), mkdirat(2), mkfifoat(2),
mknodat(2), linkat(2), readlinkat(2), symlinkat(2), renameat(2), unlinkat(2),
utimensat(2), openat(2).
Also implement O_SEARCH for openat(2)
Still missing:
- some flags for openat(2)
- fexecve(2) implementation
2012-11-18 21:41:51 +04:00
|
|
|
if ((error = fd_nameiat(l, fdat, &nd)) != 0) {
|
2010-11-19 09:44:33 +03:00
|
|
|
pathbuf_destroy(pb);
|
2001-09-08 06:05:39 +04:00
|
|
|
goto out;
|
2010-11-19 09:44:33 +03:00
|
|
|
}
|
1994-06-29 10:29:24 +04:00
|
|
|
vp = nd.ni_vp;
|
2010-11-19 09:44:33 +03:00
|
|
|
pathbuf_destroy(pb);
|
1994-06-29 10:29:24 +04:00
|
|
|
|
|
|
|
/* Flags == 0 means only check for existence. */
|
Add most system calls for POSIX extended API set, part 2, with test cases:
faccessat(2), fchmodat(2), fchownat(2), fstatat(2), mkdirat(2), mkfifoat(2),
mknodat(2), linkat(2), readlinkat(2), symlinkat(2), renameat(2), unlinkat(2),
utimensat(2), openat(2).
Also implement O_SEARCH for openat(2)
Still missing:
- some flags for openat(2)
- fexecve(2) implementation
2012-11-18 21:41:51 +04:00
|
|
|
if (mode) {
|
|
|
|
vmode = 0;
|
|
|
|
if (mode & R_OK)
|
|
|
|
vmode |= VREAD;
|
|
|
|
if (mode & W_OK)
|
|
|
|
vmode |= VWRITE;
|
|
|
|
if (mode & X_OK)
|
|
|
|
vmode |= VEXEC;
|
|
|
|
|
|
|
|
error = VOP_ACCESS(vp, vmode, cred);
|
|
|
|
if (!error && (vmode & VWRITE))
|
1999-06-30 14:00:06 +04:00
|
|
|
error = vn_writechk(vp);
|
1994-06-29 10:29:24 +04:00
|
|
|
}
|
|
|
|
vput(vp);
|
2001-09-08 06:05:39 +04:00
|
|
|
out:
|
2006-05-15 01:15:11 +04:00
|
|
|
kauth_cred_free(cred);
|
1994-06-29 10:29:24 +04:00
|
|
|
return (error);
|
|
|
|
}
|
|
|
|
|
2011-08-08 16:08:52 +04:00
|
|
|
int
|
|
|
|
sys_faccessat(struct lwp *l, const struct sys_faccessat_args *uap,
|
|
|
|
register_t *retval)
|
|
|
|
{
|
|
|
|
/* {
|
|
|
|
syscallarg(int) fd;
|
|
|
|
syscallarg(const char *) path;
|
|
|
|
syscallarg(int) amode;
|
|
|
|
syscallarg(int) flag;
|
|
|
|
} */
|
|
|
|
|
Add most system calls for POSIX extended API set, part 2, with test cases:
faccessat(2), fchmodat(2), fchownat(2), fstatat(2), mkdirat(2), mkfifoat(2),
mknodat(2), linkat(2), readlinkat(2), symlinkat(2), renameat(2), unlinkat(2),
utimensat(2), openat(2).
Also implement O_SEARCH for openat(2)
Still missing:
- some flags for openat(2)
- fexecve(2) implementation
2012-11-18 21:41:51 +04:00
|
|
|
return do_sys_accessat(l, SCARG(uap, fd), SCARG(uap, path),
|
|
|
|
SCARG(uap, amode), SCARG(uap, flag));
|
2011-08-08 16:08:52 +04:00
|
|
|
}
|
|
|
|
|
2007-03-10 19:50:01 +03:00
|
|
|
/*
|
|
|
|
* Common code for all sys_stat functions, including compat versions.
|
|
|
|
*/
|
|
|
|
int
|
Add most system calls for POSIX extended API set, part 2, with test cases:
faccessat(2), fchmodat(2), fchownat(2), fstatat(2), mkdirat(2), mkfifoat(2),
mknodat(2), linkat(2), readlinkat(2), symlinkat(2), renameat(2), unlinkat(2),
utimensat(2), openat(2).
Also implement O_SEARCH for openat(2)
Still missing:
- some flags for openat(2)
- fexecve(2) implementation
2012-11-18 21:41:51 +04:00
|
|
|
do_sys_stat(const char *userpath, unsigned int nd_flag,
|
|
|
|
struct stat *sb)
|
|
|
|
{
|
|
|
|
return do_sys_statat(NULL, AT_FDCWD, userpath, nd_flag, sb);
|
|
|
|
}
|
|
|
|
|
|
|
|
static int
|
|
|
|
do_sys_statat(struct lwp *l, int fdat, const char *userpath,
|
|
|
|
unsigned int nd_flag, struct stat *sb)
|
2007-03-10 19:50:01 +03:00
|
|
|
{
|
|
|
|
int error;
|
2010-11-19 09:44:33 +03:00
|
|
|
struct pathbuf *pb;
|
2007-03-10 19:50:01 +03:00
|
|
|
struct nameidata nd;
|
|
|
|
|
Add most system calls for POSIX extended API set, part 2, with test cases:
faccessat(2), fchmodat(2), fchownat(2), fstatat(2), mkdirat(2), mkfifoat(2),
mknodat(2), linkat(2), readlinkat(2), symlinkat(2), renameat(2), unlinkat(2),
utimensat(2), openat(2).
Also implement O_SEARCH for openat(2)
Still missing:
- some flags for openat(2)
- fexecve(2) implementation
2012-11-18 21:41:51 +04:00
|
|
|
KASSERT(l != NULL || fdat == AT_FDCWD);
|
|
|
|
|
2010-11-19 09:44:33 +03:00
|
|
|
error = pathbuf_copyin(userpath, &pb);
|
|
|
|
if (error) {
|
|
|
|
return error;
|
|
|
|
}
|
Add most system calls for POSIX extended API set, part 2, with test cases:
faccessat(2), fchmodat(2), fchownat(2), fstatat(2), mkdirat(2), mkfifoat(2),
mknodat(2), linkat(2), readlinkat(2), symlinkat(2), renameat(2), unlinkat(2),
utimensat(2), openat(2).
Also implement O_SEARCH for openat(2)
Still missing:
- some flags for openat(2)
- fexecve(2) implementation
2012-11-18 21:41:51 +04:00
|
|
|
|
|
|
|
NDINIT(&nd, LOOKUP, nd_flag | LOCKLEAF | TRYEMULROOT, pb);
|
|
|
|
|
|
|
|
error = fd_nameiat(l, fdat, &nd);
|
2010-11-19 09:44:33 +03:00
|
|
|
if (error != 0) {
|
|
|
|
pathbuf_destroy(pb);
|
2007-03-10 19:50:01 +03:00
|
|
|
return error;
|
2010-11-19 09:44:33 +03:00
|
|
|
}
|
2008-03-22 00:54:58 +03:00
|
|
|
error = vn_stat(nd.ni_vp, sb);
|
2007-03-10 19:50:01 +03:00
|
|
|
vput(nd.ni_vp);
|
2010-11-19 09:44:33 +03:00
|
|
|
pathbuf_destroy(pb);
|
2007-03-10 19:50:01 +03:00
|
|
|
return error;
|
|
|
|
}
|
|
|
|
|
1994-06-29 10:29:24 +04:00
|
|
|
/*
|
|
|
|
* Get file status; this version follows links.
|
|
|
|
*/
|
|
|
|
/* ARGSUSED */
|
1996-02-04 05:17:43 +03:00
|
|
|
int
|
2009-01-11 05:45:45 +03:00
|
|
|
sys___stat50(struct lwp *l, const struct sys___stat50_args *uap, register_t *retval)
|
1995-09-20 01:40:36 +04:00
|
|
|
{
|
2007-12-21 02:02:38 +03:00
|
|
|
/* {
|
1996-12-22 13:21:06 +03:00
|
|
|
syscallarg(const char *) path;
|
1994-10-20 07:22:35 +03:00
|
|
|
syscallarg(struct stat *) ub;
|
2007-12-21 02:02:38 +03:00
|
|
|
} */
|
1994-06-29 10:29:24 +04:00
|
|
|
struct stat sb;
|
|
|
|
int error;
|
|
|
|
|
Add most system calls for POSIX extended API set, part 2, with test cases:
faccessat(2), fchmodat(2), fchownat(2), fstatat(2), mkdirat(2), mkfifoat(2),
mknodat(2), linkat(2), readlinkat(2), symlinkat(2), renameat(2), unlinkat(2),
utimensat(2), openat(2).
Also implement O_SEARCH for openat(2)
Still missing:
- some flags for openat(2)
- fexecve(2) implementation
2012-11-18 21:41:51 +04:00
|
|
|
error = do_sys_statat(l, AT_FDCWD, SCARG(uap, path), FOLLOW, &sb);
|
1994-06-29 10:29:24 +04:00
|
|
|
if (error)
|
2007-03-10 19:50:01 +03:00
|
|
|
return error;
|
|
|
|
return copyout(&sb, SCARG(uap, ub), sizeof(sb));
|
1994-06-29 10:29:24 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Get file status; this version does not follow links.
|
|
|
|
*/
|
|
|
|
/* ARGSUSED */
|
1996-02-04 05:17:43 +03:00
|
|
|
int
|
2009-01-11 05:45:45 +03:00
|
|
|
sys___lstat50(struct lwp *l, const struct sys___lstat50_args *uap, register_t *retval)
|
1995-09-20 01:40:36 +04:00
|
|
|
{
|
2007-12-21 02:02:38 +03:00
|
|
|
/* {
|
1996-12-22 13:21:06 +03:00
|
|
|
syscallarg(const char *) path;
|
1994-10-20 07:22:35 +03:00
|
|
|
syscallarg(struct stat *) ub;
|
2007-12-21 02:02:38 +03:00
|
|
|
} */
|
1996-02-08 05:54:20 +03:00
|
|
|
struct stat sb;
|
1994-06-29 10:29:24 +04:00
|
|
|
int error;
|
|
|
|
|
Add most system calls for POSIX extended API set, part 2, with test cases:
faccessat(2), fchmodat(2), fchownat(2), fstatat(2), mkdirat(2), mkfifoat(2),
mknodat(2), linkat(2), readlinkat(2), symlinkat(2), renameat(2), unlinkat(2),
utimensat(2), openat(2).
Also implement O_SEARCH for openat(2)
Still missing:
- some flags for openat(2)
- fexecve(2) implementation
2012-11-18 21:41:51 +04:00
|
|
|
error = do_sys_statat(l, AT_FDCWD, SCARG(uap, path), NOFOLLOW, &sb);
|
1996-02-07 19:55:56 +03:00
|
|
|
if (error)
|
2007-03-10 19:50:01 +03:00
|
|
|
return error;
|
|
|
|
return copyout(&sb, SCARG(uap, ub), sizeof(sb));
|
1994-06-29 10:29:24 +04:00
|
|
|
}
|
|
|
|
|
2011-08-08 16:08:52 +04:00
|
|
|
int
|
|
|
|
sys_fstatat(struct lwp *l, const struct sys_fstatat_args *uap,
|
|
|
|
register_t *retval)
|
|
|
|
{
|
|
|
|
/* {
|
|
|
|
syscallarg(int) fd;
|
|
|
|
syscallarg(const char *) path;
|
Add most system calls for POSIX extended API set, part 2, with test cases:
faccessat(2), fchmodat(2), fchownat(2), fstatat(2), mkdirat(2), mkfifoat(2),
mknodat(2), linkat(2), readlinkat(2), symlinkat(2), renameat(2), unlinkat(2),
utimensat(2), openat(2).
Also implement O_SEARCH for openat(2)
Still missing:
- some flags for openat(2)
- fexecve(2) implementation
2012-11-18 21:41:51 +04:00
|
|
|
syscallarg(struct stat *) buf;
|
2011-08-08 16:08:52 +04:00
|
|
|
syscallarg(int) flag;
|
|
|
|
} */
|
Add most system calls for POSIX extended API set, part 2, with test cases:
faccessat(2), fchmodat(2), fchownat(2), fstatat(2), mkdirat(2), mkfifoat(2),
mknodat(2), linkat(2), readlinkat(2), symlinkat(2), renameat(2), unlinkat(2),
utimensat(2), openat(2).
Also implement O_SEARCH for openat(2)
Still missing:
- some flags for openat(2)
- fexecve(2) implementation
2012-11-18 21:41:51 +04:00
|
|
|
unsigned int nd_flag;
|
2012-11-19 19:01:17 +04:00
|
|
|
struct stat sb;
|
|
|
|
int error;
|
2011-08-08 16:08:52 +04:00
|
|
|
|
Add most system calls for POSIX extended API set, part 2, with test cases:
faccessat(2), fchmodat(2), fchownat(2), fstatat(2), mkdirat(2), mkfifoat(2),
mknodat(2), linkat(2), readlinkat(2), symlinkat(2), renameat(2), unlinkat(2),
utimensat(2), openat(2).
Also implement O_SEARCH for openat(2)
Still missing:
- some flags for openat(2)
- fexecve(2) implementation
2012-11-18 21:41:51 +04:00
|
|
|
if (SCARG(uap, flag) & AT_SYMLINK_NOFOLLOW)
|
|
|
|
nd_flag = NOFOLLOW;
|
|
|
|
else
|
|
|
|
nd_flag = FOLLOW;
|
|
|
|
|
2012-11-19 19:01:17 +04:00
|
|
|
error = do_sys_statat(l, SCARG(uap, fd), SCARG(uap, path), nd_flag,
|
|
|
|
&sb);
|
|
|
|
if (error)
|
|
|
|
return error;
|
|
|
|
return copyout(&sb, SCARG(uap, buf), sizeof(sb));
|
2011-08-08 16:08:52 +04:00
|
|
|
}
|
Add most system calls for POSIX extended API set, part 2, with test cases:
faccessat(2), fchmodat(2), fchownat(2), fstatat(2), mkdirat(2), mkfifoat(2),
mknodat(2), linkat(2), readlinkat(2), symlinkat(2), renameat(2), unlinkat(2),
utimensat(2), openat(2).
Also implement O_SEARCH for openat(2)
Still missing:
- some flags for openat(2)
- fexecve(2) implementation
2012-11-18 21:41:51 +04:00
|
|
|
|
1994-06-29 10:29:24 +04:00
|
|
|
/*
|
|
|
|
* Get configurable pathname variables.
|
|
|
|
*/
|
|
|
|
/* ARGSUSED */
|
1996-02-04 05:17:43 +03:00
|
|
|
int
|
2007-12-21 02:02:38 +03:00
|
|
|
sys_pathconf(struct lwp *l, const struct sys_pathconf_args *uap, register_t *retval)
|
1995-09-20 01:40:36 +04:00
|
|
|
{
|
2007-12-21 02:02:38 +03:00
|
|
|
/* {
|
1996-12-22 13:21:06 +03:00
|
|
|
syscallarg(const char *) path;
|
1994-10-20 07:22:35 +03:00
|
|
|
syscallarg(int) name;
|
2007-12-21 02:02:38 +03:00
|
|
|
} */
|
1994-06-29 10:29:24 +04:00
|
|
|
int error;
|
2010-11-19 09:44:33 +03:00
|
|
|
struct pathbuf *pb;
|
1994-06-29 10:29:24 +04:00
|
|
|
struct nameidata nd;
|
|
|
|
|
2010-11-19 09:44:33 +03:00
|
|
|
error = pathbuf_copyin(SCARG(uap, path), &pb);
|
|
|
|
if (error) {
|
|
|
|
return error;
|
|
|
|
}
|
|
|
|
NDINIT(&nd, LOOKUP, FOLLOW | LOCKLEAF | TRYEMULROOT, pb);
|
|
|
|
if ((error = namei(&nd)) != 0) {
|
|
|
|
pathbuf_destroy(pb);
|
1994-06-29 10:29:24 +04:00
|
|
|
return (error);
|
2010-11-19 09:44:33 +03:00
|
|
|
}
|
1994-10-20 07:22:35 +03:00
|
|
|
error = VOP_PATHCONF(nd.ni_vp, SCARG(uap, name), retval);
|
1994-06-29 10:29:24 +04:00
|
|
|
vput(nd.ni_vp);
|
2010-11-19 09:44:33 +03:00
|
|
|
pathbuf_destroy(pb);
|
1994-06-29 10:29:24 +04:00
|
|
|
return (error);
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Return target name of a symbolic link.
|
|
|
|
*/
|
|
|
|
/* ARGSUSED */
|
1996-02-04 05:17:43 +03:00
|
|
|
int
|
Add most system calls for POSIX extended API set, part 2, with test cases:
faccessat(2), fchmodat(2), fchownat(2), fstatat(2), mkdirat(2), mkfifoat(2),
mknodat(2), linkat(2), readlinkat(2), symlinkat(2), renameat(2), unlinkat(2),
utimensat(2), openat(2).
Also implement O_SEARCH for openat(2)
Still missing:
- some flags for openat(2)
- fexecve(2) implementation
2012-11-18 21:41:51 +04:00
|
|
|
sys_readlink(struct lwp *l, const struct sys_readlink_args *uap,
|
|
|
|
register_t *retval)
|
1995-09-20 01:40:36 +04:00
|
|
|
{
|
2007-12-21 02:02:38 +03:00
|
|
|
/* {
|
1996-12-22 13:21:06 +03:00
|
|
|
syscallarg(const char *) path;
|
1994-10-20 07:22:35 +03:00
|
|
|
syscallarg(char *) buf;
|
1998-03-27 16:02:20 +03:00
|
|
|
syscallarg(size_t) count;
|
2007-12-21 02:02:38 +03:00
|
|
|
} */
|
Add most system calls for POSIX extended API set, part 2, with test cases:
faccessat(2), fchmodat(2), fchownat(2), fstatat(2), mkdirat(2), mkfifoat(2),
mknodat(2), linkat(2), readlinkat(2), symlinkat(2), renameat(2), unlinkat(2),
utimensat(2), openat(2).
Also implement O_SEARCH for openat(2)
Still missing:
- some flags for openat(2)
- fexecve(2) implementation
2012-11-18 21:41:51 +04:00
|
|
|
return do_sys_readlinkat(l, AT_FDCWD, SCARG(uap, path),
|
|
|
|
SCARG(uap, buf), SCARG(uap, count), retval);
|
|
|
|
}
|
|
|
|
|
|
|
|
static int
|
|
|
|
do_sys_readlinkat(struct lwp *l, int fdat, const char *path, char *buf,
|
|
|
|
size_t count, register_t *retval)
|
|
|
|
{
|
2000-03-30 13:27:11 +04:00
|
|
|
struct vnode *vp;
|
1994-06-29 10:29:24 +04:00
|
|
|
struct iovec aiov;
|
|
|
|
struct uio auio;
|
|
|
|
int error;
|
2010-11-19 09:44:33 +03:00
|
|
|
struct pathbuf *pb;
|
1994-06-29 10:29:24 +04:00
|
|
|
struct nameidata nd;
|
|
|
|
|
Add most system calls for POSIX extended API set, part 2, with test cases:
faccessat(2), fchmodat(2), fchownat(2), fstatat(2), mkdirat(2), mkfifoat(2),
mknodat(2), linkat(2), readlinkat(2), symlinkat(2), renameat(2), unlinkat(2),
utimensat(2), openat(2).
Also implement O_SEARCH for openat(2)
Still missing:
- some flags for openat(2)
- fexecve(2) implementation
2012-11-18 21:41:51 +04:00
|
|
|
error = pathbuf_copyin(path, &pb);
|
2010-11-19 09:44:33 +03:00
|
|
|
if (error) {
|
|
|
|
return error;
|
|
|
|
}
|
|
|
|
NDINIT(&nd, LOOKUP, NOFOLLOW | LOCKLEAF | TRYEMULROOT, pb);
|
Add most system calls for POSIX extended API set, part 2, with test cases:
faccessat(2), fchmodat(2), fchownat(2), fstatat(2), mkdirat(2), mkfifoat(2),
mknodat(2), linkat(2), readlinkat(2), symlinkat(2), renameat(2), unlinkat(2),
utimensat(2), openat(2).
Also implement O_SEARCH for openat(2)
Still missing:
- some flags for openat(2)
- fexecve(2) implementation
2012-11-18 21:41:51 +04:00
|
|
|
if ((error = fd_nameiat(l, fdat, &nd)) != 0) {
|
2010-11-19 09:44:33 +03:00
|
|
|
pathbuf_destroy(pb);
|
|
|
|
return error;
|
|
|
|
}
|
1994-06-29 10:29:24 +04:00
|
|
|
vp = nd.ni_vp;
|
2010-11-19 09:44:33 +03:00
|
|
|
pathbuf_destroy(pb);
|
1994-06-29 10:29:24 +04:00
|
|
|
if (vp->v_type != VLNK)
|
|
|
|
error = EINVAL;
|
1997-10-31 01:47:06 +03:00
|
|
|
else if (!(vp->v_mount->mnt_flag & MNT_SYMPERM) ||
|
2007-11-26 22:01:26 +03:00
|
|
|
(error = VOP_ACCESS(vp, VREAD, l->l_cred)) == 0) {
|
Add most system calls for POSIX extended API set, part 2, with test cases:
faccessat(2), fchmodat(2), fchownat(2), fstatat(2), mkdirat(2), mkfifoat(2),
mknodat(2), linkat(2), readlinkat(2), symlinkat(2), renameat(2), unlinkat(2),
utimensat(2), openat(2).
Also implement O_SEARCH for openat(2)
Still missing:
- some flags for openat(2)
- fexecve(2) implementation
2012-11-18 21:41:51 +04:00
|
|
|
aiov.iov_base = buf;
|
|
|
|
aiov.iov_len = count;
|
1994-06-29 10:29:24 +04:00
|
|
|
auio.uio_iov = &aiov;
|
|
|
|
auio.uio_iovcnt = 1;
|
|
|
|
auio.uio_offset = 0;
|
|
|
|
auio.uio_rw = UIO_READ;
|
2006-03-01 15:38:10 +03:00
|
|
|
KASSERT(l == curlwp);
|
|
|
|
auio.uio_vmspace = l->l_proc->p_vmspace;
|
Add most system calls for POSIX extended API set, part 2, with test cases:
faccessat(2), fchmodat(2), fchownat(2), fstatat(2), mkdirat(2), mkfifoat(2),
mknodat(2), linkat(2), readlinkat(2), symlinkat(2), renameat(2), unlinkat(2),
utimensat(2), openat(2).
Also implement O_SEARCH for openat(2)
Still missing:
- some flags for openat(2)
- fexecve(2) implementation
2012-11-18 21:41:51 +04:00
|
|
|
auio.uio_resid = count;
|
2006-07-24 02:06:03 +04:00
|
|
|
error = VOP_READLINK(vp, &auio, l->l_cred);
|
1994-06-29 10:29:24 +04:00
|
|
|
}
|
|
|
|
vput(vp);
|
Add most system calls for POSIX extended API set, part 2, with test cases:
faccessat(2), fchmodat(2), fchownat(2), fstatat(2), mkdirat(2), mkfifoat(2),
mknodat(2), linkat(2), readlinkat(2), symlinkat(2), renameat(2), unlinkat(2),
utimensat(2), openat(2).
Also implement O_SEARCH for openat(2)
Still missing:
- some flags for openat(2)
- fexecve(2) implementation
2012-11-18 21:41:51 +04:00
|
|
|
*retval = count - auio.uio_resid;
|
1994-06-29 10:29:24 +04:00
|
|
|
return (error);
|
|
|
|
}
|
|
|
|
|
2011-08-08 16:08:52 +04:00
|
|
|
int
|
|
|
|
sys_readlinkat(struct lwp *l, const struct sys_readlinkat_args *uap,
|
|
|
|
register_t *retval)
|
|
|
|
{
|
|
|
|
/* {
|
|
|
|
syscallarg(int) fd;
|
|
|
|
syscallarg(const char *) path;
|
|
|
|
syscallarg(char *) buf;
|
Add most system calls for POSIX extended API set, part 2, with test cases:
faccessat(2), fchmodat(2), fchownat(2), fstatat(2), mkdirat(2), mkfifoat(2),
mknodat(2), linkat(2), readlinkat(2), symlinkat(2), renameat(2), unlinkat(2),
utimensat(2), openat(2).
Also implement O_SEARCH for openat(2)
Still missing:
- some flags for openat(2)
- fexecve(2) implementation
2012-11-18 21:41:51 +04:00
|
|
|
syscallarg(size_t) bufsize;
|
2011-08-08 16:08:52 +04:00
|
|
|
} */
|
|
|
|
|
Add most system calls for POSIX extended API set, part 2, with test cases:
faccessat(2), fchmodat(2), fchownat(2), fstatat(2), mkdirat(2), mkfifoat(2),
mknodat(2), linkat(2), readlinkat(2), symlinkat(2), renameat(2), unlinkat(2),
utimensat(2), openat(2).
Also implement O_SEARCH for openat(2)
Still missing:
- some flags for openat(2)
- fexecve(2) implementation
2012-11-18 21:41:51 +04:00
|
|
|
return do_sys_readlinkat(l, SCARG(uap, fd), SCARG(uap, path),
|
|
|
|
SCARG(uap, buf), SCARG(uap, bufsize), retval);
|
2011-08-08 16:08:52 +04:00
|
|
|
}
|
|
|
|
|
1994-06-29 10:29:24 +04:00
|
|
|
/*
|
|
|
|
* Change flags of a file given a path name.
|
|
|
|
*/
|
|
|
|
/* ARGSUSED */
|
1996-02-04 05:17:43 +03:00
|
|
|
int
|
2007-12-21 02:02:38 +03:00
|
|
|
sys_chflags(struct lwp *l, const struct sys_chflags_args *uap, register_t *retval)
|
1995-09-20 01:40:36 +04:00
|
|
|
{
|
2007-12-21 02:02:38 +03:00
|
|
|
/* {
|
1996-12-22 13:21:06 +03:00
|
|
|
syscallarg(const char *) path;
|
|
|
|
syscallarg(u_long) flags;
|
2007-12-21 02:02:38 +03:00
|
|
|
} */
|
2000-03-30 13:27:11 +04:00
|
|
|
struct vnode *vp;
|
1994-06-29 10:29:24 +04:00
|
|
|
int error;
|
|
|
|
|
Convert 67 namei call sites to use namei_simple, in these functions:
check_console, veriexecclose, veriexec_delete, veriexec_file_add,
emul_find_root, coff_load_shlib (sh3 version), coff_load_shlib,
compat_20_sys_statfs, compat_20_netbsd32_statfs,
ELFNAME2(netbsd32,probe_noteless), darwin_sys_statfs,
ibcs2_sys_statfs, ibcs2_sys_statvfs, linux_sys_uselib,
osf1_sys_statfs, sunos_sys_statfs, sunos32_sys_statfs,
ultrix_sys_statfs, do_sys_mount, fss_create_files (3 of 4),
adosfs_mount, cd9660_mount, coda_ioctl, coda_mount, ext2fs_mount,
ffs_mount, filecore_mount, hfs_mount, lfs_mount, msdosfs_mount,
ntfs_mount, sysvbfs_mount, udf_mount, union_mount, sys_chflags,
sys_lchflags, sys_chmod, sys_lchmod, sys_chown, sys_lchown,
sys___posix_chown, sys___posix_lchown, sys_link, do_sys_pstatvfs,
sys_quotactl, sys_revoke, sys_truncate, do_sys_utimes, sys_extattrctl,
sys_extattr_set_file, sys_extattr_set_link, sys_extattr_get_file,
sys_extattr_get_link, sys_extattr_delete_file,
sys_extattr_delete_link, sys_extattr_list_file, sys_extattr_list_link,
sys_setxattr, sys_lsetxattr, sys_getxattr, sys_lgetxattr,
sys_listxattr, sys_llistxattr, sys_removexattr, sys_lremovexattr
All have been scrutinized (several times, in fact) and compile-tested,
but not all have been explicitly tested in action.
XXX: While I haven't (intentionally) changed the use or nonuse of
XXX: TRYEMULROOT in any of these places, I'm not convinced all the
XXX: uses are correct; an audit might be desirable.
2009-06-29 09:08:15 +04:00
|
|
|
error = namei_simple_user(SCARG(uap, path),
|
|
|
|
NSM_FOLLOW_TRYEMULROOT, &vp);
|
|
|
|
if (error != 0)
|
1994-06-29 10:29:24 +04:00
|
|
|
return (error);
|
2005-12-11 15:16:03 +03:00
|
|
|
error = change_flags(vp, SCARG(uap, flags), l);
|
1994-06-29 10:29:24 +04:00
|
|
|
vput(vp);
|
|
|
|
return (error);
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Change flags of a file given a file descriptor.
|
|
|
|
*/
|
|
|
|
/* ARGSUSED */
|
1996-02-04 05:17:43 +03:00
|
|
|
int
|
2007-12-21 02:02:38 +03:00
|
|
|
sys_fchflags(struct lwp *l, const struct sys_fchflags_args *uap, register_t *retval)
|
1995-09-20 01:40:36 +04:00
|
|
|
{
|
2007-12-21 02:02:38 +03:00
|
|
|
/* {
|
1994-10-20 07:22:35 +03:00
|
|
|
syscallarg(int) fd;
|
1996-12-22 13:21:06 +03:00
|
|
|
syscallarg(u_long) flags;
|
2007-12-21 02:02:38 +03:00
|
|
|
} */
|
1994-06-29 10:29:24 +04:00
|
|
|
struct vnode *vp;
|
2008-03-22 00:54:58 +03:00
|
|
|
file_t *fp;
|
1994-06-29 10:29:24 +04:00
|
|
|
int error;
|
|
|
|
|
2008-03-22 00:54:58 +03:00
|
|
|
/* fd_getvnode() will use the descriptor for us */
|
|
|
|
if ((error = fd_getvnode(SCARG(uap, fd), &fp)) != 0)
|
1994-06-29 10:29:24 +04:00
|
|
|
return (error);
|
2008-03-22 00:54:58 +03:00
|
|
|
vp = fp->f_data;
|
2005-12-11 15:16:03 +03:00
|
|
|
error = change_flags(vp, SCARG(uap, flags), l);
|
2010-06-24 16:58:48 +04:00
|
|
|
VOP_UNLOCK(vp);
|
2008-03-22 00:54:58 +03:00
|
|
|
fd_putfile(SCARG(uap, fd));
|
1994-06-29 10:29:24 +04:00
|
|
|
return (error);
|
|
|
|
}
|
|
|
|
|
2000-04-17 18:31:21 +04:00
|
|
|
/*
|
2000-09-28 10:43:20 +04:00
|
|
|
* Change flags of a file given a path name; this version does
|
2000-04-17 18:31:21 +04:00
|
|
|
* not follow links.
|
|
|
|
*/
|
|
|
|
int
|
2007-12-21 02:02:38 +03:00
|
|
|
sys_lchflags(struct lwp *l, const struct sys_lchflags_args *uap, register_t *retval)
|
2000-04-17 18:31:21 +04:00
|
|
|
{
|
2007-12-21 02:02:38 +03:00
|
|
|
/* {
|
2000-04-17 18:31:21 +04:00
|
|
|
syscallarg(const char *) path;
|
|
|
|
syscallarg(u_long) flags;
|
2007-12-21 02:02:38 +03:00
|
|
|
} */
|
2000-09-28 10:43:20 +04:00
|
|
|
struct vnode *vp;
|
2000-04-17 18:31:21 +04:00
|
|
|
int error;
|
|
|
|
|
Convert 67 namei call sites to use namei_simple, in these functions:
check_console, veriexecclose, veriexec_delete, veriexec_file_add,
emul_find_root, coff_load_shlib (sh3 version), coff_load_shlib,
compat_20_sys_statfs, compat_20_netbsd32_statfs,
ELFNAME2(netbsd32,probe_noteless), darwin_sys_statfs,
ibcs2_sys_statfs, ibcs2_sys_statvfs, linux_sys_uselib,
osf1_sys_statfs, sunos_sys_statfs, sunos32_sys_statfs,
ultrix_sys_statfs, do_sys_mount, fss_create_files (3 of 4),
adosfs_mount, cd9660_mount, coda_ioctl, coda_mount, ext2fs_mount,
ffs_mount, filecore_mount, hfs_mount, lfs_mount, msdosfs_mount,
ntfs_mount, sysvbfs_mount, udf_mount, union_mount, sys_chflags,
sys_lchflags, sys_chmod, sys_lchmod, sys_chown, sys_lchown,
sys___posix_chown, sys___posix_lchown, sys_link, do_sys_pstatvfs,
sys_quotactl, sys_revoke, sys_truncate, do_sys_utimes, sys_extattrctl,
sys_extattr_set_file, sys_extattr_set_link, sys_extattr_get_file,
sys_extattr_get_link, sys_extattr_delete_file,
sys_extattr_delete_link, sys_extattr_list_file, sys_extattr_list_link,
sys_setxattr, sys_lsetxattr, sys_getxattr, sys_lgetxattr,
sys_listxattr, sys_llistxattr, sys_removexattr, sys_lremovexattr
All have been scrutinized (several times, in fact) and compile-tested,
but not all have been explicitly tested in action.
XXX: While I haven't (intentionally) changed the use or nonuse of
XXX: TRYEMULROOT in any of these places, I'm not convinced all the
XXX: uses are correct; an audit might be desirable.
2009-06-29 09:08:15 +04:00
|
|
|
error = namei_simple_user(SCARG(uap, path),
|
|
|
|
NSM_NOFOLLOW_TRYEMULROOT, &vp);
|
|
|
|
if (error != 0)
|
2000-04-17 18:31:21 +04:00
|
|
|
return (error);
|
2005-12-11 15:16:03 +03:00
|
|
|
error = change_flags(vp, SCARG(uap, flags), l);
|
2000-09-28 10:43:20 +04:00
|
|
|
vput(vp);
|
|
|
|
return (error);
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Common routine to change flags of a file.
|
|
|
|
*/
|
|
|
|
int
|
2005-12-11 15:16:03 +03:00
|
|
|
change_flags(struct vnode *vp, u_long flags, struct lwp *l)
|
2000-09-28 10:43:20 +04:00
|
|
|
{
|
|
|
|
struct vattr vattr;
|
|
|
|
int error;
|
|
|
|
|
2000-04-17 18:31:21 +04:00
|
|
|
vn_lock(vp, LK_EXCLUSIVE | LK_RETRY);
|
2012-03-13 22:40:26 +04:00
|
|
|
|
2010-01-08 14:35:07 +03:00
|
|
|
vattr_null(&vattr);
|
2000-09-28 10:43:20 +04:00
|
|
|
vattr.va_flags = flags;
|
2007-11-26 22:01:26 +03:00
|
|
|
error = VOP_SETATTR(vp, &vattr, l->l_cred);
|
2012-03-13 22:40:26 +04:00
|
|
|
|
2000-04-17 18:31:21 +04:00
|
|
|
return (error);
|
|
|
|
}
|
|
|
|
|
1994-06-29 10:29:24 +04:00
|
|
|
/*
|
1997-10-03 18:44:26 +04:00
|
|
|
* Change mode of a file given path name; this version follows links.
|
1994-06-29 10:29:24 +04:00
|
|
|
*/
|
|
|
|
/* ARGSUSED */
|
1996-02-04 05:17:43 +03:00
|
|
|
int
|
2007-12-21 02:02:38 +03:00
|
|
|
sys_chmod(struct lwp *l, const struct sys_chmod_args *uap, register_t *retval)
|
1995-09-20 01:40:36 +04:00
|
|
|
{
|
2007-12-21 02:02:38 +03:00
|
|
|
/* {
|
1996-12-22 13:21:06 +03:00
|
|
|
syscallarg(const char *) path;
|
1994-10-20 07:22:35 +03:00
|
|
|
syscallarg(int) mode;
|
2007-12-21 02:02:38 +03:00
|
|
|
} */
|
Add most system calls for POSIX extended API set, part 2, with test cases:
faccessat(2), fchmodat(2), fchownat(2), fstatat(2), mkdirat(2), mkfifoat(2),
mknodat(2), linkat(2), readlinkat(2), symlinkat(2), renameat(2), unlinkat(2),
utimensat(2), openat(2).
Also implement O_SEARCH for openat(2)
Still missing:
- some flags for openat(2)
- fexecve(2) implementation
2012-11-18 21:41:51 +04:00
|
|
|
return do_sys_chmodat(l, AT_FDCWD, SCARG(uap, path),
|
|
|
|
SCARG(uap, mode), 0);
|
|
|
|
}
|
|
|
|
|
|
|
|
static int
|
|
|
|
do_sys_chmodat(struct lwp *l, int fdat, const char *path, int mode, int flags)
|
|
|
|
{
|
1994-06-29 10:29:24 +04:00
|
|
|
int error;
|
Convert 67 namei call sites to use namei_simple, in these functions:
check_console, veriexecclose, veriexec_delete, veriexec_file_add,
emul_find_root, coff_load_shlib (sh3 version), coff_load_shlib,
compat_20_sys_statfs, compat_20_netbsd32_statfs,
ELFNAME2(netbsd32,probe_noteless), darwin_sys_statfs,
ibcs2_sys_statfs, ibcs2_sys_statvfs, linux_sys_uselib,
osf1_sys_statfs, sunos_sys_statfs, sunos32_sys_statfs,
ultrix_sys_statfs, do_sys_mount, fss_create_files (3 of 4),
adosfs_mount, cd9660_mount, coda_ioctl, coda_mount, ext2fs_mount,
ffs_mount, filecore_mount, hfs_mount, lfs_mount, msdosfs_mount,
ntfs_mount, sysvbfs_mount, udf_mount, union_mount, sys_chflags,
sys_lchflags, sys_chmod, sys_lchmod, sys_chown, sys_lchown,
sys___posix_chown, sys___posix_lchown, sys_link, do_sys_pstatvfs,
sys_quotactl, sys_revoke, sys_truncate, do_sys_utimes, sys_extattrctl,
sys_extattr_set_file, sys_extattr_set_link, sys_extattr_get_file,
sys_extattr_get_link, sys_extattr_delete_file,
sys_extattr_delete_link, sys_extattr_list_file, sys_extattr_list_link,
sys_setxattr, sys_lsetxattr, sys_getxattr, sys_lgetxattr,
sys_listxattr, sys_llistxattr, sys_removexattr, sys_lremovexattr
All have been scrutinized (several times, in fact) and compile-tested,
but not all have been explicitly tested in action.
XXX: While I haven't (intentionally) changed the use or nonuse of
XXX: TRYEMULROOT in any of these places, I'm not convinced all the
XXX: uses are correct; an audit might be desirable.
2009-06-29 09:08:15 +04:00
|
|
|
struct vnode *vp;
|
Add most system calls for POSIX extended API set, part 2, with test cases:
faccessat(2), fchmodat(2), fchownat(2), fstatat(2), mkdirat(2), mkfifoat(2),
mknodat(2), linkat(2), readlinkat(2), symlinkat(2), renameat(2), unlinkat(2),
utimensat(2), openat(2).
Also implement O_SEARCH for openat(2)
Still missing:
- some flags for openat(2)
- fexecve(2) implementation
2012-11-18 21:41:51 +04:00
|
|
|
namei_simple_flags_t ns_flag;
|
1994-06-29 10:29:24 +04:00
|
|
|
|
Add most system calls for POSIX extended API set, part 2, with test cases:
faccessat(2), fchmodat(2), fchownat(2), fstatat(2), mkdirat(2), mkfifoat(2),
mknodat(2), linkat(2), readlinkat(2), symlinkat(2), renameat(2), unlinkat(2),
utimensat(2), openat(2).
Also implement O_SEARCH for openat(2)
Still missing:
- some flags for openat(2)
- fexecve(2) implementation
2012-11-18 21:41:51 +04:00
|
|
|
if (flags & AT_SYMLINK_NOFOLLOW)
|
|
|
|
ns_flag = NSM_NOFOLLOW_TRYEMULROOT;
|
|
|
|
else
|
|
|
|
ns_flag = NSM_FOLLOW_TRYEMULROOT;
|
|
|
|
|
|
|
|
error = fd_nameiat_simple_user(l, fdat, path, ns_flag, &vp);
|
Convert 67 namei call sites to use namei_simple, in these functions:
check_console, veriexecclose, veriexec_delete, veriexec_file_add,
emul_find_root, coff_load_shlib (sh3 version), coff_load_shlib,
compat_20_sys_statfs, compat_20_netbsd32_statfs,
ELFNAME2(netbsd32,probe_noteless), darwin_sys_statfs,
ibcs2_sys_statfs, ibcs2_sys_statvfs, linux_sys_uselib,
osf1_sys_statfs, sunos_sys_statfs, sunos32_sys_statfs,
ultrix_sys_statfs, do_sys_mount, fss_create_files (3 of 4),
adosfs_mount, cd9660_mount, coda_ioctl, coda_mount, ext2fs_mount,
ffs_mount, filecore_mount, hfs_mount, lfs_mount, msdosfs_mount,
ntfs_mount, sysvbfs_mount, udf_mount, union_mount, sys_chflags,
sys_lchflags, sys_chmod, sys_lchmod, sys_chown, sys_lchown,
sys___posix_chown, sys___posix_lchown, sys_link, do_sys_pstatvfs,
sys_quotactl, sys_revoke, sys_truncate, do_sys_utimes, sys_extattrctl,
sys_extattr_set_file, sys_extattr_set_link, sys_extattr_get_file,
sys_extattr_get_link, sys_extattr_delete_file,
sys_extattr_delete_link, sys_extattr_list_file, sys_extattr_list_link,
sys_setxattr, sys_lsetxattr, sys_getxattr, sys_lgetxattr,
sys_listxattr, sys_llistxattr, sys_removexattr, sys_lremovexattr
All have been scrutinized (several times, in fact) and compile-tested,
but not all have been explicitly tested in action.
XXX: While I haven't (intentionally) changed the use or nonuse of
XXX: TRYEMULROOT in any of these places, I'm not convinced all the
XXX: uses are correct; an audit might be desirable.
2009-06-29 09:08:15 +04:00
|
|
|
if (error != 0)
|
Add most system calls for POSIX extended API set, part 2, with test cases:
faccessat(2), fchmodat(2), fchownat(2), fstatat(2), mkdirat(2), mkfifoat(2),
mknodat(2), linkat(2), readlinkat(2), symlinkat(2), renameat(2), unlinkat(2),
utimensat(2), openat(2).
Also implement O_SEARCH for openat(2)
Still missing:
- some flags for openat(2)
- fexecve(2) implementation
2012-11-18 21:41:51 +04:00
|
|
|
return error;
|
1997-10-03 18:14:36 +04:00
|
|
|
|
Add most system calls for POSIX extended API set, part 2, with test cases:
faccessat(2), fchmodat(2), fchownat(2), fstatat(2), mkdirat(2), mkfifoat(2),
mknodat(2), linkat(2), readlinkat(2), symlinkat(2), renameat(2), unlinkat(2),
utimensat(2), openat(2).
Also implement O_SEARCH for openat(2)
Still missing:
- some flags for openat(2)
- fexecve(2) implementation
2012-11-18 21:41:51 +04:00
|
|
|
error = change_mode(vp, mode, l);
|
1997-10-03 18:14:36 +04:00
|
|
|
|
Convert 67 namei call sites to use namei_simple, in these functions:
check_console, veriexecclose, veriexec_delete, veriexec_file_add,
emul_find_root, coff_load_shlib (sh3 version), coff_load_shlib,
compat_20_sys_statfs, compat_20_netbsd32_statfs,
ELFNAME2(netbsd32,probe_noteless), darwin_sys_statfs,
ibcs2_sys_statfs, ibcs2_sys_statvfs, linux_sys_uselib,
osf1_sys_statfs, sunos_sys_statfs, sunos32_sys_statfs,
ultrix_sys_statfs, do_sys_mount, fss_create_files (3 of 4),
adosfs_mount, cd9660_mount, coda_ioctl, coda_mount, ext2fs_mount,
ffs_mount, filecore_mount, hfs_mount, lfs_mount, msdosfs_mount,
ntfs_mount, sysvbfs_mount, udf_mount, union_mount, sys_chflags,
sys_lchflags, sys_chmod, sys_lchmod, sys_chown, sys_lchown,
sys___posix_chown, sys___posix_lchown, sys_link, do_sys_pstatvfs,
sys_quotactl, sys_revoke, sys_truncate, do_sys_utimes, sys_extattrctl,
sys_extattr_set_file, sys_extattr_set_link, sys_extattr_get_file,
sys_extattr_get_link, sys_extattr_delete_file,
sys_extattr_delete_link, sys_extattr_list_file, sys_extattr_list_link,
sys_setxattr, sys_lsetxattr, sys_getxattr, sys_lgetxattr,
sys_listxattr, sys_llistxattr, sys_removexattr, sys_lremovexattr
All have been scrutinized (several times, in fact) and compile-tested,
but not all have been explicitly tested in action.
XXX: While I haven't (intentionally) changed the use or nonuse of
XXX: TRYEMULROOT in any of these places, I'm not convinced all the
XXX: uses are correct; an audit might be desirable.
2009-06-29 09:08:15 +04:00
|
|
|
vrele(vp);
|
Add most system calls for POSIX extended API set, part 2, with test cases:
faccessat(2), fchmodat(2), fchownat(2), fstatat(2), mkdirat(2), mkfifoat(2),
mknodat(2), linkat(2), readlinkat(2), symlinkat(2), renameat(2), unlinkat(2),
utimensat(2), openat(2).
Also implement O_SEARCH for openat(2)
Still missing:
- some flags for openat(2)
- fexecve(2) implementation
2012-11-18 21:41:51 +04:00
|
|
|
|
1994-06-29 10:29:24 +04:00
|
|
|
return (error);
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Change mode of a file given a file descriptor.
|
|
|
|
*/
|
|
|
|
/* ARGSUSED */
|
1996-02-04 05:17:43 +03:00
|
|
|
int
|
2007-12-21 02:02:38 +03:00
|
|
|
sys_fchmod(struct lwp *l, const struct sys_fchmod_args *uap, register_t *retval)
|
1995-09-20 01:40:36 +04:00
|
|
|
{
|
2007-12-21 02:02:38 +03:00
|
|
|
/* {
|
1994-10-20 07:22:35 +03:00
|
|
|
syscallarg(int) fd;
|
|
|
|
syscallarg(int) mode;
|
2007-12-21 02:02:38 +03:00
|
|
|
} */
|
2008-03-22 00:54:58 +03:00
|
|
|
file_t *fp;
|
1994-06-29 10:29:24 +04:00
|
|
|
int error;
|
|
|
|
|
2008-03-22 00:54:58 +03:00
|
|
|
/* fd_getvnode() will use the descriptor for us */
|
|
|
|
if ((error = fd_getvnode(SCARG(uap, fd), &fp)) != 0)
|
1994-06-29 10:29:24 +04:00
|
|
|
return (error);
|
2008-03-22 00:54:58 +03:00
|
|
|
error = change_mode(fp->f_data, SCARG(uap, mode), l);
|
|
|
|
fd_putfile(SCARG(uap, fd));
|
1999-05-06 00:01:01 +04:00
|
|
|
return (error);
|
1997-10-03 18:14:36 +04:00
|
|
|
}
|
|
|
|
|
2011-08-08 16:08:52 +04:00
|
|
|
int
|
|
|
|
sys_fchmodat(struct lwp *l, const struct sys_fchmodat_args *uap,
|
|
|
|
register_t *retval)
|
|
|
|
{
|
|
|
|
/* {
|
|
|
|
syscallarg(int) fd;
|
|
|
|
syscallarg(const char *) path;
|
|
|
|
syscallarg(int) mode;
|
|
|
|
syscallarg(int) flag;
|
|
|
|
} */
|
|
|
|
|
Add most system calls for POSIX extended API set, part 2, with test cases:
faccessat(2), fchmodat(2), fchownat(2), fstatat(2), mkdirat(2), mkfifoat(2),
mknodat(2), linkat(2), readlinkat(2), symlinkat(2), renameat(2), unlinkat(2),
utimensat(2), openat(2).
Also implement O_SEARCH for openat(2)
Still missing:
- some flags for openat(2)
- fexecve(2) implementation
2012-11-18 21:41:51 +04:00
|
|
|
return do_sys_chmodat(l, SCARG(uap, fd), SCARG(uap, path),
|
|
|
|
SCARG(uap, mode), SCARG(uap, flag));
|
2011-08-08 16:08:52 +04:00
|
|
|
}
|
|
|
|
|
1997-10-03 18:44:26 +04:00
|
|
|
/*
|
|
|
|
* Change mode of a file given path name; this version does not follow links.
|
|
|
|
*/
|
|
|
|
/* ARGSUSED */
|
|
|
|
int
|
2007-12-21 02:02:38 +03:00
|
|
|
sys_lchmod(struct lwp *l, const struct sys_lchmod_args *uap, register_t *retval)
|
1997-10-03 18:44:26 +04:00
|
|
|
{
|
2007-12-21 02:02:38 +03:00
|
|
|
/* {
|
1997-10-03 18:44:26 +04:00
|
|
|
syscallarg(const char *) path;
|
|
|
|
syscallarg(int) mode;
|
2007-12-21 02:02:38 +03:00
|
|
|
} */
|
1997-10-03 18:44:26 +04:00
|
|
|
int error;
|
Convert 67 namei call sites to use namei_simple, in these functions:
check_console, veriexecclose, veriexec_delete, veriexec_file_add,
emul_find_root, coff_load_shlib (sh3 version), coff_load_shlib,
compat_20_sys_statfs, compat_20_netbsd32_statfs,
ELFNAME2(netbsd32,probe_noteless), darwin_sys_statfs,
ibcs2_sys_statfs, ibcs2_sys_statvfs, linux_sys_uselib,
osf1_sys_statfs, sunos_sys_statfs, sunos32_sys_statfs,
ultrix_sys_statfs, do_sys_mount, fss_create_files (3 of 4),
adosfs_mount, cd9660_mount, coda_ioctl, coda_mount, ext2fs_mount,
ffs_mount, filecore_mount, hfs_mount, lfs_mount, msdosfs_mount,
ntfs_mount, sysvbfs_mount, udf_mount, union_mount, sys_chflags,
sys_lchflags, sys_chmod, sys_lchmod, sys_chown, sys_lchown,
sys___posix_chown, sys___posix_lchown, sys_link, do_sys_pstatvfs,
sys_quotactl, sys_revoke, sys_truncate, do_sys_utimes, sys_extattrctl,
sys_extattr_set_file, sys_extattr_set_link, sys_extattr_get_file,
sys_extattr_get_link, sys_extattr_delete_file,
sys_extattr_delete_link, sys_extattr_list_file, sys_extattr_list_link,
sys_setxattr, sys_lsetxattr, sys_getxattr, sys_lgetxattr,
sys_listxattr, sys_llistxattr, sys_removexattr, sys_lremovexattr
All have been scrutinized (several times, in fact) and compile-tested,
but not all have been explicitly tested in action.
XXX: While I haven't (intentionally) changed the use or nonuse of
XXX: TRYEMULROOT in any of these places, I'm not convinced all the
XXX: uses are correct; an audit might be desirable.
2009-06-29 09:08:15 +04:00
|
|
|
struct vnode *vp;
|
1997-10-03 18:44:26 +04:00
|
|
|
|
Convert 67 namei call sites to use namei_simple, in these functions:
check_console, veriexecclose, veriexec_delete, veriexec_file_add,
emul_find_root, coff_load_shlib (sh3 version), coff_load_shlib,
compat_20_sys_statfs, compat_20_netbsd32_statfs,
ELFNAME2(netbsd32,probe_noteless), darwin_sys_statfs,
ibcs2_sys_statfs, ibcs2_sys_statvfs, linux_sys_uselib,
osf1_sys_statfs, sunos_sys_statfs, sunos32_sys_statfs,
ultrix_sys_statfs, do_sys_mount, fss_create_files (3 of 4),
adosfs_mount, cd9660_mount, coda_ioctl, coda_mount, ext2fs_mount,
ffs_mount, filecore_mount, hfs_mount, lfs_mount, msdosfs_mount,
ntfs_mount, sysvbfs_mount, udf_mount, union_mount, sys_chflags,
sys_lchflags, sys_chmod, sys_lchmod, sys_chown, sys_lchown,
sys___posix_chown, sys___posix_lchown, sys_link, do_sys_pstatvfs,
sys_quotactl, sys_revoke, sys_truncate, do_sys_utimes, sys_extattrctl,
sys_extattr_set_file, sys_extattr_set_link, sys_extattr_get_file,
sys_extattr_get_link, sys_extattr_delete_file,
sys_extattr_delete_link, sys_extattr_list_file, sys_extattr_list_link,
sys_setxattr, sys_lsetxattr, sys_getxattr, sys_lgetxattr,
sys_listxattr, sys_llistxattr, sys_removexattr, sys_lremovexattr
All have been scrutinized (several times, in fact) and compile-tested,
but not all have been explicitly tested in action.
XXX: While I haven't (intentionally) changed the use or nonuse of
XXX: TRYEMULROOT in any of these places, I'm not convinced all the
XXX: uses are correct; an audit might be desirable.
2009-06-29 09:08:15 +04:00
|
|
|
error = namei_simple_user(SCARG(uap, path),
|
|
|
|
NSM_NOFOLLOW_TRYEMULROOT, &vp);
|
|
|
|
if (error != 0)
|
1997-10-03 18:44:26 +04:00
|
|
|
return (error);
|
|
|
|
|
Convert 67 namei call sites to use namei_simple, in these functions:
check_console, veriexecclose, veriexec_delete, veriexec_file_add,
emul_find_root, coff_load_shlib (sh3 version), coff_load_shlib,
compat_20_sys_statfs, compat_20_netbsd32_statfs,
ELFNAME2(netbsd32,probe_noteless), darwin_sys_statfs,
ibcs2_sys_statfs, ibcs2_sys_statvfs, linux_sys_uselib,
osf1_sys_statfs, sunos_sys_statfs, sunos32_sys_statfs,
ultrix_sys_statfs, do_sys_mount, fss_create_files (3 of 4),
adosfs_mount, cd9660_mount, coda_ioctl, coda_mount, ext2fs_mount,
ffs_mount, filecore_mount, hfs_mount, lfs_mount, msdosfs_mount,
ntfs_mount, sysvbfs_mount, udf_mount, union_mount, sys_chflags,
sys_lchflags, sys_chmod, sys_lchmod, sys_chown, sys_lchown,
sys___posix_chown, sys___posix_lchown, sys_link, do_sys_pstatvfs,
sys_quotactl, sys_revoke, sys_truncate, do_sys_utimes, sys_extattrctl,
sys_extattr_set_file, sys_extattr_set_link, sys_extattr_get_file,
sys_extattr_get_link, sys_extattr_delete_file,
sys_extattr_delete_link, sys_extattr_list_file, sys_extattr_list_link,
sys_setxattr, sys_lsetxattr, sys_getxattr, sys_lgetxattr,
sys_listxattr, sys_llistxattr, sys_removexattr, sys_lremovexattr
All have been scrutinized (several times, in fact) and compile-tested,
but not all have been explicitly tested in action.
XXX: While I haven't (intentionally) changed the use or nonuse of
XXX: TRYEMULROOT in any of these places, I'm not convinced all the
XXX: uses are correct; an audit might be desirable.
2009-06-29 09:08:15 +04:00
|
|
|
error = change_mode(vp, SCARG(uap, mode), l);
|
1997-10-03 18:44:26 +04:00
|
|
|
|
Convert 67 namei call sites to use namei_simple, in these functions:
check_console, veriexecclose, veriexec_delete, veriexec_file_add,
emul_find_root, coff_load_shlib (sh3 version), coff_load_shlib,
compat_20_sys_statfs, compat_20_netbsd32_statfs,
ELFNAME2(netbsd32,probe_noteless), darwin_sys_statfs,
ibcs2_sys_statfs, ibcs2_sys_statvfs, linux_sys_uselib,
osf1_sys_statfs, sunos_sys_statfs, sunos32_sys_statfs,
ultrix_sys_statfs, do_sys_mount, fss_create_files (3 of 4),
adosfs_mount, cd9660_mount, coda_ioctl, coda_mount, ext2fs_mount,
ffs_mount, filecore_mount, hfs_mount, lfs_mount, msdosfs_mount,
ntfs_mount, sysvbfs_mount, udf_mount, union_mount, sys_chflags,
sys_lchflags, sys_chmod, sys_lchmod, sys_chown, sys_lchown,
sys___posix_chown, sys___posix_lchown, sys_link, do_sys_pstatvfs,
sys_quotactl, sys_revoke, sys_truncate, do_sys_utimes, sys_extattrctl,
sys_extattr_set_file, sys_extattr_set_link, sys_extattr_get_file,
sys_extattr_get_link, sys_extattr_delete_file,
sys_extattr_delete_link, sys_extattr_list_file, sys_extattr_list_link,
sys_setxattr, sys_lsetxattr, sys_getxattr, sys_lgetxattr,
sys_listxattr, sys_llistxattr, sys_removexattr, sys_lremovexattr
All have been scrutinized (several times, in fact) and compile-tested,
but not all have been explicitly tested in action.
XXX: While I haven't (intentionally) changed the use or nonuse of
XXX: TRYEMULROOT in any of these places, I'm not convinced all the
XXX: uses are correct; an audit might be desirable.
2009-06-29 09:08:15 +04:00
|
|
|
vrele(vp);
|
1997-10-03 18:44:26 +04:00
|
|
|
return (error);
|
|
|
|
}
|
|
|
|
|
1997-10-03 18:14:36 +04:00
|
|
|
/*
|
|
|
|
* Common routine to set mode given a vnode.
|
|
|
|
*/
|
|
|
|
static int
|
2005-12-11 15:16:03 +03:00
|
|
|
change_mode(struct vnode *vp, int mode, struct lwp *l)
|
1997-10-03 18:14:36 +04:00
|
|
|
{
|
|
|
|
struct vattr vattr;
|
|
|
|
int error;
|
|
|
|
|
1998-03-01 05:20:01 +03:00
|
|
|
vn_lock(vp, LK_EXCLUSIVE | LK_RETRY);
|
2010-01-08 14:35:07 +03:00
|
|
|
vattr_null(&vattr);
|
1998-03-01 05:20:01 +03:00
|
|
|
vattr.va_mode = mode & ALLPERMS;
|
2007-11-26 22:01:26 +03:00
|
|
|
error = VOP_SETATTR(vp, &vattr, l->l_cred);
|
2010-06-24 16:58:48 +04:00
|
|
|
VOP_UNLOCK(vp);
|
1994-06-29 10:29:24 +04:00
|
|
|
return (error);
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
1997-10-03 18:44:26 +04:00
|
|
|
* Set ownership given a path name; this version follows links.
|
1994-06-29 10:29:24 +04:00
|
|
|
*/
|
|
|
|
/* ARGSUSED */
|
1996-02-04 05:17:43 +03:00
|
|
|
int
|
2007-12-21 02:02:38 +03:00
|
|
|
sys_chown(struct lwp *l, const struct sys_chown_args *uap, register_t *retval)
|
1995-09-20 01:40:36 +04:00
|
|
|
{
|
2007-12-21 02:02:38 +03:00
|
|
|
/* {
|
1996-12-22 13:21:06 +03:00
|
|
|
syscallarg(const char *) path;
|
|
|
|
syscallarg(uid_t) uid;
|
|
|
|
syscallarg(gid_t) gid;
|
2007-12-21 02:02:38 +03:00
|
|
|
} */
|
Add most system calls for POSIX extended API set, part 2, with test cases:
faccessat(2), fchmodat(2), fchownat(2), fstatat(2), mkdirat(2), mkfifoat(2),
mknodat(2), linkat(2), readlinkat(2), symlinkat(2), renameat(2), unlinkat(2),
utimensat(2), openat(2).
Also implement O_SEARCH for openat(2)
Still missing:
- some flags for openat(2)
- fexecve(2) implementation
2012-11-18 21:41:51 +04:00
|
|
|
return do_sys_chownat(l, AT_FDCWD, SCARG(uap, path), SCARG(uap,uid),
|
|
|
|
SCARG(uap, gid), 0);
|
|
|
|
}
|
|
|
|
|
|
|
|
static int
|
|
|
|
do_sys_chownat(struct lwp *l, int fdat, const char *path, uid_t uid,
|
|
|
|
gid_t gid, int flags)
|
|
|
|
{
|
1994-06-29 10:29:24 +04:00
|
|
|
int error;
|
Convert 67 namei call sites to use namei_simple, in these functions:
check_console, veriexecclose, veriexec_delete, veriexec_file_add,
emul_find_root, coff_load_shlib (sh3 version), coff_load_shlib,
compat_20_sys_statfs, compat_20_netbsd32_statfs,
ELFNAME2(netbsd32,probe_noteless), darwin_sys_statfs,
ibcs2_sys_statfs, ibcs2_sys_statvfs, linux_sys_uselib,
osf1_sys_statfs, sunos_sys_statfs, sunos32_sys_statfs,
ultrix_sys_statfs, do_sys_mount, fss_create_files (3 of 4),
adosfs_mount, cd9660_mount, coda_ioctl, coda_mount, ext2fs_mount,
ffs_mount, filecore_mount, hfs_mount, lfs_mount, msdosfs_mount,
ntfs_mount, sysvbfs_mount, udf_mount, union_mount, sys_chflags,
sys_lchflags, sys_chmod, sys_lchmod, sys_chown, sys_lchown,
sys___posix_chown, sys___posix_lchown, sys_link, do_sys_pstatvfs,
sys_quotactl, sys_revoke, sys_truncate, do_sys_utimes, sys_extattrctl,
sys_extattr_set_file, sys_extattr_set_link, sys_extattr_get_file,
sys_extattr_get_link, sys_extattr_delete_file,
sys_extattr_delete_link, sys_extattr_list_file, sys_extattr_list_link,
sys_setxattr, sys_lsetxattr, sys_getxattr, sys_lgetxattr,
sys_listxattr, sys_llistxattr, sys_removexattr, sys_lremovexattr
All have been scrutinized (several times, in fact) and compile-tested,
but not all have been explicitly tested in action.
XXX: While I haven't (intentionally) changed the use or nonuse of
XXX: TRYEMULROOT in any of these places, I'm not convinced all the
XXX: uses are correct; an audit might be desirable.
2009-06-29 09:08:15 +04:00
|
|
|
struct vnode *vp;
|
Add most system calls for POSIX extended API set, part 2, with test cases:
faccessat(2), fchmodat(2), fchownat(2), fstatat(2), mkdirat(2), mkfifoat(2),
mknodat(2), linkat(2), readlinkat(2), symlinkat(2), renameat(2), unlinkat(2),
utimensat(2), openat(2).
Also implement O_SEARCH for openat(2)
Still missing:
- some flags for openat(2)
- fexecve(2) implementation
2012-11-18 21:41:51 +04:00
|
|
|
namei_simple_flags_t ns_flag;
|
1994-06-29 10:29:24 +04:00
|
|
|
|
Add most system calls for POSIX extended API set, part 2, with test cases:
faccessat(2), fchmodat(2), fchownat(2), fstatat(2), mkdirat(2), mkfifoat(2),
mknodat(2), linkat(2), readlinkat(2), symlinkat(2), renameat(2), unlinkat(2),
utimensat(2), openat(2).
Also implement O_SEARCH for openat(2)
Still missing:
- some flags for openat(2)
- fexecve(2) implementation
2012-11-18 21:41:51 +04:00
|
|
|
if (flags & AT_SYMLINK_NOFOLLOW)
|
|
|
|
ns_flag = NSM_NOFOLLOW_TRYEMULROOT;
|
|
|
|
else
|
|
|
|
ns_flag = NSM_FOLLOW_TRYEMULROOT;
|
|
|
|
|
|
|
|
error = fd_nameiat_simple_user(l, fdat, path, ns_flag, &vp);
|
Convert 67 namei call sites to use namei_simple, in these functions:
check_console, veriexecclose, veriexec_delete, veriexec_file_add,
emul_find_root, coff_load_shlib (sh3 version), coff_load_shlib,
compat_20_sys_statfs, compat_20_netbsd32_statfs,
ELFNAME2(netbsd32,probe_noteless), darwin_sys_statfs,
ibcs2_sys_statfs, ibcs2_sys_statvfs, linux_sys_uselib,
osf1_sys_statfs, sunos_sys_statfs, sunos32_sys_statfs,
ultrix_sys_statfs, do_sys_mount, fss_create_files (3 of 4),
adosfs_mount, cd9660_mount, coda_ioctl, coda_mount, ext2fs_mount,
ffs_mount, filecore_mount, hfs_mount, lfs_mount, msdosfs_mount,
ntfs_mount, sysvbfs_mount, udf_mount, union_mount, sys_chflags,
sys_lchflags, sys_chmod, sys_lchmod, sys_chown, sys_lchown,
sys___posix_chown, sys___posix_lchown, sys_link, do_sys_pstatvfs,
sys_quotactl, sys_revoke, sys_truncate, do_sys_utimes, sys_extattrctl,
sys_extattr_set_file, sys_extattr_set_link, sys_extattr_get_file,
sys_extattr_get_link, sys_extattr_delete_file,
sys_extattr_delete_link, sys_extattr_list_file, sys_extattr_list_link,
sys_setxattr, sys_lsetxattr, sys_getxattr, sys_lgetxattr,
sys_listxattr, sys_llistxattr, sys_removexattr, sys_lremovexattr
All have been scrutinized (several times, in fact) and compile-tested,
but not all have been explicitly tested in action.
XXX: While I haven't (intentionally) changed the use or nonuse of
XXX: TRYEMULROOT in any of these places, I'm not convinced all the
XXX: uses are correct; an audit might be desirable.
2009-06-29 09:08:15 +04:00
|
|
|
if (error != 0)
|
Add most system calls for POSIX extended API set, part 2, with test cases:
faccessat(2), fchmodat(2), fchownat(2), fstatat(2), mkdirat(2), mkfifoat(2),
mknodat(2), linkat(2), readlinkat(2), symlinkat(2), renameat(2), unlinkat(2),
utimensat(2), openat(2).
Also implement O_SEARCH for openat(2)
Still missing:
- some flags for openat(2)
- fexecve(2) implementation
2012-11-18 21:41:51 +04:00
|
|
|
return error;
|
1997-04-30 23:29:43 +04:00
|
|
|
|
Add most system calls for POSIX extended API set, part 2, with test cases:
faccessat(2), fchmodat(2), fchownat(2), fstatat(2), mkdirat(2), mkfifoat(2),
mknodat(2), linkat(2), readlinkat(2), symlinkat(2), renameat(2), unlinkat(2),
utimensat(2), openat(2).
Also implement O_SEARCH for openat(2)
Still missing:
- some flags for openat(2)
- fexecve(2) implementation
2012-11-18 21:41:51 +04:00
|
|
|
error = change_owner(vp, uid, gid, l, 0);
|
1998-02-14 22:49:43 +03:00
|
|
|
|
Convert 67 namei call sites to use namei_simple, in these functions:
check_console, veriexecclose, veriexec_delete, veriexec_file_add,
emul_find_root, coff_load_shlib (sh3 version), coff_load_shlib,
compat_20_sys_statfs, compat_20_netbsd32_statfs,
ELFNAME2(netbsd32,probe_noteless), darwin_sys_statfs,
ibcs2_sys_statfs, ibcs2_sys_statvfs, linux_sys_uselib,
osf1_sys_statfs, sunos_sys_statfs, sunos32_sys_statfs,
ultrix_sys_statfs, do_sys_mount, fss_create_files (3 of 4),
adosfs_mount, cd9660_mount, coda_ioctl, coda_mount, ext2fs_mount,
ffs_mount, filecore_mount, hfs_mount, lfs_mount, msdosfs_mount,
ntfs_mount, sysvbfs_mount, udf_mount, union_mount, sys_chflags,
sys_lchflags, sys_chmod, sys_lchmod, sys_chown, sys_lchown,
sys___posix_chown, sys___posix_lchown, sys_link, do_sys_pstatvfs,
sys_quotactl, sys_revoke, sys_truncate, do_sys_utimes, sys_extattrctl,
sys_extattr_set_file, sys_extattr_set_link, sys_extattr_get_file,
sys_extattr_get_link, sys_extattr_delete_file,
sys_extattr_delete_link, sys_extattr_list_file, sys_extattr_list_link,
sys_setxattr, sys_lsetxattr, sys_getxattr, sys_lgetxattr,
sys_listxattr, sys_llistxattr, sys_removexattr, sys_lremovexattr
All have been scrutinized (several times, in fact) and compile-tested,
but not all have been explicitly tested in action.
XXX: While I haven't (intentionally) changed the use or nonuse of
XXX: TRYEMULROOT in any of these places, I'm not convinced all the
XXX: uses are correct; an audit might be desirable.
2009-06-29 09:08:15 +04:00
|
|
|
vrele(vp);
|
Add most system calls for POSIX extended API set, part 2, with test cases:
faccessat(2), fchmodat(2), fchownat(2), fstatat(2), mkdirat(2), mkfifoat(2),
mknodat(2), linkat(2), readlinkat(2), symlinkat(2), renameat(2), unlinkat(2),
utimensat(2), openat(2).
Also implement O_SEARCH for openat(2)
Still missing:
- some flags for openat(2)
- fexecve(2) implementation
2012-11-18 21:41:51 +04:00
|
|
|
|
1998-02-14 22:49:43 +03:00
|
|
|
return (error);
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Set ownership given a path name; this version follows links.
|
|
|
|
* Provides POSIX semantics.
|
|
|
|
*/
|
|
|
|
/* ARGSUSED */
|
|
|
|
int
|
2007-12-21 02:02:38 +03:00
|
|
|
sys___posix_chown(struct lwp *l, const struct sys___posix_chown_args *uap, register_t *retval)
|
1998-02-14 22:49:43 +03:00
|
|
|
{
|
2007-12-21 02:02:38 +03:00
|
|
|
/* {
|
1998-02-14 22:49:43 +03:00
|
|
|
syscallarg(const char *) path;
|
|
|
|
syscallarg(uid_t) uid;
|
|
|
|
syscallarg(gid_t) gid;
|
2007-12-21 02:02:38 +03:00
|
|
|
} */
|
1998-02-14 22:49:43 +03:00
|
|
|
int error;
|
Convert 67 namei call sites to use namei_simple, in these functions:
check_console, veriexecclose, veriexec_delete, veriexec_file_add,
emul_find_root, coff_load_shlib (sh3 version), coff_load_shlib,
compat_20_sys_statfs, compat_20_netbsd32_statfs,
ELFNAME2(netbsd32,probe_noteless), darwin_sys_statfs,
ibcs2_sys_statfs, ibcs2_sys_statvfs, linux_sys_uselib,
osf1_sys_statfs, sunos_sys_statfs, sunos32_sys_statfs,
ultrix_sys_statfs, do_sys_mount, fss_create_files (3 of 4),
adosfs_mount, cd9660_mount, coda_ioctl, coda_mount, ext2fs_mount,
ffs_mount, filecore_mount, hfs_mount, lfs_mount, msdosfs_mount,
ntfs_mount, sysvbfs_mount, udf_mount, union_mount, sys_chflags,
sys_lchflags, sys_chmod, sys_lchmod, sys_chown, sys_lchown,
sys___posix_chown, sys___posix_lchown, sys_link, do_sys_pstatvfs,
sys_quotactl, sys_revoke, sys_truncate, do_sys_utimes, sys_extattrctl,
sys_extattr_set_file, sys_extattr_set_link, sys_extattr_get_file,
sys_extattr_get_link, sys_extattr_delete_file,
sys_extattr_delete_link, sys_extattr_list_file, sys_extattr_list_link,
sys_setxattr, sys_lsetxattr, sys_getxattr, sys_lgetxattr,
sys_listxattr, sys_llistxattr, sys_removexattr, sys_lremovexattr
All have been scrutinized (several times, in fact) and compile-tested,
but not all have been explicitly tested in action.
XXX: While I haven't (intentionally) changed the use or nonuse of
XXX: TRYEMULROOT in any of these places, I'm not convinced all the
XXX: uses are correct; an audit might be desirable.
2009-06-29 09:08:15 +04:00
|
|
|
struct vnode *vp;
|
1998-02-14 22:49:43 +03:00
|
|
|
|
Convert 67 namei call sites to use namei_simple, in these functions:
check_console, veriexecclose, veriexec_delete, veriexec_file_add,
emul_find_root, coff_load_shlib (sh3 version), coff_load_shlib,
compat_20_sys_statfs, compat_20_netbsd32_statfs,
ELFNAME2(netbsd32,probe_noteless), darwin_sys_statfs,
ibcs2_sys_statfs, ibcs2_sys_statvfs, linux_sys_uselib,
osf1_sys_statfs, sunos_sys_statfs, sunos32_sys_statfs,
ultrix_sys_statfs, do_sys_mount, fss_create_files (3 of 4),
adosfs_mount, cd9660_mount, coda_ioctl, coda_mount, ext2fs_mount,
ffs_mount, filecore_mount, hfs_mount, lfs_mount, msdosfs_mount,
ntfs_mount, sysvbfs_mount, udf_mount, union_mount, sys_chflags,
sys_lchflags, sys_chmod, sys_lchmod, sys_chown, sys_lchown,
sys___posix_chown, sys___posix_lchown, sys_link, do_sys_pstatvfs,
sys_quotactl, sys_revoke, sys_truncate, do_sys_utimes, sys_extattrctl,
sys_extattr_set_file, sys_extattr_set_link, sys_extattr_get_file,
sys_extattr_get_link, sys_extattr_delete_file,
sys_extattr_delete_link, sys_extattr_list_file, sys_extattr_list_link,
sys_setxattr, sys_lsetxattr, sys_getxattr, sys_lgetxattr,
sys_listxattr, sys_llistxattr, sys_removexattr, sys_lremovexattr
All have been scrutinized (several times, in fact) and compile-tested,
but not all have been explicitly tested in action.
XXX: While I haven't (intentionally) changed the use or nonuse of
XXX: TRYEMULROOT in any of these places, I'm not convinced all the
XXX: uses are correct; an audit might be desirable.
2009-06-29 09:08:15 +04:00
|
|
|
error = namei_simple_user(SCARG(uap, path),
|
|
|
|
NSM_FOLLOW_TRYEMULROOT, &vp);
|
|
|
|
if (error != 0)
|
1998-02-14 22:49:43 +03:00
|
|
|
return (error);
|
|
|
|
|
Convert 67 namei call sites to use namei_simple, in these functions:
check_console, veriexecclose, veriexec_delete, veriexec_file_add,
emul_find_root, coff_load_shlib (sh3 version), coff_load_shlib,
compat_20_sys_statfs, compat_20_netbsd32_statfs,
ELFNAME2(netbsd32,probe_noteless), darwin_sys_statfs,
ibcs2_sys_statfs, ibcs2_sys_statvfs, linux_sys_uselib,
osf1_sys_statfs, sunos_sys_statfs, sunos32_sys_statfs,
ultrix_sys_statfs, do_sys_mount, fss_create_files (3 of 4),
adosfs_mount, cd9660_mount, coda_ioctl, coda_mount, ext2fs_mount,
ffs_mount, filecore_mount, hfs_mount, lfs_mount, msdosfs_mount,
ntfs_mount, sysvbfs_mount, udf_mount, union_mount, sys_chflags,
sys_lchflags, sys_chmod, sys_lchmod, sys_chown, sys_lchown,
sys___posix_chown, sys___posix_lchown, sys_link, do_sys_pstatvfs,
sys_quotactl, sys_revoke, sys_truncate, do_sys_utimes, sys_extattrctl,
sys_extattr_set_file, sys_extattr_set_link, sys_extattr_get_file,
sys_extattr_get_link, sys_extattr_delete_file,
sys_extattr_delete_link, sys_extattr_list_file, sys_extattr_list_link,
sys_setxattr, sys_lsetxattr, sys_getxattr, sys_lgetxattr,
sys_listxattr, sys_llistxattr, sys_removexattr, sys_lremovexattr
All have been scrutinized (several times, in fact) and compile-tested,
but not all have been explicitly tested in action.
XXX: While I haven't (intentionally) changed the use or nonuse of
XXX: TRYEMULROOT in any of these places, I'm not convinced all the
XXX: uses are correct; an audit might be desirable.
2009-06-29 09:08:15 +04:00
|
|
|
error = change_owner(vp, SCARG(uap, uid), SCARG(uap, gid), l, 1);
|
1997-04-30 23:29:43 +04:00
|
|
|
|
Convert 67 namei call sites to use namei_simple, in these functions:
check_console, veriexecclose, veriexec_delete, veriexec_file_add,
emul_find_root, coff_load_shlib (sh3 version), coff_load_shlib,
compat_20_sys_statfs, compat_20_netbsd32_statfs,
ELFNAME2(netbsd32,probe_noteless), darwin_sys_statfs,
ibcs2_sys_statfs, ibcs2_sys_statvfs, linux_sys_uselib,
osf1_sys_statfs, sunos_sys_statfs, sunos32_sys_statfs,
ultrix_sys_statfs, do_sys_mount, fss_create_files (3 of 4),
adosfs_mount, cd9660_mount, coda_ioctl, coda_mount, ext2fs_mount,
ffs_mount, filecore_mount, hfs_mount, lfs_mount, msdosfs_mount,
ntfs_mount, sysvbfs_mount, udf_mount, union_mount, sys_chflags,
sys_lchflags, sys_chmod, sys_lchmod, sys_chown, sys_lchown,
sys___posix_chown, sys___posix_lchown, sys_link, do_sys_pstatvfs,
sys_quotactl, sys_revoke, sys_truncate, do_sys_utimes, sys_extattrctl,
sys_extattr_set_file, sys_extattr_set_link, sys_extattr_get_file,
sys_extattr_get_link, sys_extattr_delete_file,
sys_extattr_delete_link, sys_extattr_list_file, sys_extattr_list_link,
sys_setxattr, sys_lsetxattr, sys_getxattr, sys_lgetxattr,
sys_listxattr, sys_llistxattr, sys_removexattr, sys_lremovexattr
All have been scrutinized (several times, in fact) and compile-tested,
but not all have been explicitly tested in action.
XXX: While I haven't (intentionally) changed the use or nonuse of
XXX: TRYEMULROOT in any of these places, I'm not convinced all the
XXX: uses are correct; an audit might be desirable.
2009-06-29 09:08:15 +04:00
|
|
|
vrele(vp);
|
1994-06-29 10:29:24 +04:00
|
|
|
return (error);
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Set ownership given a file descriptor.
|
|
|
|
*/
|
|
|
|
/* ARGSUSED */
|
1996-02-04 05:17:43 +03:00
|
|
|
int
|
2007-12-21 02:02:38 +03:00
|
|
|
sys_fchown(struct lwp *l, const struct sys_fchown_args *uap, register_t *retval)
|
1995-09-20 01:40:36 +04:00
|
|
|
{
|
2007-12-21 02:02:38 +03:00
|
|
|
/* {
|
1994-10-20 07:22:35 +03:00
|
|
|
syscallarg(int) fd;
|
1996-12-22 13:21:06 +03:00
|
|
|
syscallarg(uid_t) uid;
|
|
|
|
syscallarg(gid_t) gid;
|
2007-12-21 02:02:38 +03:00
|
|
|
} */
|
1994-06-29 10:29:24 +04:00
|
|
|
int error;
|
2008-03-22 00:54:58 +03:00
|
|
|
file_t *fp;
|
1994-06-29 10:29:24 +04:00
|
|
|
|
2008-03-22 00:54:58 +03:00
|
|
|
/* fd_getvnode() will use the descriptor for us */
|
|
|
|
if ((error = fd_getvnode(SCARG(uap, fd), &fp)) != 0)
|
1994-06-29 10:29:24 +04:00
|
|
|
return (error);
|
2008-03-22 00:54:58 +03:00
|
|
|
error = change_owner(fp->f_data, SCARG(uap, uid), SCARG(uap, gid),
|
|
|
|
l, 0);
|
|
|
|
fd_putfile(SCARG(uap, fd));
|
1999-05-06 00:01:01 +04:00
|
|
|
return (error);
|
1998-02-14 22:49:43 +03:00
|
|
|
}
|
|
|
|
|
2011-08-08 16:08:52 +04:00
|
|
|
int
|
|
|
|
sys_fchownat(struct lwp *l, const struct sys_fchownat_args *uap,
|
|
|
|
register_t *retval)
|
|
|
|
{
|
|
|
|
/* {
|
|
|
|
syscallarg(int) fd;
|
|
|
|
syscallarg(const char *) path;
|
Add most system calls for POSIX extended API set, part 2, with test cases:
faccessat(2), fchmodat(2), fchownat(2), fstatat(2), mkdirat(2), mkfifoat(2),
mknodat(2), linkat(2), readlinkat(2), symlinkat(2), renameat(2), unlinkat(2),
utimensat(2), openat(2).
Also implement O_SEARCH for openat(2)
Still missing:
- some flags for openat(2)
- fexecve(2) implementation
2012-11-18 21:41:51 +04:00
|
|
|
syscallarg(uid_t) owner;
|
|
|
|
syscallarg(gid_t) group;
|
2011-08-08 16:08:52 +04:00
|
|
|
syscallarg(int) flag;
|
|
|
|
} */
|
|
|
|
|
Add most system calls for POSIX extended API set, part 2, with test cases:
faccessat(2), fchmodat(2), fchownat(2), fstatat(2), mkdirat(2), mkfifoat(2),
mknodat(2), linkat(2), readlinkat(2), symlinkat(2), renameat(2), unlinkat(2),
utimensat(2), openat(2).
Also implement O_SEARCH for openat(2)
Still missing:
- some flags for openat(2)
- fexecve(2) implementation
2012-11-18 21:41:51 +04:00
|
|
|
return do_sys_chownat(l, SCARG(uap, fd), SCARG(uap, path),
|
|
|
|
SCARG(uap, owner), SCARG(uap, group),
|
|
|
|
SCARG(uap, flag));
|
2011-08-08 16:08:52 +04:00
|
|
|
}
|
|
|
|
|
1998-02-14 22:49:43 +03:00
|
|
|
/*
|
|
|
|
* Set ownership given a file descriptor, providing POSIX/XPG semantics.
|
|
|
|
*/
|
|
|
|
/* ARGSUSED */
|
|
|
|
int
|
2007-12-21 02:02:38 +03:00
|
|
|
sys___posix_fchown(struct lwp *l, const struct sys___posix_fchown_args *uap, register_t *retval)
|
1998-02-14 22:49:43 +03:00
|
|
|
{
|
2007-12-21 02:02:38 +03:00
|
|
|
/* {
|
1998-02-14 22:49:43 +03:00
|
|
|
syscallarg(int) fd;
|
|
|
|
syscallarg(uid_t) uid;
|
|
|
|
syscallarg(gid_t) gid;
|
2007-12-21 02:02:38 +03:00
|
|
|
} */
|
1998-02-14 22:49:43 +03:00
|
|
|
int error;
|
2008-03-22 00:54:58 +03:00
|
|
|
file_t *fp;
|
1998-02-14 22:49:43 +03:00
|
|
|
|
2008-03-22 00:54:58 +03:00
|
|
|
/* fd_getvnode() will use the descriptor for us */
|
|
|
|
if ((error = fd_getvnode(SCARG(uap, fd), &fp)) != 0)
|
1998-02-14 22:49:43 +03:00
|
|
|
return (error);
|
2008-03-22 00:54:58 +03:00
|
|
|
error = change_owner(fp->f_data, SCARG(uap, uid), SCARG(uap, gid),
|
|
|
|
l, 1);
|
|
|
|
fd_putfile(SCARG(uap, fd));
|
1999-05-06 00:01:01 +04:00
|
|
|
return (error);
|
1997-04-30 23:29:43 +04:00
|
|
|
}
|
|
|
|
|
1997-10-03 18:44:26 +04:00
|
|
|
/*
|
|
|
|
* Set ownership given a path name; this version does not follow links.
|
|
|
|
*/
|
|
|
|
/* ARGSUSED */
|
|
|
|
int
|
2007-12-21 02:02:38 +03:00
|
|
|
sys_lchown(struct lwp *l, const struct sys_lchown_args *uap, register_t *retval)
|
1997-10-03 18:44:26 +04:00
|
|
|
{
|
2007-12-21 02:02:38 +03:00
|
|
|
/* {
|
1997-10-03 18:44:26 +04:00
|
|
|
syscallarg(const char *) path;
|
|
|
|
syscallarg(uid_t) uid;
|
|
|
|
syscallarg(gid_t) gid;
|
2007-12-21 02:02:38 +03:00
|
|
|
} */
|
1997-10-03 18:44:26 +04:00
|
|
|
int error;
|
Convert 67 namei call sites to use namei_simple, in these functions:
check_console, veriexecclose, veriexec_delete, veriexec_file_add,
emul_find_root, coff_load_shlib (sh3 version), coff_load_shlib,
compat_20_sys_statfs, compat_20_netbsd32_statfs,
ELFNAME2(netbsd32,probe_noteless), darwin_sys_statfs,
ibcs2_sys_statfs, ibcs2_sys_statvfs, linux_sys_uselib,
osf1_sys_statfs, sunos_sys_statfs, sunos32_sys_statfs,
ultrix_sys_statfs, do_sys_mount, fss_create_files (3 of 4),
adosfs_mount, cd9660_mount, coda_ioctl, coda_mount, ext2fs_mount,
ffs_mount, filecore_mount, hfs_mount, lfs_mount, msdosfs_mount,
ntfs_mount, sysvbfs_mount, udf_mount, union_mount, sys_chflags,
sys_lchflags, sys_chmod, sys_lchmod, sys_chown, sys_lchown,
sys___posix_chown, sys___posix_lchown, sys_link, do_sys_pstatvfs,
sys_quotactl, sys_revoke, sys_truncate, do_sys_utimes, sys_extattrctl,
sys_extattr_set_file, sys_extattr_set_link, sys_extattr_get_file,
sys_extattr_get_link, sys_extattr_delete_file,
sys_extattr_delete_link, sys_extattr_list_file, sys_extattr_list_link,
sys_setxattr, sys_lsetxattr, sys_getxattr, sys_lgetxattr,
sys_listxattr, sys_llistxattr, sys_removexattr, sys_lremovexattr
All have been scrutinized (several times, in fact) and compile-tested,
but not all have been explicitly tested in action.
XXX: While I haven't (intentionally) changed the use or nonuse of
XXX: TRYEMULROOT in any of these places, I'm not convinced all the
XXX: uses are correct; an audit might be desirable.
2009-06-29 09:08:15 +04:00
|
|
|
struct vnode *vp;
|
1997-10-03 18:44:26 +04:00
|
|
|
|
Convert 67 namei call sites to use namei_simple, in these functions:
check_console, veriexecclose, veriexec_delete, veriexec_file_add,
emul_find_root, coff_load_shlib (sh3 version), coff_load_shlib,
compat_20_sys_statfs, compat_20_netbsd32_statfs,
ELFNAME2(netbsd32,probe_noteless), darwin_sys_statfs,
ibcs2_sys_statfs, ibcs2_sys_statvfs, linux_sys_uselib,
osf1_sys_statfs, sunos_sys_statfs, sunos32_sys_statfs,
ultrix_sys_statfs, do_sys_mount, fss_create_files (3 of 4),
adosfs_mount, cd9660_mount, coda_ioctl, coda_mount, ext2fs_mount,
ffs_mount, filecore_mount, hfs_mount, lfs_mount, msdosfs_mount,
ntfs_mount, sysvbfs_mount, udf_mount, union_mount, sys_chflags,
sys_lchflags, sys_chmod, sys_lchmod, sys_chown, sys_lchown,
sys___posix_chown, sys___posix_lchown, sys_link, do_sys_pstatvfs,
sys_quotactl, sys_revoke, sys_truncate, do_sys_utimes, sys_extattrctl,
sys_extattr_set_file, sys_extattr_set_link, sys_extattr_get_file,
sys_extattr_get_link, sys_extattr_delete_file,
sys_extattr_delete_link, sys_extattr_list_file, sys_extattr_list_link,
sys_setxattr, sys_lsetxattr, sys_getxattr, sys_lgetxattr,
sys_listxattr, sys_llistxattr, sys_removexattr, sys_lremovexattr
All have been scrutinized (several times, in fact) and compile-tested,
but not all have been explicitly tested in action.
XXX: While I haven't (intentionally) changed the use or nonuse of
XXX: TRYEMULROOT in any of these places, I'm not convinced all the
XXX: uses are correct; an audit might be desirable.
2009-06-29 09:08:15 +04:00
|
|
|
error = namei_simple_user(SCARG(uap, path),
|
|
|
|
NSM_NOFOLLOW_TRYEMULROOT, &vp);
|
|
|
|
if (error != 0)
|
1997-10-03 18:44:26 +04:00
|
|
|
return (error);
|
|
|
|
|
Convert 67 namei call sites to use namei_simple, in these functions:
check_console, veriexecclose, veriexec_delete, veriexec_file_add,
emul_find_root, coff_load_shlib (sh3 version), coff_load_shlib,
compat_20_sys_statfs, compat_20_netbsd32_statfs,
ELFNAME2(netbsd32,probe_noteless), darwin_sys_statfs,
ibcs2_sys_statfs, ibcs2_sys_statvfs, linux_sys_uselib,
osf1_sys_statfs, sunos_sys_statfs, sunos32_sys_statfs,
ultrix_sys_statfs, do_sys_mount, fss_create_files (3 of 4),
adosfs_mount, cd9660_mount, coda_ioctl, coda_mount, ext2fs_mount,
ffs_mount, filecore_mount, hfs_mount, lfs_mount, msdosfs_mount,
ntfs_mount, sysvbfs_mount, udf_mount, union_mount, sys_chflags,
sys_lchflags, sys_chmod, sys_lchmod, sys_chown, sys_lchown,
sys___posix_chown, sys___posix_lchown, sys_link, do_sys_pstatvfs,
sys_quotactl, sys_revoke, sys_truncate, do_sys_utimes, sys_extattrctl,
sys_extattr_set_file, sys_extattr_set_link, sys_extattr_get_file,
sys_extattr_get_link, sys_extattr_delete_file,
sys_extattr_delete_link, sys_extattr_list_file, sys_extattr_list_link,
sys_setxattr, sys_lsetxattr, sys_getxattr, sys_lgetxattr,
sys_listxattr, sys_llistxattr, sys_removexattr, sys_lremovexattr
All have been scrutinized (several times, in fact) and compile-tested,
but not all have been explicitly tested in action.
XXX: While I haven't (intentionally) changed the use or nonuse of
XXX: TRYEMULROOT in any of these places, I'm not convinced all the
XXX: uses are correct; an audit might be desirable.
2009-06-29 09:08:15 +04:00
|
|
|
error = change_owner(vp, SCARG(uap, uid), SCARG(uap, gid), l, 0);
|
1997-10-03 18:44:26 +04:00
|
|
|
|
Convert 67 namei call sites to use namei_simple, in these functions:
check_console, veriexecclose, veriexec_delete, veriexec_file_add,
emul_find_root, coff_load_shlib (sh3 version), coff_load_shlib,
compat_20_sys_statfs, compat_20_netbsd32_statfs,
ELFNAME2(netbsd32,probe_noteless), darwin_sys_statfs,
ibcs2_sys_statfs, ibcs2_sys_statvfs, linux_sys_uselib,
osf1_sys_statfs, sunos_sys_statfs, sunos32_sys_statfs,
ultrix_sys_statfs, do_sys_mount, fss_create_files (3 of 4),
adosfs_mount, cd9660_mount, coda_ioctl, coda_mount, ext2fs_mount,
ffs_mount, filecore_mount, hfs_mount, lfs_mount, msdosfs_mount,
ntfs_mount, sysvbfs_mount, udf_mount, union_mount, sys_chflags,
sys_lchflags, sys_chmod, sys_lchmod, sys_chown, sys_lchown,
sys___posix_chown, sys___posix_lchown, sys_link, do_sys_pstatvfs,
sys_quotactl, sys_revoke, sys_truncate, do_sys_utimes, sys_extattrctl,
sys_extattr_set_file, sys_extattr_set_link, sys_extattr_get_file,
sys_extattr_get_link, sys_extattr_delete_file,
sys_extattr_delete_link, sys_extattr_list_file, sys_extattr_list_link,
sys_setxattr, sys_lsetxattr, sys_getxattr, sys_lgetxattr,
sys_listxattr, sys_llistxattr, sys_removexattr, sys_lremovexattr
All have been scrutinized (several times, in fact) and compile-tested,
but not all have been explicitly tested in action.
XXX: While I haven't (intentionally) changed the use or nonuse of
XXX: TRYEMULROOT in any of these places, I'm not convinced all the
XXX: uses are correct; an audit might be desirable.
2009-06-29 09:08:15 +04:00
|
|
|
vrele(vp);
|
1997-10-03 18:44:26 +04:00
|
|
|
return (error);
|
|
|
|
}
|
|
|
|
|
1997-04-30 23:29:43 +04:00
|
|
|
/*
|
1998-02-14 22:49:43 +03:00
|
|
|
* Set ownership given a path name; this version does not follow links.
|
|
|
|
* Provides POSIX/XPG semantics.
|
|
|
|
*/
|
|
|
|
/* ARGSUSED */
|
|
|
|
int
|
2007-12-21 02:02:38 +03:00
|
|
|
sys___posix_lchown(struct lwp *l, const struct sys___posix_lchown_args *uap, register_t *retval)
|
1998-02-14 22:49:43 +03:00
|
|
|
{
|
2007-12-21 02:02:38 +03:00
|
|
|
/* {
|
1998-02-14 22:49:43 +03:00
|
|
|
syscallarg(const char *) path;
|
|
|
|
syscallarg(uid_t) uid;
|
|
|
|
syscallarg(gid_t) gid;
|
2007-12-21 02:02:38 +03:00
|
|
|
} */
|
1998-02-14 22:49:43 +03:00
|
|
|
int error;
|
Convert 67 namei call sites to use namei_simple, in these functions:
check_console, veriexecclose, veriexec_delete, veriexec_file_add,
emul_find_root, coff_load_shlib (sh3 version), coff_load_shlib,
compat_20_sys_statfs, compat_20_netbsd32_statfs,
ELFNAME2(netbsd32,probe_noteless), darwin_sys_statfs,
ibcs2_sys_statfs, ibcs2_sys_statvfs, linux_sys_uselib,
osf1_sys_statfs, sunos_sys_statfs, sunos32_sys_statfs,
ultrix_sys_statfs, do_sys_mount, fss_create_files (3 of 4),
adosfs_mount, cd9660_mount, coda_ioctl, coda_mount, ext2fs_mount,
ffs_mount, filecore_mount, hfs_mount, lfs_mount, msdosfs_mount,
ntfs_mount, sysvbfs_mount, udf_mount, union_mount, sys_chflags,
sys_lchflags, sys_chmod, sys_lchmod, sys_chown, sys_lchown,
sys___posix_chown, sys___posix_lchown, sys_link, do_sys_pstatvfs,
sys_quotactl, sys_revoke, sys_truncate, do_sys_utimes, sys_extattrctl,
sys_extattr_set_file, sys_extattr_set_link, sys_extattr_get_file,
sys_extattr_get_link, sys_extattr_delete_file,
sys_extattr_delete_link, sys_extattr_list_file, sys_extattr_list_link,
sys_setxattr, sys_lsetxattr, sys_getxattr, sys_lgetxattr,
sys_listxattr, sys_llistxattr, sys_removexattr, sys_lremovexattr
All have been scrutinized (several times, in fact) and compile-tested,
but not all have been explicitly tested in action.
XXX: While I haven't (intentionally) changed the use or nonuse of
XXX: TRYEMULROOT in any of these places, I'm not convinced all the
XXX: uses are correct; an audit might be desirable.
2009-06-29 09:08:15 +04:00
|
|
|
struct vnode *vp;
|
1998-02-14 22:49:43 +03:00
|
|
|
|
Convert 67 namei call sites to use namei_simple, in these functions:
check_console, veriexecclose, veriexec_delete, veriexec_file_add,
emul_find_root, coff_load_shlib (sh3 version), coff_load_shlib,
compat_20_sys_statfs, compat_20_netbsd32_statfs,
ELFNAME2(netbsd32,probe_noteless), darwin_sys_statfs,
ibcs2_sys_statfs, ibcs2_sys_statvfs, linux_sys_uselib,
osf1_sys_statfs, sunos_sys_statfs, sunos32_sys_statfs,
ultrix_sys_statfs, do_sys_mount, fss_create_files (3 of 4),
adosfs_mount, cd9660_mount, coda_ioctl, coda_mount, ext2fs_mount,
ffs_mount, filecore_mount, hfs_mount, lfs_mount, msdosfs_mount,
ntfs_mount, sysvbfs_mount, udf_mount, union_mount, sys_chflags,
sys_lchflags, sys_chmod, sys_lchmod, sys_chown, sys_lchown,
sys___posix_chown, sys___posix_lchown, sys_link, do_sys_pstatvfs,
sys_quotactl, sys_revoke, sys_truncate, do_sys_utimes, sys_extattrctl,
sys_extattr_set_file, sys_extattr_set_link, sys_extattr_get_file,
sys_extattr_get_link, sys_extattr_delete_file,
sys_extattr_delete_link, sys_extattr_list_file, sys_extattr_list_link,
sys_setxattr, sys_lsetxattr, sys_getxattr, sys_lgetxattr,
sys_listxattr, sys_llistxattr, sys_removexattr, sys_lremovexattr
All have been scrutinized (several times, in fact) and compile-tested,
but not all have been explicitly tested in action.
XXX: While I haven't (intentionally) changed the use or nonuse of
XXX: TRYEMULROOT in any of these places, I'm not convinced all the
XXX: uses are correct; an audit might be desirable.
2009-06-29 09:08:15 +04:00
|
|
|
error = namei_simple_user(SCARG(uap, path),
|
|
|
|
NSM_NOFOLLOW_TRYEMULROOT, &vp);
|
|
|
|
if (error != 0)
|
1998-02-14 22:49:43 +03:00
|
|
|
return (error);
|
|
|
|
|
Convert 67 namei call sites to use namei_simple, in these functions:
check_console, veriexecclose, veriexec_delete, veriexec_file_add,
emul_find_root, coff_load_shlib (sh3 version), coff_load_shlib,
compat_20_sys_statfs, compat_20_netbsd32_statfs,
ELFNAME2(netbsd32,probe_noteless), darwin_sys_statfs,
ibcs2_sys_statfs, ibcs2_sys_statvfs, linux_sys_uselib,
osf1_sys_statfs, sunos_sys_statfs, sunos32_sys_statfs,
ultrix_sys_statfs, do_sys_mount, fss_create_files (3 of 4),
adosfs_mount, cd9660_mount, coda_ioctl, coda_mount, ext2fs_mount,
ffs_mount, filecore_mount, hfs_mount, lfs_mount, msdosfs_mount,
ntfs_mount, sysvbfs_mount, udf_mount, union_mount, sys_chflags,
sys_lchflags, sys_chmod, sys_lchmod, sys_chown, sys_lchown,
sys___posix_chown, sys___posix_lchown, sys_link, do_sys_pstatvfs,
sys_quotactl, sys_revoke, sys_truncate, do_sys_utimes, sys_extattrctl,
sys_extattr_set_file, sys_extattr_set_link, sys_extattr_get_file,
sys_extattr_get_link, sys_extattr_delete_file,
sys_extattr_delete_link, sys_extattr_list_file, sys_extattr_list_link,
sys_setxattr, sys_lsetxattr, sys_getxattr, sys_lgetxattr,
sys_listxattr, sys_llistxattr, sys_removexattr, sys_lremovexattr
All have been scrutinized (several times, in fact) and compile-tested,
but not all have been explicitly tested in action.
XXX: While I haven't (intentionally) changed the use or nonuse of
XXX: TRYEMULROOT in any of these places, I'm not convinced all the
XXX: uses are correct; an audit might be desirable.
2009-06-29 09:08:15 +04:00
|
|
|
error = change_owner(vp, SCARG(uap, uid), SCARG(uap, gid), l, 1);
|
1998-02-14 22:49:43 +03:00
|
|
|
|
Convert 67 namei call sites to use namei_simple, in these functions:
check_console, veriexecclose, veriexec_delete, veriexec_file_add,
emul_find_root, coff_load_shlib (sh3 version), coff_load_shlib,
compat_20_sys_statfs, compat_20_netbsd32_statfs,
ELFNAME2(netbsd32,probe_noteless), darwin_sys_statfs,
ibcs2_sys_statfs, ibcs2_sys_statvfs, linux_sys_uselib,
osf1_sys_statfs, sunos_sys_statfs, sunos32_sys_statfs,
ultrix_sys_statfs, do_sys_mount, fss_create_files (3 of 4),
adosfs_mount, cd9660_mount, coda_ioctl, coda_mount, ext2fs_mount,
ffs_mount, filecore_mount, hfs_mount, lfs_mount, msdosfs_mount,
ntfs_mount, sysvbfs_mount, udf_mount, union_mount, sys_chflags,
sys_lchflags, sys_chmod, sys_lchmod, sys_chown, sys_lchown,
sys___posix_chown, sys___posix_lchown, sys_link, do_sys_pstatvfs,
sys_quotactl, sys_revoke, sys_truncate, do_sys_utimes, sys_extattrctl,
sys_extattr_set_file, sys_extattr_set_link, sys_extattr_get_file,
sys_extattr_get_link, sys_extattr_delete_file,
sys_extattr_delete_link, sys_extattr_list_file, sys_extattr_list_link,
sys_setxattr, sys_lsetxattr, sys_getxattr, sys_lgetxattr,
sys_listxattr, sys_llistxattr, sys_removexattr, sys_lremovexattr
All have been scrutinized (several times, in fact) and compile-tested,
but not all have been explicitly tested in action.
XXX: While I haven't (intentionally) changed the use or nonuse of
XXX: TRYEMULROOT in any of these places, I'm not convinced all the
XXX: uses are correct; an audit might be desirable.
2009-06-29 09:08:15 +04:00
|
|
|
vrele(vp);
|
1998-02-14 22:49:43 +03:00
|
|
|
return (error);
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
2004-03-23 16:22:32 +03:00
|
|
|
* Common routine to set ownership given a vnode.
|
1997-04-30 23:29:43 +04:00
|
|
|
*/
|
|
|
|
static int
|
2005-12-11 15:16:03 +03:00
|
|
|
change_owner(struct vnode *vp, uid_t uid, gid_t gid, struct lwp *l,
|
2005-06-06 03:47:48 +04:00
|
|
|
int posix_semantics)
|
1997-04-30 23:29:43 +04:00
|
|
|
{
|
|
|
|
struct vattr vattr;
|
1998-02-14 22:49:43 +03:00
|
|
|
mode_t newmode;
|
1997-04-30 23:29:43 +04:00
|
|
|
int error;
|
|
|
|
|
1998-03-01 05:20:01 +03:00
|
|
|
vn_lock(vp, LK_EXCLUSIVE | LK_RETRY);
|
2007-11-26 22:01:26 +03:00
|
|
|
if ((error = VOP_GETATTR(vp, &vattr, l->l_cred)) != 0)
|
1997-04-30 23:29:43 +04:00
|
|
|
goto out;
|
|
|
|
|
2002-08-26 05:26:29 +04:00
|
|
|
#define CHANGED(x) ((int)(x) != -1)
|
1998-02-14 22:49:43 +03:00
|
|
|
newmode = vattr.va_mode;
|
|
|
|
if (posix_semantics) {
|
|
|
|
/*
|
1998-03-10 14:49:33 +03:00
|
|
|
* POSIX/XPG semantics: if the caller is not the super-user,
|
|
|
|
* clear set-user-id and set-group-id bits. Both POSIX and
|
|
|
|
* the XPG consider the behaviour for calls by the super-user
|
|
|
|
* implementation-defined; we leave the set-user-id and set-
|
|
|
|
* group-id settings intact in that case.
|
1998-02-14 22:49:43 +03:00
|
|
|
*/
|
2012-03-13 22:40:26 +04:00
|
|
|
if (vattr.va_mode & S_ISUID) {
|
2012-04-17 23:15:15 +04:00
|
|
|
if (kauth_authorize_vnode(l->l_cred,
|
|
|
|
KAUTH_VNODE_RETAIN_SUID, vp, NULL, EPERM) != 0)
|
2012-03-13 22:40:26 +04:00
|
|
|
newmode &= ~S_ISUID;
|
|
|
|
}
|
|
|
|
if (vattr.va_mode & S_ISGID) {
|
2012-04-17 23:15:15 +04:00
|
|
|
if (kauth_authorize_vnode(l->l_cred,
|
|
|
|
KAUTH_VNODE_RETAIN_SGID, vp, NULL, EPERM) != 0)
|
2012-03-13 22:40:26 +04:00
|
|
|
newmode &= ~S_ISGID;
|
|
|
|
}
|
1998-02-14 22:49:43 +03:00
|
|
|
} else {
|
|
|
|
/*
|
|
|
|
* NetBSD semantics: when changing owner and/or group,
|
|
|
|
* clear the respective bit(s).
|
|
|
|
*/
|
|
|
|
if (CHANGED(uid))
|
|
|
|
newmode &= ~S_ISUID;
|
|
|
|
if (CHANGED(gid))
|
|
|
|
newmode &= ~S_ISGID;
|
|
|
|
}
|
|
|
|
/* Update va_mode iff altered. */
|
|
|
|
if (vattr.va_mode == newmode)
|
|
|
|
newmode = VNOVAL;
|
2004-03-23 16:22:32 +03:00
|
|
|
|
2010-01-08 14:35:07 +03:00
|
|
|
vattr_null(&vattr);
|
2002-08-26 05:26:29 +04:00
|
|
|
vattr.va_uid = CHANGED(uid) ? uid : (uid_t)VNOVAL;
|
|
|
|
vattr.va_gid = CHANGED(gid) ? gid : (gid_t)VNOVAL;
|
1997-04-30 23:29:43 +04:00
|
|
|
vattr.va_mode = newmode;
|
2007-11-26 22:01:26 +03:00
|
|
|
error = VOP_SETATTR(vp, &vattr, l->l_cred);
|
1998-02-14 22:49:43 +03:00
|
|
|
#undef CHANGED
|
2004-03-23 16:22:32 +03:00
|
|
|
|
1997-04-30 23:29:43 +04:00
|
|
|
out:
|
2010-06-24 16:58:48 +04:00
|
|
|
VOP_UNLOCK(vp);
|
1994-06-29 10:29:24 +04:00
|
|
|
return (error);
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
1997-10-03 18:44:26 +04:00
|
|
|
* Set the access and modification times given a path name; this
|
|
|
|
* version follows links.
|
1994-06-29 10:29:24 +04:00
|
|
|
*/
|
|
|
|
/* ARGSUSED */
|
1996-02-04 05:17:43 +03:00
|
|
|
int
|
2009-01-11 05:45:45 +03:00
|
|
|
sys___utimes50(struct lwp *l, const struct sys___utimes50_args *uap,
|
|
|
|
register_t *retval)
|
1995-09-20 01:40:36 +04:00
|
|
|
{
|
2007-12-21 02:02:38 +03:00
|
|
|
/* {
|
1996-12-22 13:21:06 +03:00
|
|
|
syscallarg(const char *) path;
|
|
|
|
syscallarg(const struct timeval *) tptr;
|
2007-12-21 02:02:38 +03:00
|
|
|
} */
|
1994-06-29 10:29:24 +04:00
|
|
|
|
2007-05-12 21:28:19 +04:00
|
|
|
return do_sys_utimes(l, NULL, SCARG(uap, path), FOLLOW,
|
2008-03-22 00:54:58 +03:00
|
|
|
SCARG(uap, tptr), UIO_USERSPACE);
|
1994-06-29 10:29:24 +04:00
|
|
|
}
|
|
|
|
|
1996-04-23 14:29:02 +04:00
|
|
|
/*
|
|
|
|
* Set the access and modification times given a file descriptor.
|
|
|
|
*/
|
|
|
|
/* ARGSUSED */
|
|
|
|
int
|
2009-01-11 05:45:45 +03:00
|
|
|
sys___futimes50(struct lwp *l, const struct sys___futimes50_args *uap,
|
|
|
|
register_t *retval)
|
1996-04-23 14:29:02 +04:00
|
|
|
{
|
2007-12-21 02:02:38 +03:00
|
|
|
/* {
|
1996-04-23 14:29:02 +04:00
|
|
|
syscallarg(int) fd;
|
1996-12-22 13:21:06 +03:00
|
|
|
syscallarg(const struct timeval *) tptr;
|
2007-12-21 02:02:38 +03:00
|
|
|
} */
|
1996-04-23 14:29:02 +04:00
|
|
|
int error;
|
2008-03-22 00:54:58 +03:00
|
|
|
file_t *fp;
|
1996-04-23 14:29:02 +04:00
|
|
|
|
2008-03-22 00:54:58 +03:00
|
|
|
/* fd_getvnode() will use the descriptor for us */
|
|
|
|
if ((error = fd_getvnode(SCARG(uap, fd), &fp)) != 0)
|
1997-10-03 17:46:02 +04:00
|
|
|
return (error);
|
2008-03-22 00:54:58 +03:00
|
|
|
error = do_sys_utimes(l, fp->f_data, NULL, 0, SCARG(uap, tptr),
|
|
|
|
UIO_USERSPACE);
|
|
|
|
fd_putfile(SCARG(uap, fd));
|
1999-05-06 00:01:01 +04:00
|
|
|
return (error);
|
1997-10-03 18:14:36 +04:00
|
|
|
}
|
|
|
|
|
2011-08-17 11:22:33 +04:00
|
|
|
int
|
|
|
|
sys_futimens(struct lwp *l, const struct sys_futimens_args *uap,
|
|
|
|
register_t *retval)
|
|
|
|
{
|
|
|
|
/* {
|
|
|
|
syscallarg(int) fd;
|
|
|
|
syscallarg(const struct timespec *) tptr;
|
|
|
|
} */
|
|
|
|
int error;
|
|
|
|
file_t *fp;
|
|
|
|
|
|
|
|
/* fd_getvnode() will use the descriptor for us */
|
|
|
|
if ((error = fd_getvnode(SCARG(uap, fd), &fp)) != 0)
|
|
|
|
return (error);
|
Add most system calls for POSIX extended API set, part 2, with test cases:
faccessat(2), fchmodat(2), fchownat(2), fstatat(2), mkdirat(2), mkfifoat(2),
mknodat(2), linkat(2), readlinkat(2), symlinkat(2), renameat(2), unlinkat(2),
utimensat(2), openat(2).
Also implement O_SEARCH for openat(2)
Still missing:
- some flags for openat(2)
- fexecve(2) implementation
2012-11-18 21:41:51 +04:00
|
|
|
error = do_sys_utimensat(l, AT_FDCWD, fp->f_data, NULL, 0,
|
|
|
|
SCARG(uap, tptr), UIO_USERSPACE);
|
2011-08-17 11:22:33 +04:00
|
|
|
fd_putfile(SCARG(uap, fd));
|
|
|
|
return (error);
|
|
|
|
}
|
|
|
|
|
1997-10-03 18:44:26 +04:00
|
|
|
/*
|
|
|
|
* Set the access and modification times given a path name; this
|
|
|
|
* version does not follow links.
|
|
|
|
*/
|
|
|
|
int
|
2009-01-11 05:45:45 +03:00
|
|
|
sys___lutimes50(struct lwp *l, const struct sys___lutimes50_args *uap,
|
|
|
|
register_t *retval)
|
1997-10-03 18:44:26 +04:00
|
|
|
{
|
2007-12-21 02:02:38 +03:00
|
|
|
/* {
|
1997-10-03 18:44:26 +04:00
|
|
|
syscallarg(const char *) path;
|
|
|
|
syscallarg(const struct timeval *) tptr;
|
2007-12-21 02:02:38 +03:00
|
|
|
} */
|
1997-10-03 18:44:26 +04:00
|
|
|
|
2007-05-12 21:28:19 +04:00
|
|
|
return do_sys_utimes(l, NULL, SCARG(uap, path), NOFOLLOW,
|
2008-03-22 00:54:58 +03:00
|
|
|
SCARG(uap, tptr), UIO_USERSPACE);
|
1997-10-03 18:44:26 +04:00
|
|
|
}
|
|
|
|
|
2011-08-08 16:08:52 +04:00
|
|
|
int
|
|
|
|
sys_utimensat(struct lwp *l, const struct sys_utimensat_args *uap,
|
|
|
|
register_t *retval)
|
|
|
|
{
|
|
|
|
/* {
|
|
|
|
syscallarg(int) fd;
|
|
|
|
syscallarg(const char *) path;
|
|
|
|
syscallarg(const struct timespec *) tptr;
|
|
|
|
syscallarg(int) flag;
|
|
|
|
} */
|
2011-08-17 11:22:33 +04:00
|
|
|
int follow;
|
|
|
|
const struct timespec *tptr;
|
Add most system calls for POSIX extended API set, part 2, with test cases:
faccessat(2), fchmodat(2), fchownat(2), fstatat(2), mkdirat(2), mkfifoat(2),
mknodat(2), linkat(2), readlinkat(2), symlinkat(2), renameat(2), unlinkat(2),
utimensat(2), openat(2).
Also implement O_SEARCH for openat(2)
Still missing:
- some flags for openat(2)
- fexecve(2) implementation
2012-11-18 21:41:51 +04:00
|
|
|
int error;
|
2011-08-17 11:22:33 +04:00
|
|
|
|
|
|
|
tptr = SCARG(uap, tptr);
|
|
|
|
follow = (SCARG(uap, flag) & AT_SYMLINK_NOFOLLOW) ? NOFOLLOW : FOLLOW;
|
|
|
|
|
Add most system calls for POSIX extended API set, part 2, with test cases:
faccessat(2), fchmodat(2), fchownat(2), fstatat(2), mkdirat(2), mkfifoat(2),
mknodat(2), linkat(2), readlinkat(2), symlinkat(2), renameat(2), unlinkat(2),
utimensat(2), openat(2).
Also implement O_SEARCH for openat(2)
Still missing:
- some flags for openat(2)
- fexecve(2) implementation
2012-11-18 21:41:51 +04:00
|
|
|
error = do_sys_utimensat(l, SCARG(uap, fd), NULL,
|
|
|
|
SCARG(uap, path), follow, tptr, UIO_USERSPACE);
|
|
|
|
|
|
|
|
return error;
|
2011-08-08 16:08:52 +04:00
|
|
|
}
|
|
|
|
|
1997-10-03 18:14:36 +04:00
|
|
|
/*
|
|
|
|
* Common routine to set access and modification times given a vnode.
|
|
|
|
*/
|
2007-05-12 21:28:19 +04:00
|
|
|
int
|
2011-08-17 11:22:33 +04:00
|
|
|
do_sys_utimens(struct lwp *l, struct vnode *vp, const char *path, int flag,
|
|
|
|
const struct timespec *tptr, enum uio_seg seg)
|
Add most system calls for POSIX extended API set, part 2, with test cases:
faccessat(2), fchmodat(2), fchownat(2), fstatat(2), mkdirat(2), mkfifoat(2),
mknodat(2), linkat(2), readlinkat(2), symlinkat(2), renameat(2), unlinkat(2),
utimensat(2), openat(2).
Also implement O_SEARCH for openat(2)
Still missing:
- some flags for openat(2)
- fexecve(2) implementation
2012-11-18 21:41:51 +04:00
|
|
|
{
|
|
|
|
return do_sys_utimensat(l, AT_FDCWD, vp, path, flag, tptr, seg);
|
|
|
|
}
|
|
|
|
|
|
|
|
static int
|
|
|
|
do_sys_utimensat(struct lwp *l, int fdat, struct vnode *vp,
|
|
|
|
const char *path, int flag, const struct timespec *tptr, enum uio_seg seg)
|
1997-10-03 18:14:36 +04:00
|
|
|
{
|
|
|
|
struct vattr vattr;
|
Convert 67 namei call sites to use namei_simple, in these functions:
check_console, veriexecclose, veriexec_delete, veriexec_file_add,
emul_find_root, coff_load_shlib (sh3 version), coff_load_shlib,
compat_20_sys_statfs, compat_20_netbsd32_statfs,
ELFNAME2(netbsd32,probe_noteless), darwin_sys_statfs,
ibcs2_sys_statfs, ibcs2_sys_statvfs, linux_sys_uselib,
osf1_sys_statfs, sunos_sys_statfs, sunos32_sys_statfs,
ultrix_sys_statfs, do_sys_mount, fss_create_files (3 of 4),
adosfs_mount, cd9660_mount, coda_ioctl, coda_mount, ext2fs_mount,
ffs_mount, filecore_mount, hfs_mount, lfs_mount, msdosfs_mount,
ntfs_mount, sysvbfs_mount, udf_mount, union_mount, sys_chflags,
sys_lchflags, sys_chmod, sys_lchmod, sys_chown, sys_lchown,
sys___posix_chown, sys___posix_lchown, sys_link, do_sys_pstatvfs,
sys_quotactl, sys_revoke, sys_truncate, do_sys_utimes, sys_extattrctl,
sys_extattr_set_file, sys_extattr_set_link, sys_extattr_get_file,
sys_extattr_get_link, sys_extattr_delete_file,
sys_extattr_delete_link, sys_extattr_list_file, sys_extattr_list_link,
sys_setxattr, sys_lsetxattr, sys_getxattr, sys_lgetxattr,
sys_listxattr, sys_llistxattr, sys_removexattr, sys_lremovexattr
All have been scrutinized (several times, in fact) and compile-tested,
but not all have been explicitly tested in action.
XXX: While I haven't (intentionally) changed the use or nonuse of
XXX: TRYEMULROOT in any of these places, I'm not convinced all the
XXX: uses are correct; an audit might be desirable.
2009-06-29 09:08:15 +04:00
|
|
|
int error, dorele = 0;
|
|
|
|
namei_simple_flags_t sflags;
|
2008-06-17 20:18:01 +04:00
|
|
|
bool vanull, setbirthtime;
|
|
|
|
struct timespec ts[2];
|
1997-10-03 18:14:36 +04:00
|
|
|
|
Add most system calls for POSIX extended API set, part 2, with test cases:
faccessat(2), fchmodat(2), fchownat(2), fstatat(2), mkdirat(2), mkfifoat(2),
mknodat(2), linkat(2), readlinkat(2), symlinkat(2), renameat(2), unlinkat(2),
utimensat(2), openat(2).
Also implement O_SEARCH for openat(2)
Still missing:
- some flags for openat(2)
- fexecve(2) implementation
2012-11-18 21:41:51 +04:00
|
|
|
KASSERT(l != NULL || fdat == AT_FDCWD);
|
|
|
|
|
Convert 67 namei call sites to use namei_simple, in these functions:
check_console, veriexecclose, veriexec_delete, veriexec_file_add,
emul_find_root, coff_load_shlib (sh3 version), coff_load_shlib,
compat_20_sys_statfs, compat_20_netbsd32_statfs,
ELFNAME2(netbsd32,probe_noteless), darwin_sys_statfs,
ibcs2_sys_statfs, ibcs2_sys_statvfs, linux_sys_uselib,
osf1_sys_statfs, sunos_sys_statfs, sunos32_sys_statfs,
ultrix_sys_statfs, do_sys_mount, fss_create_files (3 of 4),
adosfs_mount, cd9660_mount, coda_ioctl, coda_mount, ext2fs_mount,
ffs_mount, filecore_mount, hfs_mount, lfs_mount, msdosfs_mount,
ntfs_mount, sysvbfs_mount, udf_mount, union_mount, sys_chflags,
sys_lchflags, sys_chmod, sys_lchmod, sys_chown, sys_lchown,
sys___posix_chown, sys___posix_lchown, sys_link, do_sys_pstatvfs,
sys_quotactl, sys_revoke, sys_truncate, do_sys_utimes, sys_extattrctl,
sys_extattr_set_file, sys_extattr_set_link, sys_extattr_get_file,
sys_extattr_get_link, sys_extattr_delete_file,
sys_extattr_delete_link, sys_extattr_list_file, sys_extattr_list_link,
sys_setxattr, sys_lsetxattr, sys_getxattr, sys_lgetxattr,
sys_listxattr, sys_llistxattr, sys_removexattr, sys_lremovexattr
All have been scrutinized (several times, in fact) and compile-tested,
but not all have been explicitly tested in action.
XXX: While I haven't (intentionally) changed the use or nonuse of
XXX: TRYEMULROOT in any of these places, I'm not convinced all the
XXX: uses are correct; an audit might be desirable.
2009-06-29 09:08:15 +04:00
|
|
|
/*
|
|
|
|
* I have checked all callers and they pass either FOLLOW,
|
|
|
|
* NOFOLLOW, or 0 (when they don't pass a path), and NOFOLLOW
|
|
|
|
* is 0. More to the point, they don't pass anything else.
|
|
|
|
* Let's keep it that way at least until the namei interfaces
|
|
|
|
* are fully sanitized.
|
|
|
|
*/
|
|
|
|
KASSERT(flag == NOFOLLOW || flag == FOLLOW);
|
|
|
|
sflags = (flag == FOLLOW) ?
|
|
|
|
NSM_FOLLOW_TRYEMULROOT : NSM_NOFOLLOW_TRYEMULROOT;
|
|
|
|
|
1997-10-03 18:14:36 +04:00
|
|
|
if (tptr == NULL) {
|
2008-06-17 20:18:01 +04:00
|
|
|
vanull = true;
|
|
|
|
nanotime(&ts[0]);
|
|
|
|
ts[1] = ts[0];
|
1996-04-23 14:29:02 +04:00
|
|
|
} else {
|
2008-06-17 20:18:01 +04:00
|
|
|
vanull = false;
|
2007-05-12 21:28:19 +04:00
|
|
|
if (seg != UIO_SYSSPACE) {
|
2011-08-17 11:22:33 +04:00
|
|
|
error = copyin(tptr, ts, sizeof (ts));
|
2007-05-12 21:28:19 +04:00
|
|
|
if (error != 0)
|
|
|
|
return error;
|
2011-08-18 23:34:47 +04:00
|
|
|
} else {
|
|
|
|
ts[0] = tptr[0];
|
|
|
|
ts[1] = tptr[1];
|
2007-05-12 21:28:19 +04:00
|
|
|
}
|
1996-04-23 14:29:02 +04:00
|
|
|
}
|
2007-05-12 21:28:19 +04:00
|
|
|
|
2011-08-23 02:09:07 +04:00
|
|
|
if (ts[0].tv_nsec == UTIME_NOW) {
|
2011-08-17 11:22:33 +04:00
|
|
|
nanotime(&ts[0]);
|
2011-08-23 02:09:07 +04:00
|
|
|
if (ts[1].tv_nsec == UTIME_NOW) {
|
|
|
|
vanull = true;
|
|
|
|
ts[1] = ts[0];
|
|
|
|
}
|
|
|
|
} else if (ts[1].tv_nsec == UTIME_NOW)
|
2011-08-17 11:22:33 +04:00
|
|
|
nanotime(&ts[1]);
|
|
|
|
|
2007-05-12 21:28:19 +04:00
|
|
|
if (vp == NULL) {
|
Convert 67 namei call sites to use namei_simple, in these functions:
check_console, veriexecclose, veriexec_delete, veriexec_file_add,
emul_find_root, coff_load_shlib (sh3 version), coff_load_shlib,
compat_20_sys_statfs, compat_20_netbsd32_statfs,
ELFNAME2(netbsd32,probe_noteless), darwin_sys_statfs,
ibcs2_sys_statfs, ibcs2_sys_statvfs, linux_sys_uselib,
osf1_sys_statfs, sunos_sys_statfs, sunos32_sys_statfs,
ultrix_sys_statfs, do_sys_mount, fss_create_files (3 of 4),
adosfs_mount, cd9660_mount, coda_ioctl, coda_mount, ext2fs_mount,
ffs_mount, filecore_mount, hfs_mount, lfs_mount, msdosfs_mount,
ntfs_mount, sysvbfs_mount, udf_mount, union_mount, sys_chflags,
sys_lchflags, sys_chmod, sys_lchmod, sys_chown, sys_lchown,
sys___posix_chown, sys___posix_lchown, sys_link, do_sys_pstatvfs,
sys_quotactl, sys_revoke, sys_truncate, do_sys_utimes, sys_extattrctl,
sys_extattr_set_file, sys_extattr_set_link, sys_extattr_get_file,
sys_extattr_get_link, sys_extattr_delete_file,
sys_extattr_delete_link, sys_extattr_list_file, sys_extattr_list_link,
sys_setxattr, sys_lsetxattr, sys_getxattr, sys_lgetxattr,
sys_listxattr, sys_llistxattr, sys_removexattr, sys_lremovexattr
All have been scrutinized (several times, in fact) and compile-tested,
but not all have been explicitly tested in action.
XXX: While I haven't (intentionally) changed the use or nonuse of
XXX: TRYEMULROOT in any of these places, I'm not convinced all the
XXX: uses are correct; an audit might be desirable.
2009-06-29 09:08:15 +04:00
|
|
|
/* note: SEG describes TPTR, not PATH; PATH is always user */
|
Add most system calls for POSIX extended API set, part 2, with test cases:
faccessat(2), fchmodat(2), fchownat(2), fstatat(2), mkdirat(2), mkfifoat(2),
mknodat(2), linkat(2), readlinkat(2), symlinkat(2), renameat(2), unlinkat(2),
utimensat(2), openat(2).
Also implement O_SEARCH for openat(2)
Still missing:
- some flags for openat(2)
- fexecve(2) implementation
2012-11-18 21:41:51 +04:00
|
|
|
error = fd_nameiat_simple_user(l, fdat, path, sflags, &vp);
|
Convert 67 namei call sites to use namei_simple, in these functions:
check_console, veriexecclose, veriexec_delete, veriexec_file_add,
emul_find_root, coff_load_shlib (sh3 version), coff_load_shlib,
compat_20_sys_statfs, compat_20_netbsd32_statfs,
ELFNAME2(netbsd32,probe_noteless), darwin_sys_statfs,
ibcs2_sys_statfs, ibcs2_sys_statvfs, linux_sys_uselib,
osf1_sys_statfs, sunos_sys_statfs, sunos32_sys_statfs,
ultrix_sys_statfs, do_sys_mount, fss_create_files (3 of 4),
adosfs_mount, cd9660_mount, coda_ioctl, coda_mount, ext2fs_mount,
ffs_mount, filecore_mount, hfs_mount, lfs_mount, msdosfs_mount,
ntfs_mount, sysvbfs_mount, udf_mount, union_mount, sys_chflags,
sys_lchflags, sys_chmod, sys_lchmod, sys_chown, sys_lchown,
sys___posix_chown, sys___posix_lchown, sys_link, do_sys_pstatvfs,
sys_quotactl, sys_revoke, sys_truncate, do_sys_utimes, sys_extattrctl,
sys_extattr_set_file, sys_extattr_set_link, sys_extattr_get_file,
sys_extattr_get_link, sys_extattr_delete_file,
sys_extattr_delete_link, sys_extattr_list_file, sys_extattr_list_link,
sys_setxattr, sys_lsetxattr, sys_getxattr, sys_lgetxattr,
sys_listxattr, sys_llistxattr, sys_removexattr, sys_lremovexattr
All have been scrutinized (several times, in fact) and compile-tested,
but not all have been explicitly tested in action.
XXX: While I haven't (intentionally) changed the use or nonuse of
XXX: TRYEMULROOT in any of these places, I'm not convinced all the
XXX: uses are correct; an audit might be desirable.
2009-06-29 09:08:15 +04:00
|
|
|
if (error != 0)
|
2008-06-17 20:18:01 +04:00
|
|
|
return error;
|
Convert 67 namei call sites to use namei_simple, in these functions:
check_console, veriexecclose, veriexec_delete, veriexec_file_add,
emul_find_root, coff_load_shlib (sh3 version), coff_load_shlib,
compat_20_sys_statfs, compat_20_netbsd32_statfs,
ELFNAME2(netbsd32,probe_noteless), darwin_sys_statfs,
ibcs2_sys_statfs, ibcs2_sys_statvfs, linux_sys_uselib,
osf1_sys_statfs, sunos_sys_statfs, sunos32_sys_statfs,
ultrix_sys_statfs, do_sys_mount, fss_create_files (3 of 4),
adosfs_mount, cd9660_mount, coda_ioctl, coda_mount, ext2fs_mount,
ffs_mount, filecore_mount, hfs_mount, lfs_mount, msdosfs_mount,
ntfs_mount, sysvbfs_mount, udf_mount, union_mount, sys_chflags,
sys_lchflags, sys_chmod, sys_lchmod, sys_chown, sys_lchown,
sys___posix_chown, sys___posix_lchown, sys_link, do_sys_pstatvfs,
sys_quotactl, sys_revoke, sys_truncate, do_sys_utimes, sys_extattrctl,
sys_extattr_set_file, sys_extattr_set_link, sys_extattr_get_file,
sys_extattr_get_link, sys_extattr_delete_file,
sys_extattr_delete_link, sys_extattr_list_file, sys_extattr_list_link,
sys_setxattr, sys_lsetxattr, sys_getxattr, sys_lgetxattr,
sys_listxattr, sys_llistxattr, sys_removexattr, sys_lremovexattr
All have been scrutinized (several times, in fact) and compile-tested,
but not all have been explicitly tested in action.
XXX: While I haven't (intentionally) changed the use or nonuse of
XXX: TRYEMULROOT in any of these places, I'm not convinced all the
XXX: uses are correct; an audit might be desirable.
2009-06-29 09:08:15 +04:00
|
|
|
dorele = 1;
|
|
|
|
}
|
2007-05-12 21:28:19 +04:00
|
|
|
|
1998-03-01 05:20:01 +03:00
|
|
|
vn_lock(vp, LK_EXCLUSIVE | LK_RETRY);
|
2008-06-17 20:18:01 +04:00
|
|
|
setbirthtime = (VOP_GETATTR(vp, &vattr, l->l_cred) == 0 &&
|
|
|
|
timespeccmp(&ts[1], &vattr.va_birthtime, <));
|
2010-01-08 14:35:07 +03:00
|
|
|
vattr_null(&vattr);
|
2011-08-17 11:22:33 +04:00
|
|
|
|
|
|
|
if (ts[0].tv_nsec != UTIME_OMIT)
|
|
|
|
vattr.va_atime = ts[0];
|
|
|
|
|
|
|
|
if (ts[1].tv_nsec != UTIME_OMIT) {
|
|
|
|
vattr.va_mtime = ts[1];
|
|
|
|
if (setbirthtime)
|
|
|
|
vattr.va_birthtime = ts[1];
|
|
|
|
}
|
|
|
|
|
2008-06-17 20:18:01 +04:00
|
|
|
if (vanull)
|
2009-04-28 07:01:15 +04:00
|
|
|
vattr.va_vaflags |= VA_UTIMES_NULL;
|
2007-11-26 22:01:26 +03:00
|
|
|
error = VOP_SETATTR(vp, &vattr, l->l_cred);
|
2010-06-24 16:58:48 +04:00
|
|
|
VOP_UNLOCK(vp);
|
2007-05-12 21:28:19 +04:00
|
|
|
|
Convert 67 namei call sites to use namei_simple, in these functions:
check_console, veriexecclose, veriexec_delete, veriexec_file_add,
emul_find_root, coff_load_shlib (sh3 version), coff_load_shlib,
compat_20_sys_statfs, compat_20_netbsd32_statfs,
ELFNAME2(netbsd32,probe_noteless), darwin_sys_statfs,
ibcs2_sys_statfs, ibcs2_sys_statvfs, linux_sys_uselib,
osf1_sys_statfs, sunos_sys_statfs, sunos32_sys_statfs,
ultrix_sys_statfs, do_sys_mount, fss_create_files (3 of 4),
adosfs_mount, cd9660_mount, coda_ioctl, coda_mount, ext2fs_mount,
ffs_mount, filecore_mount, hfs_mount, lfs_mount, msdosfs_mount,
ntfs_mount, sysvbfs_mount, udf_mount, union_mount, sys_chflags,
sys_lchflags, sys_chmod, sys_lchmod, sys_chown, sys_lchown,
sys___posix_chown, sys___posix_lchown, sys_link, do_sys_pstatvfs,
sys_quotactl, sys_revoke, sys_truncate, do_sys_utimes, sys_extattrctl,
sys_extattr_set_file, sys_extattr_set_link, sys_extattr_get_file,
sys_extattr_get_link, sys_extattr_delete_file,
sys_extattr_delete_link, sys_extattr_list_file, sys_extattr_list_link,
sys_setxattr, sys_lsetxattr, sys_getxattr, sys_lgetxattr,
sys_listxattr, sys_llistxattr, sys_removexattr, sys_lremovexattr
All have been scrutinized (several times, in fact) and compile-tested,
but not all have been explicitly tested in action.
XXX: While I haven't (intentionally) changed the use or nonuse of
XXX: TRYEMULROOT in any of these places, I'm not convinced all the
XXX: uses are correct; an audit might be desirable.
2009-06-29 09:08:15 +04:00
|
|
|
if (dorele != 0)
|
|
|
|
vrele(vp);
|
2007-05-12 21:28:19 +04:00
|
|
|
|
2008-06-17 20:18:01 +04:00
|
|
|
return error;
|
1996-04-23 14:29:02 +04:00
|
|
|
}
|
|
|
|
|
2011-08-17 11:22:33 +04:00
|
|
|
int
|
|
|
|
do_sys_utimes(struct lwp *l, struct vnode *vp, const char *path, int flag,
|
|
|
|
const struct timeval *tptr, enum uio_seg seg)
|
|
|
|
{
|
|
|
|
struct timespec ts[2];
|
|
|
|
struct timespec *tsptr = NULL;
|
|
|
|
int error;
|
|
|
|
|
|
|
|
if (tptr != NULL) {
|
|
|
|
struct timeval tv[2];
|
|
|
|
|
|
|
|
if (seg != UIO_SYSSPACE) {
|
|
|
|
error = copyin(tptr, tv, sizeof (tv));
|
|
|
|
if (error != 0)
|
|
|
|
return error;
|
|
|
|
tptr = tv;
|
|
|
|
}
|
|
|
|
|
|
|
|
if ((tv[0].tv_usec == UTIME_NOW) ||
|
|
|
|
(tv[0].tv_usec == UTIME_OMIT))
|
|
|
|
ts[0].tv_nsec = tv[0].tv_usec;
|
|
|
|
else
|
|
|
|
TIMEVAL_TO_TIMESPEC(&tptr[0], &ts[0]);
|
|
|
|
|
|
|
|
if ((tv[1].tv_usec == UTIME_NOW) ||
|
|
|
|
(tv[1].tv_usec == UTIME_OMIT))
|
|
|
|
ts[1].tv_nsec = tv[1].tv_usec;
|
|
|
|
else
|
|
|
|
TIMEVAL_TO_TIMESPEC(&tptr[1], &ts[1]);
|
|
|
|
|
|
|
|
tsptr = &ts[0];
|
|
|
|
}
|
|
|
|
|
|
|
|
return do_sys_utimens(l, vp, path, flag, tsptr, UIO_SYSSPACE);
|
|
|
|
}
|
|
|
|
|
1994-06-29 10:29:24 +04:00
|
|
|
/*
|
|
|
|
* Truncate a file given its path name.
|
|
|
|
*/
|
|
|
|
/* ARGSUSED */
|
1996-02-04 05:17:43 +03:00
|
|
|
int
|
2007-12-21 02:02:38 +03:00
|
|
|
sys_truncate(struct lwp *l, const struct sys_truncate_args *uap, register_t *retval)
|
1995-09-20 01:40:36 +04:00
|
|
|
{
|
2007-12-21 02:02:38 +03:00
|
|
|
/* {
|
1996-12-22 13:21:06 +03:00
|
|
|
syscallarg(const char *) path;
|
1994-10-20 07:22:35 +03:00
|
|
|
syscallarg(int) pad;
|
|
|
|
syscallarg(off_t) length;
|
2007-12-21 02:02:38 +03:00
|
|
|
} */
|
2000-03-30 13:27:11 +04:00
|
|
|
struct vnode *vp;
|
1994-06-29 10:29:24 +04:00
|
|
|
struct vattr vattr;
|
|
|
|
int error;
|
|
|
|
|
Convert 67 namei call sites to use namei_simple, in these functions:
check_console, veriexecclose, veriexec_delete, veriexec_file_add,
emul_find_root, coff_load_shlib (sh3 version), coff_load_shlib,
compat_20_sys_statfs, compat_20_netbsd32_statfs,
ELFNAME2(netbsd32,probe_noteless), darwin_sys_statfs,
ibcs2_sys_statfs, ibcs2_sys_statvfs, linux_sys_uselib,
osf1_sys_statfs, sunos_sys_statfs, sunos32_sys_statfs,
ultrix_sys_statfs, do_sys_mount, fss_create_files (3 of 4),
adosfs_mount, cd9660_mount, coda_ioctl, coda_mount, ext2fs_mount,
ffs_mount, filecore_mount, hfs_mount, lfs_mount, msdosfs_mount,
ntfs_mount, sysvbfs_mount, udf_mount, union_mount, sys_chflags,
sys_lchflags, sys_chmod, sys_lchmod, sys_chown, sys_lchown,
sys___posix_chown, sys___posix_lchown, sys_link, do_sys_pstatvfs,
sys_quotactl, sys_revoke, sys_truncate, do_sys_utimes, sys_extattrctl,
sys_extattr_set_file, sys_extattr_set_link, sys_extattr_get_file,
sys_extattr_get_link, sys_extattr_delete_file,
sys_extattr_delete_link, sys_extattr_list_file, sys_extattr_list_link,
sys_setxattr, sys_lsetxattr, sys_getxattr, sys_lgetxattr,
sys_listxattr, sys_llistxattr, sys_removexattr, sys_lremovexattr
All have been scrutinized (several times, in fact) and compile-tested,
but not all have been explicitly tested in action.
XXX: While I haven't (intentionally) changed the use or nonuse of
XXX: TRYEMULROOT in any of these places, I'm not convinced all the
XXX: uses are correct; an audit might be desirable.
2009-06-29 09:08:15 +04:00
|
|
|
error = namei_simple_user(SCARG(uap, path),
|
|
|
|
NSM_FOLLOW_TRYEMULROOT, &vp);
|
|
|
|
if (error != 0)
|
1994-06-29 10:29:24 +04:00
|
|
|
return (error);
|
1998-03-01 05:20:01 +03:00
|
|
|
vn_lock(vp, LK_EXCLUSIVE | LK_RETRY);
|
1994-06-29 10:29:24 +04:00
|
|
|
if (vp->v_type == VDIR)
|
|
|
|
error = EISDIR;
|
|
|
|
else if ((error = vn_writechk(vp)) == 0 &&
|
2007-11-26 22:01:26 +03:00
|
|
|
(error = VOP_ACCESS(vp, VWRITE, l->l_cred)) == 0) {
|
2010-01-08 14:35:07 +03:00
|
|
|
vattr_null(&vattr);
|
1994-10-20 07:22:35 +03:00
|
|
|
vattr.va_size = SCARG(uap, length);
|
2007-11-26 22:01:26 +03:00
|
|
|
error = VOP_SETATTR(vp, &vattr, l->l_cred);
|
1994-06-29 10:29:24 +04:00
|
|
|
}
|
|
|
|
vput(vp);
|
|
|
|
return (error);
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Truncate a file given a file descriptor.
|
|
|
|
*/
|
|
|
|
/* ARGSUSED */
|
1996-02-04 05:17:43 +03:00
|
|
|
int
|
2007-12-21 02:02:38 +03:00
|
|
|
sys_ftruncate(struct lwp *l, const struct sys_ftruncate_args *uap, register_t *retval)
|
1995-09-20 01:40:36 +04:00
|
|
|
{
|
2007-12-21 02:02:38 +03:00
|
|
|
/* {
|
1994-10-20 07:22:35 +03:00
|
|
|
syscallarg(int) fd;
|
|
|
|
syscallarg(int) pad;
|
|
|
|
syscallarg(off_t) length;
|
2007-12-21 02:02:38 +03:00
|
|
|
} */
|
1994-06-29 10:29:24 +04:00
|
|
|
struct vattr vattr;
|
|
|
|
struct vnode *vp;
|
2008-03-22 00:54:58 +03:00
|
|
|
file_t *fp;
|
1994-06-29 10:29:24 +04:00
|
|
|
int error;
|
|
|
|
|
2008-03-22 00:54:58 +03:00
|
|
|
/* fd_getvnode() will use the descriptor for us */
|
|
|
|
if ((error = fd_getvnode(SCARG(uap, fd), &fp)) != 0)
|
1994-06-29 10:29:24 +04:00
|
|
|
return (error);
|
1999-05-06 00:01:01 +04:00
|
|
|
if ((fp->f_flag & FWRITE) == 0) {
|
|
|
|
error = EINVAL;
|
|
|
|
goto out;
|
|
|
|
}
|
2008-03-22 00:54:58 +03:00
|
|
|
vp = fp->f_data;
|
1998-03-01 05:20:01 +03:00
|
|
|
vn_lock(vp, LK_EXCLUSIVE | LK_RETRY);
|
1994-06-29 10:29:24 +04:00
|
|
|
if (vp->v_type == VDIR)
|
|
|
|
error = EISDIR;
|
|
|
|
else if ((error = vn_writechk(vp)) == 0) {
|
2010-01-08 14:35:07 +03:00
|
|
|
vattr_null(&vattr);
|
1994-10-20 07:22:35 +03:00
|
|
|
vattr.va_size = SCARG(uap, length);
|
2007-11-26 22:01:26 +03:00
|
|
|
error = VOP_SETATTR(vp, &vattr, fp->f_cred);
|
1994-06-29 10:29:24 +04:00
|
|
|
}
|
2010-06-24 16:58:48 +04:00
|
|
|
VOP_UNLOCK(vp);
|
1999-05-06 00:01:01 +04:00
|
|
|
out:
|
2008-03-22 00:54:58 +03:00
|
|
|
fd_putfile(SCARG(uap, fd));
|
1994-06-29 10:29:24 +04:00
|
|
|
return (error);
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Sync an open file.
|
|
|
|
*/
|
|
|
|
/* ARGSUSED */
|
1996-02-04 05:17:43 +03:00
|
|
|
int
|
2007-12-21 02:02:38 +03:00
|
|
|
sys_fsync(struct lwp *l, const struct sys_fsync_args *uap, register_t *retval)
|
1994-06-29 10:29:24 +04:00
|
|
|
{
|
2007-12-21 02:02:38 +03:00
|
|
|
/* {
|
1995-09-20 01:40:36 +04:00
|
|
|
syscallarg(int) fd;
|
2007-12-21 02:02:38 +03:00
|
|
|
} */
|
2000-03-30 13:27:11 +04:00
|
|
|
struct vnode *vp;
|
2008-03-22 00:54:58 +03:00
|
|
|
file_t *fp;
|
1994-06-29 10:29:24 +04:00
|
|
|
int error;
|
|
|
|
|
2008-03-22 00:54:58 +03:00
|
|
|
/* fd_getvnode() will use the descriptor for us */
|
|
|
|
if ((error = fd_getvnode(SCARG(uap, fd), &fp)) != 0)
|
1994-06-29 10:29:24 +04:00
|
|
|
return (error);
|
2008-03-22 00:54:58 +03:00
|
|
|
vp = fp->f_data;
|
1998-03-01 05:20:01 +03:00
|
|
|
vn_lock(vp, LK_EXCLUSIVE | LK_RETRY);
|
2007-11-26 22:01:26 +03:00
|
|
|
error = VOP_FSYNC(vp, fp->f_cred, FSYNC_WAIT, 0, 0);
|
2010-06-24 16:58:48 +04:00
|
|
|
VOP_UNLOCK(vp);
|
2008-03-22 00:54:58 +03:00
|
|
|
fd_putfile(SCARG(uap, fd));
|
1994-06-29 10:29:24 +04:00
|
|
|
return (error);
|
|
|
|
}
|
|
|
|
|
2003-11-15 04:19:38 +03:00
|
|
|
/*
|
|
|
|
* Sync a range of file data. API modeled after that found in AIX.
|
|
|
|
*
|
|
|
|
* FDATASYNC indicates that we need only save enough metadata to be able
|
|
|
|
* to re-read the written data. Note we duplicate AIX's requirement that
|
|
|
|
* the file be open for writing.
|
|
|
|
*/
|
|
|
|
/* ARGSUSED */
|
|
|
|
int
|
2007-12-21 02:02:38 +03:00
|
|
|
sys_fsync_range(struct lwp *l, const struct sys_fsync_range_args *uap, register_t *retval)
|
2003-11-15 04:19:38 +03:00
|
|
|
{
|
2007-12-21 02:02:38 +03:00
|
|
|
/* {
|
2003-11-15 04:19:38 +03:00
|
|
|
syscallarg(int) fd;
|
|
|
|
syscallarg(int) flags;
|
|
|
|
syscallarg(off_t) start;
|
2005-07-10 18:26:02 +04:00
|
|
|
syscallarg(off_t) length;
|
2007-12-21 02:02:38 +03:00
|
|
|
} */
|
2003-11-15 04:19:38 +03:00
|
|
|
struct vnode *vp;
|
2008-03-22 00:54:58 +03:00
|
|
|
file_t *fp;
|
2003-11-15 04:19:38 +03:00
|
|
|
int flags, nflags;
|
|
|
|
off_t s, e, len;
|
|
|
|
int error;
|
|
|
|
|
2008-03-22 00:54:58 +03:00
|
|
|
/* fd_getvnode() will use the descriptor for us */
|
|
|
|
if ((error = fd_getvnode(SCARG(uap, fd), &fp)) != 0)
|
2003-11-15 04:19:38 +03:00
|
|
|
return (error);
|
|
|
|
|
|
|
|
if ((fp->f_flag & FWRITE) == 0) {
|
2007-01-04 02:20:58 +03:00
|
|
|
error = EBADF;
|
|
|
|
goto out;
|
2003-11-15 04:19:38 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
flags = SCARG(uap, flags);
|
|
|
|
if (((flags & (FDATASYNC | FFILESYNC)) == 0) ||
|
|
|
|
((~flags & (FDATASYNC | FFILESYNC)) == 0)) {
|
2007-01-04 02:20:58 +03:00
|
|
|
error = EINVAL;
|
|
|
|
goto out;
|
2003-11-15 04:19:38 +03:00
|
|
|
}
|
|
|
|
/* Now set up the flags for value(s) to pass to VOP_FSYNC() */
|
|
|
|
if (flags & FDATASYNC)
|
|
|
|
nflags = FSYNC_DATAONLY | FSYNC_WAIT;
|
|
|
|
else
|
|
|
|
nflags = FSYNC_WAIT;
|
2005-01-26 02:55:20 +03:00
|
|
|
if (flags & FDISKSYNC)
|
|
|
|
nflags |= FSYNC_CACHE;
|
2003-11-15 04:19:38 +03:00
|
|
|
|
|
|
|
len = SCARG(uap, length);
|
2011-06-02 22:54:43 +04:00
|
|
|
/* If length == 0, we do the whole file, and s = e = 0 will do that */
|
2003-11-15 04:19:38 +03:00
|
|
|
if (len) {
|
|
|
|
s = SCARG(uap, start);
|
|
|
|
e = s + len;
|
|
|
|
if (e < s) {
|
2007-01-04 02:20:58 +03:00
|
|
|
error = EINVAL;
|
|
|
|
goto out;
|
2003-11-15 04:19:38 +03:00
|
|
|
}
|
|
|
|
} else {
|
|
|
|
e = 0;
|
|
|
|
s = 0;
|
|
|
|
}
|
|
|
|
|
2008-03-22 00:54:58 +03:00
|
|
|
vp = fp->f_data;
|
2003-11-15 04:19:38 +03:00
|
|
|
vn_lock(vp, LK_EXCLUSIVE | LK_RETRY);
|
2007-11-26 22:01:26 +03:00
|
|
|
error = VOP_FSYNC(vp, fp->f_cred, nflags, s, e);
|
2010-06-24 16:58:48 +04:00
|
|
|
VOP_UNLOCK(vp);
|
2007-01-04 02:20:58 +03:00
|
|
|
out:
|
2008-03-22 00:54:58 +03:00
|
|
|
fd_putfile(SCARG(uap, fd));
|
2003-11-15 04:19:38 +03:00
|
|
|
return (error);
|
|
|
|
}
|
|
|
|
|
1998-06-06 00:31:36 +04:00
|
|
|
/*
|
|
|
|
* Sync the data of an open file.
|
|
|
|
*/
|
|
|
|
/* ARGSUSED */
|
|
|
|
int
|
2007-12-21 02:02:38 +03:00
|
|
|
sys_fdatasync(struct lwp *l, const struct sys_fdatasync_args *uap, register_t *retval)
|
1998-06-06 00:31:36 +04:00
|
|
|
{
|
2007-12-21 02:02:38 +03:00
|
|
|
/* {
|
1998-06-06 00:31:36 +04:00
|
|
|
syscallarg(int) fd;
|
2007-12-21 02:02:38 +03:00
|
|
|
} */
|
1998-06-06 00:31:36 +04:00
|
|
|
struct vnode *vp;
|
2008-03-22 00:54:58 +03:00
|
|
|
file_t *fp;
|
1998-06-06 00:31:36 +04:00
|
|
|
int error;
|
|
|
|
|
2008-03-22 00:54:58 +03:00
|
|
|
/* fd_getvnode() will use the descriptor for us */
|
|
|
|
if ((error = fd_getvnode(SCARG(uap, fd), &fp)) != 0)
|
1998-06-06 00:31:36 +04:00
|
|
|
return (error);
|
2003-10-25 05:18:01 +04:00
|
|
|
if ((fp->f_flag & FWRITE) == 0) {
|
2008-03-22 00:54:58 +03:00
|
|
|
fd_putfile(SCARG(uap, fd));
|
2003-10-25 05:18:01 +04:00
|
|
|
return (EBADF);
|
|
|
|
}
|
2008-03-22 00:54:58 +03:00
|
|
|
vp = fp->f_data;
|
1998-06-06 00:31:36 +04:00
|
|
|
vn_lock(vp, LK_EXCLUSIVE | LK_RETRY);
|
2007-11-26 22:01:26 +03:00
|
|
|
error = VOP_FSYNC(vp, fp->f_cred, FSYNC_WAIT|FSYNC_DATAONLY, 0, 0);
|
2010-06-24 16:58:48 +04:00
|
|
|
VOP_UNLOCK(vp);
|
2008-03-22 00:54:58 +03:00
|
|
|
fd_putfile(SCARG(uap, fd));
|
1998-06-06 00:31:36 +04:00
|
|
|
return (error);
|
|
|
|
}
|
|
|
|
|
1994-06-29 10:29:24 +04:00
|
|
|
/*
|
1997-05-18 23:56:48 +04:00
|
|
|
* Rename files, (standard) BSD semantics frontend.
|
1994-06-29 10:29:24 +04:00
|
|
|
*/
|
|
|
|
/* ARGSUSED */
|
1996-02-04 05:17:43 +03:00
|
|
|
int
|
2007-12-21 02:02:38 +03:00
|
|
|
sys_rename(struct lwp *l, const struct sys_rename_args *uap, register_t *retval)
|
1995-09-20 01:40:36 +04:00
|
|
|
{
|
2007-12-21 02:02:38 +03:00
|
|
|
/* {
|
1996-12-22 13:21:06 +03:00
|
|
|
syscallarg(const char *) from;
|
|
|
|
syscallarg(const char *) to;
|
2007-12-21 02:02:38 +03:00
|
|
|
} */
|
1997-05-18 23:56:48 +04:00
|
|
|
|
Add most system calls for POSIX extended API set, part 2, with test cases:
faccessat(2), fchmodat(2), fchownat(2), fstatat(2), mkdirat(2), mkfifoat(2),
mknodat(2), linkat(2), readlinkat(2), symlinkat(2), renameat(2), unlinkat(2),
utimensat(2), openat(2).
Also implement O_SEARCH for openat(2)
Still missing:
- some flags for openat(2)
- fexecve(2) implementation
2012-11-18 21:41:51 +04:00
|
|
|
return (do_sys_renameat(l, AT_FDCWD, SCARG(uap, from), AT_FDCWD,
|
|
|
|
SCARG(uap, to), UIO_USERSPACE, 0));
|
1997-05-18 23:56:48 +04:00
|
|
|
}
|
|
|
|
|
2011-08-08 16:08:52 +04:00
|
|
|
int
|
|
|
|
sys_renameat(struct lwp *l, const struct sys_renameat_args *uap,
|
|
|
|
register_t *retval)
|
|
|
|
{
|
|
|
|
/* {
|
|
|
|
syscallarg(int) fromfd;
|
|
|
|
syscallarg(const char *) from;
|
|
|
|
syscallarg(int) tofd;
|
|
|
|
syscallarg(const char *) to;
|
|
|
|
} */
|
|
|
|
|
Add most system calls for POSIX extended API set, part 2, with test cases:
faccessat(2), fchmodat(2), fchownat(2), fstatat(2), mkdirat(2), mkfifoat(2),
mknodat(2), linkat(2), readlinkat(2), symlinkat(2), renameat(2), unlinkat(2),
utimensat(2), openat(2).
Also implement O_SEARCH for openat(2)
Still missing:
- some flags for openat(2)
- fexecve(2) implementation
2012-11-18 21:41:51 +04:00
|
|
|
return (do_sys_renameat(l, SCARG(uap, fromfd), SCARG(uap, from),
|
|
|
|
SCARG(uap, tofd), SCARG(uap, to), UIO_USERSPACE, 0));
|
2011-08-08 16:08:52 +04:00
|
|
|
}
|
|
|
|
|
1997-05-18 23:56:48 +04:00
|
|
|
/*
|
|
|
|
* Rename files, POSIX semantics frontend.
|
|
|
|
*/
|
|
|
|
/* ARGSUSED */
|
|
|
|
int
|
2007-12-21 02:02:38 +03:00
|
|
|
sys___posix_rename(struct lwp *l, const struct sys___posix_rename_args *uap, register_t *retval)
|
1997-05-18 23:56:48 +04:00
|
|
|
{
|
2007-12-21 02:02:38 +03:00
|
|
|
/* {
|
1997-05-18 23:56:48 +04:00
|
|
|
syscallarg(const char *) from;
|
|
|
|
syscallarg(const char *) to;
|
2007-12-21 02:02:38 +03:00
|
|
|
} */
|
1997-05-18 23:56:48 +04:00
|
|
|
|
Add most system calls for POSIX extended API set, part 2, with test cases:
faccessat(2), fchmodat(2), fchownat(2), fstatat(2), mkdirat(2), mkfifoat(2),
mknodat(2), linkat(2), readlinkat(2), symlinkat(2), renameat(2), unlinkat(2),
utimensat(2), openat(2).
Also implement O_SEARCH for openat(2)
Still missing:
- some flags for openat(2)
- fexecve(2) implementation
2012-11-18 21:41:51 +04:00
|
|
|
return (do_sys_renameat(l, AT_FDCWD, SCARG(uap, from), AT_FDCWD,
|
|
|
|
SCARG(uap, to), UIO_USERSPACE, 1));
|
1997-05-18 23:56:48 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Rename files. Source and destination must either both be directories,
|
|
|
|
* or both not be directories. If target is a directory, it must be empty.
|
|
|
|
* If `from' and `to' refer to the same object, the value of the `retain'
|
|
|
|
* argument is used to determine whether `from' will be
|
|
|
|
*
|
|
|
|
* (retain == 0) deleted unless `from' and `to' refer to the same
|
|
|
|
* object in the file system's name space (BSD).
|
|
|
|
* (retain == 1) always retained (POSIX).
|
2012-10-12 06:37:20 +04:00
|
|
|
*
|
|
|
|
* XXX Synchronize with nfsrv_rename in nfs_serv.c.
|
1997-05-18 23:56:48 +04:00
|
|
|
*/
|
2007-12-24 18:04:19 +03:00
|
|
|
int
|
|
|
|
do_sys_rename(const char *from, const char *to, enum uio_seg seg, int retain)
|
Add most system calls for POSIX extended API set, part 2, with test cases:
faccessat(2), fchmodat(2), fchownat(2), fstatat(2), mkdirat(2), mkfifoat(2),
mknodat(2), linkat(2), readlinkat(2), symlinkat(2), renameat(2), unlinkat(2),
utimensat(2), openat(2).
Also implement O_SEARCH for openat(2)
Still missing:
- some flags for openat(2)
- fexecve(2) implementation
2012-11-18 21:41:51 +04:00
|
|
|
{
|
|
|
|
return do_sys_renameat(NULL, AT_FDCWD, from, AT_FDCWD, to, seg, retain);
|
|
|
|
}
|
|
|
|
|
|
|
|
static int
|
|
|
|
do_sys_renameat(struct lwp *l, int fromfd, const char *from, int tofd,
|
|
|
|
const char *to, enum uio_seg seg, int retain)
|
1997-05-18 23:56:48 +04:00
|
|
|
{
|
2012-10-12 06:37:20 +04:00
|
|
|
struct pathbuf *fpb, *tpb;
|
|
|
|
struct nameidata fnd, tnd;
|
|
|
|
struct vnode *fdvp, *fvp;
|
|
|
|
struct vnode *tdvp, *tvp;
|
|
|
|
struct mount *mp, *tmp;
|
1994-06-29 10:29:24 +04:00
|
|
|
int error;
|
|
|
|
|
Add most system calls for POSIX extended API set, part 2, with test cases:
faccessat(2), fchmodat(2), fchownat(2), fstatat(2), mkdirat(2), mkfifoat(2),
mknodat(2), linkat(2), readlinkat(2), symlinkat(2), renameat(2), unlinkat(2),
utimensat(2), openat(2).
Also implement O_SEARCH for openat(2)
Still missing:
- some flags for openat(2)
- fexecve(2) implementation
2012-11-18 21:41:51 +04:00
|
|
|
KASSERT(l != NULL || (fromfd == AT_FDCWD && tofd == AT_FDCWD));
|
2012-10-12 06:37:20 +04:00
|
|
|
KASSERT(from != NULL);
|
|
|
|
KASSERT(to != NULL);
|
2010-11-19 09:44:33 +03:00
|
|
|
|
2012-10-12 06:37:20 +04:00
|
|
|
error = pathbuf_maybe_copyin(from, seg, &fpb);
|
|
|
|
if (error)
|
|
|
|
goto out0;
|
|
|
|
KASSERT(fpb != NULL);
|
2008-01-28 17:31:15 +03:00
|
|
|
|
2012-10-12 06:37:20 +04:00
|
|
|
error = pathbuf_maybe_copyin(to, seg, &tpb);
|
|
|
|
if (error)
|
2008-01-28 17:31:15 +03:00
|
|
|
goto out1;
|
2012-10-12 06:37:20 +04:00
|
|
|
KASSERT(tpb != NULL);
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Lookup from.
|
|
|
|
*
|
|
|
|
* XXX LOCKPARENT is wrong because we don't actually want it
|
|
|
|
* locked yet, but (a) namei is insane, and (b) VOP_RENAME is
|
|
|
|
* insane, so for the time being we need to leave it like this.
|
|
|
|
*/
|
|
|
|
NDINIT(&fnd, DELETE, (LOCKPARENT | TRYEMULROOT | INRENAME), fpb);
|
Add most system calls for POSIX extended API set, part 2, with test cases:
faccessat(2), fchmodat(2), fchownat(2), fstatat(2), mkdirat(2), mkfifoat(2),
mknodat(2), linkat(2), readlinkat(2), symlinkat(2), renameat(2), unlinkat(2),
utimensat(2), openat(2).
Also implement O_SEARCH for openat(2)
Still missing:
- some flags for openat(2)
- fexecve(2) implementation
2012-11-18 21:41:51 +04:00
|
|
|
if ((error = fd_nameiat(l, fromfd, &fnd)) != 0)
|
2012-10-12 06:37:20 +04:00
|
|
|
goto out2;
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Pull out the important results of the lookup, fdvp and fvp.
|
|
|
|
* Of course, fvp is bogus because we're about to unlock fdvp.
|
|
|
|
*/
|
|
|
|
fdvp = fnd.ni_dvp;
|
|
|
|
fvp = fnd.ni_vp;
|
|
|
|
KASSERT(fdvp != NULL);
|
|
|
|
KASSERT(fvp != NULL);
|
|
|
|
KASSERT((fdvp == fvp) || (VOP_ISLOCKED(fdvp) == LK_EXCLUSIVE));
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Make sure neither fdvp nor fvp is locked.
|
|
|
|
*/
|
|
|
|
if (fdvp != fvp)
|
|
|
|
VOP_UNLOCK(fdvp);
|
|
|
|
/* XXX KASSERT(VOP_ISLOCKED(fdvp) != LK_EXCLUSIVE); */
|
|
|
|
/* XXX KASSERT(VOP_ISLOCKED(fvp) != LK_EXCLUSIVE); */
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Reject renaming `.' and `..'. Can't do this until after
|
|
|
|
* namei because we need namei's parsing to find the final
|
|
|
|
* component name. (namei should just leave us with the final
|
|
|
|
* component name and not look it up itself, but anyway...)
|
|
|
|
*
|
|
|
|
* This was here before because we used to relookup from
|
|
|
|
* instead of to and relookup requires the caller to check
|
|
|
|
* this, but now file systems may depend on this check, so we
|
|
|
|
* must retain it until the file systems are all rototilled.
|
|
|
|
*/
|
|
|
|
if (((fnd.ni_cnd.cn_namelen == 1) &&
|
|
|
|
(fnd.ni_cnd.cn_nameptr[0] == '.')) ||
|
|
|
|
((fnd.ni_cnd.cn_namelen == 2) &&
|
|
|
|
(fnd.ni_cnd.cn_nameptr[0] == '.') &&
|
|
|
|
(fnd.ni_cnd.cn_nameptr[1] == '.'))) {
|
|
|
|
error = EINVAL; /* XXX EISDIR? */
|
|
|
|
goto abort0;
|
2008-01-28 17:31:15 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
2012-10-12 06:37:20 +04:00
|
|
|
* Lookup to.
|
2008-01-28 17:31:15 +03:00
|
|
|
*
|
2012-10-12 06:37:20 +04:00
|
|
|
* XXX LOCKPARENT is wrong, but...insanity, &c. Also, using
|
|
|
|
* fvp here to decide whether to add CREATEDIR is a load of
|
|
|
|
* bollocks because fvp might be the wrong node by now, since
|
|
|
|
* fdvp is unlocked.
|
2008-01-28 17:31:15 +03:00
|
|
|
*
|
2012-10-12 06:37:20 +04:00
|
|
|
* XXX Why not pass CREATEDIR always?
|
2008-01-28 17:31:15 +03:00
|
|
|
*/
|
2012-10-12 06:37:20 +04:00
|
|
|
NDINIT(&tnd, RENAME,
|
|
|
|
(LOCKPARENT | NOCACHE | TRYEMULROOT | INRENAME |
|
|
|
|
((fvp->v_type == VDIR)? CREATEDIR : 0)),
|
|
|
|
tpb);
|
Add most system calls for POSIX extended API set, part 2, with test cases:
faccessat(2), fchmodat(2), fchownat(2), fstatat(2), mkdirat(2), mkfifoat(2),
mknodat(2), linkat(2), readlinkat(2), symlinkat(2), renameat(2), unlinkat(2),
utimensat(2), openat(2).
Also implement O_SEARCH for openat(2)
Still missing:
- some flags for openat(2)
- fexecve(2) implementation
2012-11-18 21:41:51 +04:00
|
|
|
if ((error = fd_nameiat(l, tofd, &tnd)) != 0)
|
2012-10-12 06:37:20 +04:00
|
|
|
goto abort0;
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Pull out the important results of the lookup, tdvp and tvp.
|
|
|
|
* Of course, tvp is bogus because we're about to unlock tdvp.
|
|
|
|
*/
|
|
|
|
tdvp = tnd.ni_dvp;
|
|
|
|
tvp = tnd.ni_vp;
|
|
|
|
KASSERT(tdvp != NULL);
|
|
|
|
KASSERT((tdvp == tvp) || (VOP_ISLOCKED(tdvp) == LK_EXCLUSIVE));
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Make sure neither tdvp nor tvp is locked.
|
|
|
|
*/
|
|
|
|
if (tdvp != tvp)
|
|
|
|
VOP_UNLOCK(tdvp);
|
|
|
|
/* XXX KASSERT(VOP_ISLOCKED(tdvp) != LK_EXCLUSIVE); */
|
|
|
|
/* XXX KASSERT((tvp == NULL) || (VOP_ISLOCKED(tvp) != LK_EXCLUSIVE)); */
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Reject renaming onto `.' or `..'. relookup is unhappy with
|
|
|
|
* these, which is why we must do this here. Once upon a time
|
|
|
|
* we relooked up from instead of to, and consequently didn't
|
|
|
|
* need this check, but now that we relookup to instead of
|
|
|
|
* from, we need this; and we shall need it forever forward
|
|
|
|
* until the VOP_RENAME protocol changes, because file systems
|
|
|
|
* will no doubt begin to depend on this check.
|
|
|
|
*/
|
|
|
|
if (((tnd.ni_cnd.cn_namelen == 1) &&
|
|
|
|
(tnd.ni_cnd.cn_nameptr[0] == '.')) ||
|
|
|
|
((tnd.ni_cnd.cn_namelen == 2) &&
|
|
|
|
(tnd.ni_cnd.cn_nameptr[0] == '.') &&
|
|
|
|
(tnd.ni_cnd.cn_nameptr[1] == '.'))) {
|
|
|
|
error = EINVAL; /* XXX EISDIR? */
|
|
|
|
goto abort1;
|
2008-03-28 08:02:08 +03:00
|
|
|
}
|
2012-10-12 06:37:20 +04:00
|
|
|
|
|
|
|
/*
|
|
|
|
* Get the mount point. If the file system has been unmounted,
|
|
|
|
* which it may be because we're not holding any vnode locks,
|
|
|
|
* then v_mount will be NULL. We're not really supposed to
|
|
|
|
* read v_mount without holding the vnode lock, but since we
|
|
|
|
* have fdvp referenced, if fdvp->v_mount changes then at worst
|
|
|
|
* it will be set to NULL, not changed to another mount point.
|
|
|
|
* And, of course, since it is up to the file system to
|
|
|
|
* determine the real lock order, we can't lock both fdvp and
|
|
|
|
* tdvp at the same time.
|
|
|
|
*/
|
|
|
|
mp = fdvp->v_mount;
|
|
|
|
if (mp == NULL) {
|
|
|
|
error = ENOENT;
|
|
|
|
goto abort1;
|
2008-01-28 17:31:15 +03:00
|
|
|
}
|
2012-10-12 06:37:20 +04:00
|
|
|
|
|
|
|
/*
|
|
|
|
* Make sure the mount points match. Again, although we don't
|
|
|
|
* hold any vnode locks, the v_mount fields may change -- but
|
|
|
|
* at worst they will change to NULL, so this will never become
|
|
|
|
* a cross-device rename, because we hold vnode references.
|
|
|
|
*
|
|
|
|
* XXX Because nothing is locked and the compiler may reorder
|
|
|
|
* things here, unmounting the file system at an inopportune
|
|
|
|
* moment may cause rename to fail with ENXDEV when it really
|
|
|
|
* should fail with ENOENT.
|
|
|
|
*/
|
|
|
|
tmp = tdvp->v_mount;
|
|
|
|
if (tmp == NULL) {
|
|
|
|
error = ENOENT;
|
|
|
|
goto abort1;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (mp != tmp) {
|
|
|
|
error = EXDEV;
|
|
|
|
goto abort1;
|
1994-06-29 10:29:24 +04:00
|
|
|
}
|
1997-05-18 23:56:48 +04:00
|
|
|
|
2012-10-12 06:37:20 +04:00
|
|
|
/*
|
|
|
|
* Take the vfs rename lock to avoid cross-directory screw cases.
|
|
|
|
* Nothing is locked currently, so taking this lock is safe.
|
|
|
|
*/
|
2012-10-19 06:07:22 +04:00
|
|
|
error = VFS_RENAMELOCK_ENTER(mp);
|
|
|
|
if (error)
|
|
|
|
goto abort1;
|
2012-10-12 06:37:20 +04:00
|
|
|
|
|
|
|
/*
|
|
|
|
* Now fdvp, fvp, tdvp, and (if nonnull) tvp are referenced,
|
|
|
|
* and nothing is locked except for the vfs rename lock.
|
|
|
|
*
|
|
|
|
* The next step is a little rain dance to conform to the
|
|
|
|
* insane lock protocol, even though it does nothing to ward
|
|
|
|
* off race conditions.
|
|
|
|
*
|
|
|
|
* We need tdvp and tvp to be locked. However, because we have
|
|
|
|
* unlocked tdvp in order to hold no locks while we take the
|
|
|
|
* vfs rename lock, tvp may be wrong here, and we can't safely
|
|
|
|
* lock it even if the sensible file systems will just unlock
|
|
|
|
* it straight away. Consequently, we must lock tdvp and then
|
|
|
|
* relookup tvp to get it locked.
|
|
|
|
*
|
|
|
|
* Finally, because the VOP_RENAME protocol is brain-damaged
|
|
|
|
* and various file systems insanely depend on the semantics of
|
|
|
|
* this brain damage, the lookup of to must be the last lookup
|
|
|
|
* before VOP_RENAME.
|
|
|
|
*/
|
|
|
|
vn_lock(tdvp, LK_EXCLUSIVE | LK_RETRY);
|
|
|
|
error = relookup(tdvp, &tnd.ni_vp, &tnd.ni_cnd, 0);
|
|
|
|
if (error)
|
|
|
|
goto abort2;
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Drop the old tvp and pick up the new one -- which might be
|
|
|
|
* the same, but that doesn't matter to us. After this, tdvp
|
|
|
|
* and tvp should both be locked.
|
|
|
|
*/
|
|
|
|
if (tvp != NULL)
|
|
|
|
vrele(tvp);
|
|
|
|
tvp = tnd.ni_vp;
|
|
|
|
KASSERT(VOP_ISLOCKED(tdvp) == LK_EXCLUSIVE);
|
|
|
|
KASSERT((tvp == NULL) || (VOP_ISLOCKED(tvp) == LK_EXCLUSIVE));
|
|
|
|
|
|
|
|
/*
|
|
|
|
* The old do_sys_rename had various consistency checks here
|
|
|
|
* involving fvp and tvp. fvp is bogus already here, and tvp
|
|
|
|
* will become bogus soon in any sensible file system, so the
|
|
|
|
* only purpose in putting these checks here is to give lip
|
|
|
|
* service to these screw cases and to acknowledge that they
|
|
|
|
* exist, not actually to handle them, but here you go
|
|
|
|
* anyway...
|
|
|
|
*/
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Acknowledge that directories and non-directories aren't
|
|
|
|
* suposed to mix.
|
|
|
|
*/
|
1994-06-29 10:29:24 +04:00
|
|
|
if (tvp != NULL) {
|
2012-10-12 06:37:20 +04:00
|
|
|
if ((fvp->v_type == VDIR) && (tvp->v_type != VDIR)) {
|
1994-06-29 10:29:24 +04:00
|
|
|
error = ENOTDIR;
|
2012-10-12 06:37:20 +04:00
|
|
|
goto abort3;
|
|
|
|
} else if ((fvp->v_type != VDIR) && (tvp->v_type == VDIR)) {
|
1994-06-29 10:29:24 +04:00
|
|
|
error = EISDIR;
|
2012-10-12 06:37:20 +04:00
|
|
|
goto abort3;
|
1994-06-29 10:29:24 +04:00
|
|
|
}
|
|
|
|
}
|
1997-05-18 23:56:48 +04:00
|
|
|
|
2012-10-12 06:37:20 +04:00
|
|
|
/*
|
|
|
|
* Acknowledge some random screw case, among the dozens that
|
|
|
|
* might arise.
|
|
|
|
*/
|
|
|
|
if (fvp == tdvp) {
|
1994-06-29 10:29:24 +04:00
|
|
|
error = EINVAL;
|
2012-10-12 06:37:20 +04:00
|
|
|
goto abort3;
|
|
|
|
}
|
1997-05-18 23:56:48 +04:00
|
|
|
|
1997-04-07 04:04:16 +04:00
|
|
|
/*
|
2012-10-12 06:37:20 +04:00
|
|
|
* Acknowledge that POSIX has a wacky screw case.
|
|
|
|
*
|
|
|
|
* XXX Eventually the retain flag needs to be passed on to
|
|
|
|
* VOP_RENAME.
|
1997-04-07 04:04:16 +04:00
|
|
|
*/
|
1997-05-18 23:56:48 +04:00
|
|
|
if (fvp == tvp) {
|
2012-10-12 06:37:20 +04:00
|
|
|
if (retain) {
|
|
|
|
error = 0;
|
|
|
|
goto abort3;
|
|
|
|
} else if ((fdvp == tdvp) &&
|
|
|
|
(fnd.ni_cnd.cn_namelen == tnd.ni_cnd.cn_namelen) &&
|
|
|
|
(0 == memcmp(fnd.ni_cnd.cn_nameptr, tnd.ni_cnd.cn_nameptr,
|
|
|
|
fnd.ni_cnd.cn_namelen))) {
|
|
|
|
error = 0;
|
|
|
|
goto abort3;
|
|
|
|
}
|
1997-05-18 23:56:48 +04:00
|
|
|
}
|
2012-10-12 06:37:20 +04:00
|
|
|
|
2011-03-12 10:16:50 +03:00
|
|
|
/*
|
2012-10-12 06:37:20 +04:00
|
|
|
* Make sure veriexec can screw us up. (But a race can screw
|
|
|
|
* up veriexec, of course -- remember, fvp and (soon) tvp are
|
|
|
|
* bogus.)
|
2011-03-12 10:16:50 +03:00
|
|
|
*/
|
2006-07-22 14:34:26 +04:00
|
|
|
#if NVERIEXEC > 0
|
2012-10-12 06:37:20 +04:00
|
|
|
{
|
Some Veriexec stuff that's been rotting in my tree for months.
Bug fixes:
- Fix crash reported by Scott Ellis on current-users@.
- Fix race conditions in enforcing the Veriexec rename and remove
policies. These are NOT security issues.
- Fix memory leak in rename handling when overwriting a monitored
file.
- Fix table deletion logic.
- Don't prevent query requests if not in learning mode.
KPI updates:
- fileassoc_table_run() now takes a cookie to pass to the callback.
- veriexec_table_add() was removed, it is now done internally. As a
result, there's no longer a need for VERIEXEC_TABLESIZE.
- veriexec_report() was removed, it is now internal.
- Perform sanity checks on the entry type, and enforce default type
in veriexec_file_add() rather than in veriexecctl.
- Add veriexec_flush(), used to delete all Veriexec tables, and
veriexec_dump(), used to fill an array with all Veriexec entries.
New features:
- Add a '-k' flag to veriexecctl, to keep the filenames in the kernel
database. This allows Veriexec to produce slightly more accurate
logs under certain circumstances. In the future, this can be either
replaced by vnode->pathname translation, or combined with it.
- Add a VERIEXEC_DUMP ioctl, to dump the entire Veriexec database.
This can be used to recover a database if the file was lost.
Example usage:
# veriexecctl dump > /etc/signatures
Note that only entries with the filename kept (that is, were loaded
with the '-k' flag) will be dumped.
Idea from Brett Lymn.
- Add a VERIEXEC_FLUSH ioctl, to delete all Veriexec entries. Sample
usage:
# veriexecctl flush
- Add a 'veriexec_flags' rc(8) variable, and make its default have
the '-k' flag. On systems using the default signatures file
(generaetd from running 'veriexecgen' with no arguments), this will
use additional 32kb of kernel memory on average.
- Add a '-e' flag to veriexecctl, to evaluate the fingerprint during
load. This is done automatically for files marked as 'untrusted'.
Misc. stuff:
- The code for veriexecctl was massively simplified as a result of
eliminating the need for VERIEXEC_TABLESIZE, and now uses a single
pass of the signatures file, making the loading somewhat faster.
- Lots of minor fixes found using the (still under development)
Veriexec regression testsuite.
- Some of the messages Veriexec prints were improved.
- Various documentation fixes.
All relevant man-pages were updated to reflect the above changes.
Binary compatibility with existing veriexecctl binaries is maintained.
2007-05-15 23:47:43 +04:00
|
|
|
char *f1, *f2;
|
2009-01-17 10:02:35 +03:00
|
|
|
size_t f1_len;
|
|
|
|
size_t f2_len;
|
Some Veriexec stuff that's been rotting in my tree for months.
Bug fixes:
- Fix crash reported by Scott Ellis on current-users@.
- Fix race conditions in enforcing the Veriexec rename and remove
policies. These are NOT security issues.
- Fix memory leak in rename handling when overwriting a monitored
file.
- Fix table deletion logic.
- Don't prevent query requests if not in learning mode.
KPI updates:
- fileassoc_table_run() now takes a cookie to pass to the callback.
- veriexec_table_add() was removed, it is now done internally. As a
result, there's no longer a need for VERIEXEC_TABLESIZE.
- veriexec_report() was removed, it is now internal.
- Perform sanity checks on the entry type, and enforce default type
in veriexec_file_add() rather than in veriexecctl.
- Add veriexec_flush(), used to delete all Veriexec tables, and
veriexec_dump(), used to fill an array with all Veriexec entries.
New features:
- Add a '-k' flag to veriexecctl, to keep the filenames in the kernel
database. This allows Veriexec to produce slightly more accurate
logs under certain circumstances. In the future, this can be either
replaced by vnode->pathname translation, or combined with it.
- Add a VERIEXEC_DUMP ioctl, to dump the entire Veriexec database.
This can be used to recover a database if the file was lost.
Example usage:
# veriexecctl dump > /etc/signatures
Note that only entries with the filename kept (that is, were loaded
with the '-k' flag) will be dumped.
Idea from Brett Lymn.
- Add a VERIEXEC_FLUSH ioctl, to delete all Veriexec entries. Sample
usage:
# veriexecctl flush
- Add a 'veriexec_flags' rc(8) variable, and make its default have
the '-k' flag. On systems using the default signatures file
(generaetd from running 'veriexecgen' with no arguments), this will
use additional 32kb of kernel memory on average.
- Add a '-e' flag to veriexecctl, to evaluate the fingerprint during
load. This is done automatically for files marked as 'untrusted'.
Misc. stuff:
- The code for veriexecctl was massively simplified as a result of
eliminating the need for VERIEXEC_TABLESIZE, and now uses a single
pass of the signatures file, making the loading somewhat faster.
- Lots of minor fixes found using the (still under development)
Veriexec regression testsuite.
- Some of the messages Veriexec prints were improved.
- Various documentation fixes.
All relevant man-pages were updated to reflect the above changes.
Binary compatibility with existing veriexecctl binaries is maintained.
2007-05-15 23:47:43 +04:00
|
|
|
|
2012-10-12 06:37:20 +04:00
|
|
|
f1_len = fnd.ni_cnd.cn_namelen + 1;
|
2009-01-17 10:02:35 +03:00
|
|
|
f1 = kmem_alloc(f1_len, KM_SLEEP);
|
2012-10-12 06:37:20 +04:00
|
|
|
strlcpy(f1, fnd.ni_cnd.cn_nameptr, f1_len);
|
Some Veriexec stuff that's been rotting in my tree for months.
Bug fixes:
- Fix crash reported by Scott Ellis on current-users@.
- Fix race conditions in enforcing the Veriexec rename and remove
policies. These are NOT security issues.
- Fix memory leak in rename handling when overwriting a monitored
file.
- Fix table deletion logic.
- Don't prevent query requests if not in learning mode.
KPI updates:
- fileassoc_table_run() now takes a cookie to pass to the callback.
- veriexec_table_add() was removed, it is now done internally. As a
result, there's no longer a need for VERIEXEC_TABLESIZE.
- veriexec_report() was removed, it is now internal.
- Perform sanity checks on the entry type, and enforce default type
in veriexec_file_add() rather than in veriexecctl.
- Add veriexec_flush(), used to delete all Veriexec tables, and
veriexec_dump(), used to fill an array with all Veriexec entries.
New features:
- Add a '-k' flag to veriexecctl, to keep the filenames in the kernel
database. This allows Veriexec to produce slightly more accurate
logs under certain circumstances. In the future, this can be either
replaced by vnode->pathname translation, or combined with it.
- Add a VERIEXEC_DUMP ioctl, to dump the entire Veriexec database.
This can be used to recover a database if the file was lost.
Example usage:
# veriexecctl dump > /etc/signatures
Note that only entries with the filename kept (that is, were loaded
with the '-k' flag) will be dumped.
Idea from Brett Lymn.
- Add a VERIEXEC_FLUSH ioctl, to delete all Veriexec entries. Sample
usage:
# veriexecctl flush
- Add a 'veriexec_flags' rc(8) variable, and make its default have
the '-k' flag. On systems using the default signatures file
(generaetd from running 'veriexecgen' with no arguments), this will
use additional 32kb of kernel memory on average.
- Add a '-e' flag to veriexecctl, to evaluate the fingerprint during
load. This is done automatically for files marked as 'untrusted'.
Misc. stuff:
- The code for veriexecctl was massively simplified as a result of
eliminating the need for VERIEXEC_TABLESIZE, and now uses a single
pass of the signatures file, making the loading somewhat faster.
- Lots of minor fixes found using the (still under development)
Veriexec regression testsuite.
- Some of the messages Veriexec prints were improved.
- Various documentation fixes.
All relevant man-pages were updated to reflect the above changes.
Binary compatibility with existing veriexecctl binaries is maintained.
2007-05-15 23:47:43 +04:00
|
|
|
|
2012-10-12 06:37:20 +04:00
|
|
|
f2_len = tnd.ni_cnd.cn_namelen + 1;
|
2009-01-17 10:02:35 +03:00
|
|
|
f2 = kmem_alloc(f2_len, KM_SLEEP);
|
2012-10-12 06:37:20 +04:00
|
|
|
strlcpy(f2, tnd.ni_cnd.cn_nameptr, f2_len);
|
Some Veriexec stuff that's been rotting in my tree for months.
Bug fixes:
- Fix crash reported by Scott Ellis on current-users@.
- Fix race conditions in enforcing the Veriexec rename and remove
policies. These are NOT security issues.
- Fix memory leak in rename handling when overwriting a monitored
file.
- Fix table deletion logic.
- Don't prevent query requests if not in learning mode.
KPI updates:
- fileassoc_table_run() now takes a cookie to pass to the callback.
- veriexec_table_add() was removed, it is now done internally. As a
result, there's no longer a need for VERIEXEC_TABLESIZE.
- veriexec_report() was removed, it is now internal.
- Perform sanity checks on the entry type, and enforce default type
in veriexec_file_add() rather than in veriexecctl.
- Add veriexec_flush(), used to delete all Veriexec tables, and
veriexec_dump(), used to fill an array with all Veriexec entries.
New features:
- Add a '-k' flag to veriexecctl, to keep the filenames in the kernel
database. This allows Veriexec to produce slightly more accurate
logs under certain circumstances. In the future, this can be either
replaced by vnode->pathname translation, or combined with it.
- Add a VERIEXEC_DUMP ioctl, to dump the entire Veriexec database.
This can be used to recover a database if the file was lost.
Example usage:
# veriexecctl dump > /etc/signatures
Note that only entries with the filename kept (that is, were loaded
with the '-k' flag) will be dumped.
Idea from Brett Lymn.
- Add a VERIEXEC_FLUSH ioctl, to delete all Veriexec entries. Sample
usage:
# veriexecctl flush
- Add a 'veriexec_flags' rc(8) variable, and make its default have
the '-k' flag. On systems using the default signatures file
(generaetd from running 'veriexecgen' with no arguments), this will
use additional 32kb of kernel memory on average.
- Add a '-e' flag to veriexecctl, to evaluate the fingerprint during
load. This is done automatically for files marked as 'untrusted'.
Misc. stuff:
- The code for veriexecctl was massively simplified as a result of
eliminating the need for VERIEXEC_TABLESIZE, and now uses a single
pass of the signatures file, making the loading somewhat faster.
- Lots of minor fixes found using the (still under development)
Veriexec regression testsuite.
- Some of the messages Veriexec prints were improved.
- Various documentation fixes.
All relevant man-pages were updated to reflect the above changes.
Binary compatibility with existing veriexecctl binaries is maintained.
2007-05-15 23:47:43 +04:00
|
|
|
|
2011-06-11 07:00:19 +04:00
|
|
|
error = veriexec_renamechk(curlwp, fvp, f1, tvp, f2);
|
Some Veriexec stuff that's been rotting in my tree for months.
Bug fixes:
- Fix crash reported by Scott Ellis on current-users@.
- Fix race conditions in enforcing the Veriexec rename and remove
policies. These are NOT security issues.
- Fix memory leak in rename handling when overwriting a monitored
file.
- Fix table deletion logic.
- Don't prevent query requests if not in learning mode.
KPI updates:
- fileassoc_table_run() now takes a cookie to pass to the callback.
- veriexec_table_add() was removed, it is now done internally. As a
result, there's no longer a need for VERIEXEC_TABLESIZE.
- veriexec_report() was removed, it is now internal.
- Perform sanity checks on the entry type, and enforce default type
in veriexec_file_add() rather than in veriexecctl.
- Add veriexec_flush(), used to delete all Veriexec tables, and
veriexec_dump(), used to fill an array with all Veriexec entries.
New features:
- Add a '-k' flag to veriexecctl, to keep the filenames in the kernel
database. This allows Veriexec to produce slightly more accurate
logs under certain circumstances. In the future, this can be either
replaced by vnode->pathname translation, or combined with it.
- Add a VERIEXEC_DUMP ioctl, to dump the entire Veriexec database.
This can be used to recover a database if the file was lost.
Example usage:
# veriexecctl dump > /etc/signatures
Note that only entries with the filename kept (that is, were loaded
with the '-k' flag) will be dumped.
Idea from Brett Lymn.
- Add a VERIEXEC_FLUSH ioctl, to delete all Veriexec entries. Sample
usage:
# veriexecctl flush
- Add a 'veriexec_flags' rc(8) variable, and make its default have
the '-k' flag. On systems using the default signatures file
(generaetd from running 'veriexecgen' with no arguments), this will
use additional 32kb of kernel memory on average.
- Add a '-e' flag to veriexecctl, to evaluate the fingerprint during
load. This is done automatically for files marked as 'untrusted'.
Misc. stuff:
- The code for veriexecctl was massively simplified as a result of
eliminating the need for VERIEXEC_TABLESIZE, and now uses a single
pass of the signatures file, making the loading somewhat faster.
- Lots of minor fixes found using the (still under development)
Veriexec regression testsuite.
- Some of the messages Veriexec prints were improved.
- Various documentation fixes.
All relevant man-pages were updated to reflect the above changes.
Binary compatibility with existing veriexecctl binaries is maintained.
2007-05-15 23:47:43 +04:00
|
|
|
|
2009-01-17 10:02:35 +03:00
|
|
|
kmem_free(f1, f1_len);
|
|
|
|
kmem_free(f2, f2_len);
|
2012-10-12 06:37:20 +04:00
|
|
|
|
|
|
|
if (error)
|
|
|
|
goto abort3;
|
2006-12-24 11:54:55 +03:00
|
|
|
}
|
2006-07-22 14:34:26 +04:00
|
|
|
#endif /* NVERIEXEC > 0 */
|
2005-08-19 16:30:02 +04:00
|
|
|
|
2012-10-12 06:37:20 +04:00
|
|
|
/*
|
|
|
|
* All ready. Incant the rename vop.
|
|
|
|
*/
|
|
|
|
/* XXX KASSERT(VOP_ISLOCKED(fdvp) != LK_EXCLUSIVE); */
|
|
|
|
/* XXX KASSERT(VOP_ISLOCKED(fvp) != LK_EXCLUSIVE); */
|
|
|
|
KASSERT(VOP_ISLOCKED(tdvp) == LK_EXCLUSIVE);
|
|
|
|
KASSERT((tvp == NULL) || (VOP_ISLOCKED(tvp) == LK_EXCLUSIVE));
|
|
|
|
error = VOP_RENAME(fdvp, fvp, &fnd.ni_cnd, tdvp, tvp, &tnd.ni_cnd);
|
|
|
|
|
|
|
|
/*
|
|
|
|
* VOP_RENAME releases fdvp, fvp, tdvp, and tvp, and unlocks
|
|
|
|
* tdvp and tvp. But we can't assert any of that.
|
|
|
|
*/
|
|
|
|
/* XXX KASSERT(VOP_ISLOCKED(fdvp) != LK_EXCLUSIVE); */
|
|
|
|
/* XXX KASSERT(VOP_ISLOCKED(fvp) != LK_EXCLUSIVE); */
|
|
|
|
/* XXX KASSERT(VOP_ISLOCKED(tdvp) != LK_EXCLUSIVE); */
|
|
|
|
/* XXX KASSERT((tvp == NULL) || (VOP_ISLOCKED(tvp) != LK_EXCLUSIVE)); */
|
|
|
|
|
|
|
|
/*
|
|
|
|
* So all we have left to do is to drop the rename lock and
|
|
|
|
* destroy the pathbufs.
|
|
|
|
*/
|
2012-10-19 06:07:22 +04:00
|
|
|
VFS_RENAMELOCK_EXIT(mp);
|
2012-10-12 06:37:20 +04:00
|
|
|
goto out2;
|
|
|
|
|
|
|
|
abort3: if ((tvp != NULL) && (tvp != tdvp))
|
|
|
|
VOP_UNLOCK(tvp);
|
|
|
|
abort2: VOP_UNLOCK(tdvp);
|
2012-10-19 06:07:22 +04:00
|
|
|
VFS_RENAMELOCK_EXIT(mp);
|
2012-10-12 06:37:20 +04:00
|
|
|
abort1: VOP_ABORTOP(tdvp, &tnd.ni_cnd);
|
|
|
|
vrele(tdvp);
|
|
|
|
if (tvp != NULL)
|
|
|
|
vrele(tvp);
|
|
|
|
abort0: VOP_ABORTOP(fdvp, &fnd.ni_cnd);
|
|
|
|
vrele(fdvp);
|
|
|
|
vrele(fvp);
|
|
|
|
out2: pathbuf_destroy(tpb);
|
|
|
|
out1: pathbuf_destroy(fpb);
|
|
|
|
out0: return error;
|
1994-06-29 10:29:24 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Make a directory file.
|
|
|
|
*/
|
|
|
|
/* ARGSUSED */
|
1996-02-04 05:17:43 +03:00
|
|
|
int
|
2007-12-21 02:02:38 +03:00
|
|
|
sys_mkdir(struct lwp *l, const struct sys_mkdir_args *uap, register_t *retval)
|
1995-09-20 01:40:36 +04:00
|
|
|
{
|
2007-12-21 02:02:38 +03:00
|
|
|
/* {
|
1996-12-22 13:21:06 +03:00
|
|
|
syscallarg(const char *) path;
|
1994-10-20 07:22:35 +03:00
|
|
|
syscallarg(int) mode;
|
2007-12-21 02:02:38 +03:00
|
|
|
} */
|
2009-07-02 16:53:47 +04:00
|
|
|
|
Add most system calls for POSIX extended API set, part 2, with test cases:
faccessat(2), fchmodat(2), fchownat(2), fstatat(2), mkdirat(2), mkfifoat(2),
mknodat(2), linkat(2), readlinkat(2), symlinkat(2), renameat(2), unlinkat(2),
utimensat(2), openat(2).
Also implement O_SEARCH for openat(2)
Still missing:
- some flags for openat(2)
- fexecve(2) implementation
2012-11-18 21:41:51 +04:00
|
|
|
return do_sys_mkdirat(l, AT_FDCWD, SCARG(uap, path),
|
|
|
|
SCARG(uap, mode), UIO_USERSPACE);
|
2009-07-02 16:53:47 +04:00
|
|
|
}
|
|
|
|
|
2011-08-08 16:08:52 +04:00
|
|
|
int
|
|
|
|
sys_mkdirat(struct lwp *l, const struct sys_mkdirat_args *uap,
|
|
|
|
register_t *retval)
|
|
|
|
{
|
|
|
|
/* {
|
|
|
|
syscallarg(int) fd;
|
|
|
|
syscallarg(const char *) path;
|
|
|
|
syscallarg(int) mode;
|
|
|
|
} */
|
|
|
|
|
Add most system calls for POSIX extended API set, part 2, with test cases:
faccessat(2), fchmodat(2), fchownat(2), fstatat(2), mkdirat(2), mkfifoat(2),
mknodat(2), linkat(2), readlinkat(2), symlinkat(2), renameat(2), unlinkat(2),
utimensat(2), openat(2).
Also implement O_SEARCH for openat(2)
Still missing:
- some flags for openat(2)
- fexecve(2) implementation
2012-11-18 21:41:51 +04:00
|
|
|
return do_sys_mkdirat(l, SCARG(uap, fd), SCARG(uap, path),
|
|
|
|
SCARG(uap, mode), UIO_USERSPACE);
|
2011-08-08 16:08:52 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2009-07-02 16:53:47 +04:00
|
|
|
int
|
2009-08-10 02:49:00 +04:00
|
|
|
do_sys_mkdir(const char *path, mode_t mode, enum uio_seg seg)
|
Add most system calls for POSIX extended API set, part 2, with test cases:
faccessat(2), fchmodat(2), fchownat(2), fstatat(2), mkdirat(2), mkfifoat(2),
mknodat(2), linkat(2), readlinkat(2), symlinkat(2), renameat(2), unlinkat(2),
utimensat(2), openat(2).
Also implement O_SEARCH for openat(2)
Still missing:
- some flags for openat(2)
- fexecve(2) implementation
2012-11-18 21:41:51 +04:00
|
|
|
{
|
|
|
|
return do_sys_mkdirat(NULL, AT_FDCWD, path, mode, UIO_USERSPACE);
|
|
|
|
}
|
|
|
|
|
|
|
|
static int
|
|
|
|
do_sys_mkdirat(struct lwp *l, int fdat, const char *path, mode_t mode,
|
|
|
|
enum uio_seg seg)
|
2009-07-02 16:53:47 +04:00
|
|
|
{
|
|
|
|
struct proc *p = curlwp->l_proc;
|
2000-03-30 13:27:11 +04:00
|
|
|
struct vnode *vp;
|
1994-06-29 10:29:24 +04:00
|
|
|
struct vattr vattr;
|
|
|
|
int error;
|
2010-11-19 09:44:33 +03:00
|
|
|
struct pathbuf *pb;
|
1994-06-29 10:29:24 +04:00
|
|
|
struct nameidata nd;
|
|
|
|
|
Add most system calls for POSIX extended API set, part 2, with test cases:
faccessat(2), fchmodat(2), fchownat(2), fstatat(2), mkdirat(2), mkfifoat(2),
mknodat(2), linkat(2), readlinkat(2), symlinkat(2), renameat(2), unlinkat(2),
utimensat(2), openat(2).
Also implement O_SEARCH for openat(2)
Still missing:
- some flags for openat(2)
- fexecve(2) implementation
2012-11-18 21:41:51 +04:00
|
|
|
KASSERT(l != NULL || fdat == AT_FDCWD);
|
|
|
|
|
2010-11-19 09:44:33 +03:00
|
|
|
/* XXX bollocks, should pass in a pathbuf */
|
|
|
|
error = pathbuf_maybe_copyin(path, seg, &pb);
|
|
|
|
if (error) {
|
|
|
|
return error;
|
|
|
|
}
|
|
|
|
|
|
|
|
NDINIT(&nd, CREATE, LOCKPARENT | CREATEDIR | TRYEMULROOT, pb);
|
Add most system calls for POSIX extended API set, part 2, with test cases:
faccessat(2), fchmodat(2), fchownat(2), fstatat(2), mkdirat(2), mkfifoat(2),
mknodat(2), linkat(2), readlinkat(2), symlinkat(2), renameat(2), unlinkat(2),
utimensat(2), openat(2).
Also implement O_SEARCH for openat(2)
Still missing:
- some flags for openat(2)
- fexecve(2) implementation
2012-11-18 21:41:51 +04:00
|
|
|
|
|
|
|
if ((error = fd_nameiat(l, fdat, &nd)) != 0) {
|
2010-11-19 09:44:33 +03:00
|
|
|
pathbuf_destroy(pb);
|
1994-06-29 10:29:24 +04:00
|
|
|
return (error);
|
2010-11-19 09:44:33 +03:00
|
|
|
}
|
1994-06-29 10:29:24 +04:00
|
|
|
vp = nd.ni_vp;
|
|
|
|
if (vp != NULL) {
|
|
|
|
VOP_ABORTOP(nd.ni_dvp, &nd.ni_cnd);
|
|
|
|
if (nd.ni_dvp == vp)
|
|
|
|
vrele(nd.ni_dvp);
|
|
|
|
else
|
|
|
|
vput(nd.ni_dvp);
|
|
|
|
vrele(vp);
|
2010-11-19 09:44:33 +03:00
|
|
|
pathbuf_destroy(pb);
|
1994-06-29 10:29:24 +04:00
|
|
|
return (EEXIST);
|
|
|
|
}
|
2010-01-08 14:35:07 +03:00
|
|
|
vattr_null(&vattr);
|
1994-06-29 10:29:24 +04:00
|
|
|
vattr.va_type = VDIR;
|
2007-10-08 19:12:05 +04:00
|
|
|
/* We will read cwdi->cwdi_cmask unlocked. */
|
2009-07-02 16:53:47 +04:00
|
|
|
vattr.va_mode = (mode & ACCESSPERMS) &~ p->p_cwdi->cwdi_cmask;
|
1994-06-29 10:29:24 +04:00
|
|
|
error = VOP_MKDIR(nd.ni_dvp, &nd.ni_vp, &nd.ni_cnd, &vattr);
|
|
|
|
if (!error)
|
|
|
|
vput(nd.ni_vp);
|
2010-11-19 09:44:33 +03:00
|
|
|
pathbuf_destroy(pb);
|
1994-06-29 10:29:24 +04:00
|
|
|
return (error);
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Remove a directory file.
|
|
|
|
*/
|
|
|
|
/* ARGSUSED */
|
1996-02-04 05:17:43 +03:00
|
|
|
int
|
2007-12-21 02:02:38 +03:00
|
|
|
sys_rmdir(struct lwp *l, const struct sys_rmdir_args *uap, register_t *retval)
|
1994-06-29 10:29:24 +04:00
|
|
|
{
|
Add most system calls for POSIX extended API set, part 2, with test cases:
faccessat(2), fchmodat(2), fchownat(2), fstatat(2), mkdirat(2), mkfifoat(2),
mknodat(2), linkat(2), readlinkat(2), symlinkat(2), renameat(2), unlinkat(2),
utimensat(2), openat(2).
Also implement O_SEARCH for openat(2)
Still missing:
- some flags for openat(2)
- fexecve(2) implementation
2012-11-18 21:41:51 +04:00
|
|
|
return do_sys_unlinkat(l, AT_FDCWD, SCARG(uap, path),
|
|
|
|
AT_REMOVEDIR, UIO_USERSPACE);
|
1994-06-29 10:29:24 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Read a block of directory entries in a file system independent format.
|
|
|
|
*/
|
1996-02-04 05:17:43 +03:00
|
|
|
int
|
2007-12-21 02:02:38 +03:00
|
|
|
sys___getdents30(struct lwp *l, const struct sys___getdents30_args *uap, register_t *retval)
|
1995-09-20 01:40:36 +04:00
|
|
|
{
|
2007-12-21 02:02:38 +03:00
|
|
|
/* {
|
1994-10-20 07:22:35 +03:00
|
|
|
syscallarg(int) fd;
|
|
|
|
syscallarg(char *) buf;
|
1997-10-10 06:09:30 +04:00
|
|
|
syscallarg(size_t) count;
|
2007-12-21 02:02:38 +03:00
|
|
|
} */
|
2008-03-22 00:54:58 +03:00
|
|
|
file_t *fp;
|
1997-10-10 06:09:30 +04:00
|
|
|
int error, done;
|
1994-06-29 10:29:24 +04:00
|
|
|
|
2008-03-22 00:54:58 +03:00
|
|
|
/* fd_getvnode() will use the descriptor for us */
|
|
|
|
if ((error = fd_getvnode(SCARG(uap, fd), &fp)) != 0)
|
1994-06-29 10:29:24 +04:00
|
|
|
return (error);
|
1999-05-06 00:01:01 +04:00
|
|
|
if ((fp->f_flag & FREAD) == 0) {
|
|
|
|
error = EBADF;
|
|
|
|
goto out;
|
|
|
|
}
|
1997-10-10 06:09:30 +04:00
|
|
|
error = vn_readdir(fp, SCARG(uap, buf), UIO_USERSPACE,
|
2005-12-11 15:16:03 +03:00
|
|
|
SCARG(uap, count), &done, l, 0, 0);
|
2007-08-15 16:07:23 +04:00
|
|
|
ktrgenio(SCARG(uap, fd), UIO_READ, SCARG(uap, buf), done, error);
|
1997-10-10 06:09:30 +04:00
|
|
|
*retval = done;
|
1999-05-06 00:01:01 +04:00
|
|
|
out:
|
2008-03-22 00:54:58 +03:00
|
|
|
fd_putfile(SCARG(uap, fd));
|
1994-06-29 10:29:24 +04:00
|
|
|
return (error);
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Set the mode mask for creation of filesystem nodes.
|
|
|
|
*/
|
1995-09-20 01:40:36 +04:00
|
|
|
int
|
2007-12-21 02:02:38 +03:00
|
|
|
sys_umask(struct lwp *l, const struct sys_umask_args *uap, register_t *retval)
|
1994-06-29 10:29:24 +04:00
|
|
|
{
|
2007-12-21 02:02:38 +03:00
|
|
|
/* {
|
1997-10-19 07:29:20 +04:00
|
|
|
syscallarg(mode_t) newmask;
|
2007-12-21 02:02:38 +03:00
|
|
|
} */
|
2003-01-18 13:06:22 +03:00
|
|
|
struct proc *p = l->l_proc;
|
1999-04-30 22:42:58 +04:00
|
|
|
struct cwdinfo *cwdi;
|
1994-06-29 10:29:24 +04:00
|
|
|
|
2007-10-08 19:12:05 +04:00
|
|
|
/*
|
|
|
|
* cwdi->cwdi_cmask will be read unlocked elsewhere. What's
|
|
|
|
* important is that we serialize changes to the mask. The
|
|
|
|
* rw_exit() will issue a write memory barrier on our behalf,
|
|
|
|
* and force the changes out to other CPUs (as it must use an
|
|
|
|
* atomic operation, draining the local CPU's store buffers).
|
|
|
|
*/
|
1999-04-30 22:42:58 +04:00
|
|
|
cwdi = p->p_cwdi;
|
2007-10-08 19:12:05 +04:00
|
|
|
rw_enter(&cwdi->cwdi_lock, RW_WRITER);
|
1999-04-30 22:42:58 +04:00
|
|
|
*retval = cwdi->cwdi_cmask;
|
|
|
|
cwdi->cwdi_cmask = SCARG(uap, newmask) & ALLPERMS;
|
2007-10-08 19:12:05 +04:00
|
|
|
rw_exit(&cwdi->cwdi_lock);
|
|
|
|
|
1994-06-29 10:29:24 +04:00
|
|
|
return (0);
|
|
|
|
}
|
|
|
|
|
2008-01-09 11:18:12 +03:00
|
|
|
int
|
|
|
|
dorevoke(struct vnode *vp, kauth_cred_t cred)
|
|
|
|
{
|
|
|
|
struct vattr vattr;
|
2012-03-13 22:40:26 +04:00
|
|
|
int error, fs_decision;
|
2008-01-09 11:18:12 +03:00
|
|
|
|
2011-10-14 13:23:28 +04:00
|
|
|
vn_lock(vp, LK_SHARED | LK_RETRY);
|
|
|
|
error = VOP_GETATTR(vp, &vattr, cred);
|
|
|
|
VOP_UNLOCK(vp);
|
|
|
|
if (error != 0)
|
2008-01-24 20:32:52 +03:00
|
|
|
return error;
|
2012-03-13 22:40:26 +04:00
|
|
|
fs_decision = (kauth_cred_geteuid(cred) == vattr.va_uid) ? 0 : EPERM;
|
|
|
|
error = kauth_authorize_vnode(cred, KAUTH_VNODE_REVOKE, vp, NULL,
|
|
|
|
fs_decision);
|
|
|
|
if (!error)
|
2008-01-09 11:18:12 +03:00
|
|
|
VOP_REVOKE(vp, REVOKEALL);
|
|
|
|
return (error);
|
|
|
|
}
|
|
|
|
|
1994-06-29 10:29:24 +04:00
|
|
|
/*
|
|
|
|
* Void all references to file by ripping underlying filesystem
|
|
|
|
* away from vnode.
|
|
|
|
*/
|
|
|
|
/* ARGSUSED */
|
1996-02-04 05:17:43 +03:00
|
|
|
int
|
2007-12-21 02:02:38 +03:00
|
|
|
sys_revoke(struct lwp *l, const struct sys_revoke_args *uap, register_t *retval)
|
1994-06-29 10:29:24 +04:00
|
|
|
{
|
2007-12-21 02:02:38 +03:00
|
|
|
/* {
|
1996-12-22 13:21:06 +03:00
|
|
|
syscallarg(const char *) path;
|
2007-12-21 02:02:38 +03:00
|
|
|
} */
|
2000-03-30 13:27:11 +04:00
|
|
|
struct vnode *vp;
|
1994-06-29 10:29:24 +04:00
|
|
|
int error;
|
|
|
|
|
Convert 67 namei call sites to use namei_simple, in these functions:
check_console, veriexecclose, veriexec_delete, veriexec_file_add,
emul_find_root, coff_load_shlib (sh3 version), coff_load_shlib,
compat_20_sys_statfs, compat_20_netbsd32_statfs,
ELFNAME2(netbsd32,probe_noteless), darwin_sys_statfs,
ibcs2_sys_statfs, ibcs2_sys_statvfs, linux_sys_uselib,
osf1_sys_statfs, sunos_sys_statfs, sunos32_sys_statfs,
ultrix_sys_statfs, do_sys_mount, fss_create_files (3 of 4),
adosfs_mount, cd9660_mount, coda_ioctl, coda_mount, ext2fs_mount,
ffs_mount, filecore_mount, hfs_mount, lfs_mount, msdosfs_mount,
ntfs_mount, sysvbfs_mount, udf_mount, union_mount, sys_chflags,
sys_lchflags, sys_chmod, sys_lchmod, sys_chown, sys_lchown,
sys___posix_chown, sys___posix_lchown, sys_link, do_sys_pstatvfs,
sys_quotactl, sys_revoke, sys_truncate, do_sys_utimes, sys_extattrctl,
sys_extattr_set_file, sys_extattr_set_link, sys_extattr_get_file,
sys_extattr_get_link, sys_extattr_delete_file,
sys_extattr_delete_link, sys_extattr_list_file, sys_extattr_list_link,
sys_setxattr, sys_lsetxattr, sys_getxattr, sys_lgetxattr,
sys_listxattr, sys_llistxattr, sys_removexattr, sys_lremovexattr
All have been scrutinized (several times, in fact) and compile-tested,
but not all have been explicitly tested in action.
XXX: While I haven't (intentionally) changed the use or nonuse of
XXX: TRYEMULROOT in any of these places, I'm not convinced all the
XXX: uses are correct; an audit might be desirable.
2009-06-29 09:08:15 +04:00
|
|
|
error = namei_simple_user(SCARG(uap, path),
|
|
|
|
NSM_FOLLOW_TRYEMULROOT, &vp);
|
|
|
|
if (error != 0)
|
1994-06-29 10:29:24 +04:00
|
|
|
return (error);
|
2008-01-09 11:18:12 +03:00
|
|
|
error = dorevoke(vp, l->l_cred);
|
1994-06-29 10:29:24 +04:00
|
|
|
vrele(vp);
|
|
|
|
return (error);
|
|
|
|
}
|