summaryrefslogtreecommitdiffstats
path: root/sys/kern
diff options
context:
space:
mode:
Diffstat (limited to 'sys/kern')
-rw-r--r--sys/kern/syscalls.master13
-rw-r--r--sys/kern/vfs_default.c5
-rw-r--r--sys/kern/vfs_extattr.c63
-rw-r--r--sys/kern/vfs_syscalls.c63
-rw-r--r--sys/kern/vfs_vnops.c17
-rw-r--r--sys/kern/vnode_if.src2
6 files changed, 129 insertions, 34 deletions
diff --git a/sys/kern/syscalls.master b/sys/kern/syscalls.master
index 2c54df2..6e834d4 100644
--- a/sys/kern/syscalls.master
+++ b/sys/kern/syscalls.master
@@ -508,15 +508,16 @@
354 STD BSD { int __acl_aclcheck_fd(int filedes, acl_type_t type, \
struct acl *aclp); }
355 STD BSD { int extattrctl(const char *path, int cmd, \
- const char *attrname, char *arg); }
+ const char *filename, int namespace, \
+ const char *attrname); }
356 STD BSD { int extattr_set_file(const char *path, \
- const char *attrname, struct iovec *iovp, \
- unsigned iovcnt); }
+ int namespace, const char *attrname, \
+ struct iovec *iovp, unsigned iovcnt); }
357 STD BSD { int extattr_get_file(const char *path, \
- const char *attrname, struct iovec *iovp, \
- unsigned iovcnt); }
+ int namespace, const char *attrname, \
+ struct iovec *iovp, unsigned iovcnt); }
358 STD BSD { int extattr_delete_file(const char *path, \
- const char *attrname); }
+ int namespace, const char *attrname); }
359 STD BSD { int aio_waitcomplete(struct aiocb **aiocbp, struct timespec *timeout); }
360 STD BSD { int getresuid(uid_t *ruid, uid_t *euid, uid_t *suid); }
361 STD BSD { int getresgid(gid_t *rgid, gid_t *egid, gid_t *sgid); }
diff --git a/sys/kern/vfs_default.c b/sys/kern/vfs_default.c
index 3e9fc75..ee56c83 100644
--- a/sys/kern/vfs_default.c
+++ b/sys/kern/vfs_default.c
@@ -739,11 +739,12 @@ vfs_stduninit (vfsp)
}
int
-vfs_stdextattrctl(mp, cmd, attrname, arg, p)
+vfs_stdextattrctl(mp, cmd, filename_vp, namespace, attrname, p)
struct mount *mp;
int cmd;
+ struct vnode *filename_vp;
+ int namespace;
const char *attrname;
- caddr_t arg;
struct proc *p;
{
return(EOPNOTSUPP);
diff --git a/sys/kern/vfs_extattr.c b/sys/kern/vfs_extattr.c
index a6c9887..79abaf4 100644
--- a/sys/kern/vfs_extattr.c
+++ b/sys/kern/vfs_extattr.c
@@ -3681,20 +3681,65 @@ extattrctl(p, uap)
struct proc *p;
struct extattrctl_args *uap;
{
+ struct vnode *filename_vp;
struct nameidata nd;
struct mount *mp;
+ char attrname[EXTATTR_MAXNAMELEN];
int error;
+ /*
+ * SCARG(uap, attrname) not always defined. We check again later
+ * when we invoke the VFS call so as to pass in NULL there if needed.
+ */
+ if (SCARG(uap, attrname) != NULL) {
+ error = copyinstr(SCARG(uap, attrname), attrname,
+ EXTATTR_MAXNAMELEN, NULL);
+ if (error)
+ return (error);
+ }
+
+ /*
+ * SCARG(uap, filename) not always defined. If it is, grab
+ * a vnode lock, which VFS_EXTATTRCTL() will later release.
+ */
+ filename_vp = NULL;
+ if (SCARG(uap, filename) != NULL) {
+ NDINIT(&nd, LOOKUP | LOCKLEAF, FOLLOW, UIO_USERSPACE,
+ SCARG(uap, filename), p);
+ if ((error = namei(&nd)) != 0)
+ return (error);
+ filename_vp = nd.ni_vp;
+ NDFREE(&nd, NDF_NO_VP_RELE | NDF_NO_VP_UNLOCK);
+ }
+
+ /* SCARG(uap, path) always defined. */
NDINIT(&nd, LOOKUP, FOLLOW, UIO_USERSPACE, SCARG(uap, path), p);
if ((error = namei(&nd)) != 0)
return (error);
error = vn_start_write(nd.ni_vp, &mp, V_WAIT | PCATCH);
NDFREE(&nd, 0);
- if (error)
+ if (error) {
+ if (filename_vp)
+ vrele(filename_vp);
return (error);
- error = VFS_EXTATTRCTL(mp, SCARG(uap, cmd), SCARG(uap, attrname),
- SCARG(uap, arg), p);
+ }
+
+ if (SCARG(uap, attrname) != NULL) {
+ error = VFS_EXTATTRCTL(mp, SCARG(uap, cmd), filename_vp,
+ SCARG(uap, namespace), attrname, p);
+ } else {
+ error = VFS_EXTATTRCTL(mp, SCARG(uap, cmd), filename_vp,
+ SCARG(uap, namespace), NULL, p);
+ }
+
vn_finished_write(mp);
+ /*
+ * VFS_EXTATTRCTL will have unlocked, but not de-ref'd,
+ * filename_vp, so vrele it if it is defined.
+ */
+ if (filename_vp != NULL)
+ vrele(filename_vp);
+
return (error);
}
@@ -3756,8 +3801,8 @@ extattr_set_file(p, uap)
iov++;
}
cnt = auio.uio_resid;
- error = VOP_SETEXTATTR(nd.ni_vp, attrname, &auio, p->p_cred->pc_ucred,
- p);
+ error = VOP_SETEXTATTR(nd.ni_vp, SCARG(uap, namespace), attrname,
+ &auio, p->p_cred->pc_ucred, p);
cnt -= auio.uio_resid;
p->p_retval[0] = cnt;
done:
@@ -3823,8 +3868,8 @@ extattr_get_file(p, uap)
iov++;
}
cnt = auio.uio_resid;
- error = VOP_GETEXTATTR(nd.ni_vp, attrname, &auio, p->p_cred->pc_ucred,
- p);
+ error = VOP_GETEXTATTR(nd.ni_vp, SCARG(uap, namespace), attrname,
+ &auio, p->p_cred->pc_ucred, p);
cnt -= auio.uio_resid;
p->p_retval[0] = cnt;
done:
@@ -3859,8 +3904,8 @@ extattr_delete_file(p, uap)
NDFREE(&nd, 0);
return (error);
}
- error = VOP_SETEXTATTR(nd.ni_vp, attrname, NULL, p->p_cred->pc_ucred,
- p);
+ error = VOP_SETEXTATTR(nd.ni_vp, SCARG(uap, namespace), attrname,
+ NULL, p->p_cred->pc_ucred, p);
NDFREE(&nd, 0);
vn_finished_write(mp);
return(error);
diff --git a/sys/kern/vfs_syscalls.c b/sys/kern/vfs_syscalls.c
index a6c9887..79abaf4 100644
--- a/sys/kern/vfs_syscalls.c
+++ b/sys/kern/vfs_syscalls.c
@@ -3681,20 +3681,65 @@ extattrctl(p, uap)
struct proc *p;
struct extattrctl_args *uap;
{
+ struct vnode *filename_vp;
struct nameidata nd;
struct mount *mp;
+ char attrname[EXTATTR_MAXNAMELEN];
int error;
+ /*
+ * SCARG(uap, attrname) not always defined. We check again later
+ * when we invoke the VFS call so as to pass in NULL there if needed.
+ */
+ if (SCARG(uap, attrname) != NULL) {
+ error = copyinstr(SCARG(uap, attrname), attrname,
+ EXTATTR_MAXNAMELEN, NULL);
+ if (error)
+ return (error);
+ }
+
+ /*
+ * SCARG(uap, filename) not always defined. If it is, grab
+ * a vnode lock, which VFS_EXTATTRCTL() will later release.
+ */
+ filename_vp = NULL;
+ if (SCARG(uap, filename) != NULL) {
+ NDINIT(&nd, LOOKUP | LOCKLEAF, FOLLOW, UIO_USERSPACE,
+ SCARG(uap, filename), p);
+ if ((error = namei(&nd)) != 0)
+ return (error);
+ filename_vp = nd.ni_vp;
+ NDFREE(&nd, NDF_NO_VP_RELE | NDF_NO_VP_UNLOCK);
+ }
+
+ /* SCARG(uap, path) always defined. */
NDINIT(&nd, LOOKUP, FOLLOW, UIO_USERSPACE, SCARG(uap, path), p);
if ((error = namei(&nd)) != 0)
return (error);
error = vn_start_write(nd.ni_vp, &mp, V_WAIT | PCATCH);
NDFREE(&nd, 0);
- if (error)
+ if (error) {
+ if (filename_vp)
+ vrele(filename_vp);
return (error);
- error = VFS_EXTATTRCTL(mp, SCARG(uap, cmd), SCARG(uap, attrname),
- SCARG(uap, arg), p);
+ }
+
+ if (SCARG(uap, attrname) != NULL) {
+ error = VFS_EXTATTRCTL(mp, SCARG(uap, cmd), filename_vp,
+ SCARG(uap, namespace), attrname, p);
+ } else {
+ error = VFS_EXTATTRCTL(mp, SCARG(uap, cmd), filename_vp,
+ SCARG(uap, namespace), NULL, p);
+ }
+
vn_finished_write(mp);
+ /*
+ * VFS_EXTATTRCTL will have unlocked, but not de-ref'd,
+ * filename_vp, so vrele it if it is defined.
+ */
+ if (filename_vp != NULL)
+ vrele(filename_vp);
+
return (error);
}
@@ -3756,8 +3801,8 @@ extattr_set_file(p, uap)
iov++;
}
cnt = auio.uio_resid;
- error = VOP_SETEXTATTR(nd.ni_vp, attrname, &auio, p->p_cred->pc_ucred,
- p);
+ error = VOP_SETEXTATTR(nd.ni_vp, SCARG(uap, namespace), attrname,
+ &auio, p->p_cred->pc_ucred, p);
cnt -= auio.uio_resid;
p->p_retval[0] = cnt;
done:
@@ -3823,8 +3868,8 @@ extattr_get_file(p, uap)
iov++;
}
cnt = auio.uio_resid;
- error = VOP_GETEXTATTR(nd.ni_vp, attrname, &auio, p->p_cred->pc_ucred,
- p);
+ error = VOP_GETEXTATTR(nd.ni_vp, SCARG(uap, namespace), attrname,
+ &auio, p->p_cred->pc_ucred, p);
cnt -= auio.uio_resid;
p->p_retval[0] = cnt;
done:
@@ -3859,8 +3904,8 @@ extattr_delete_file(p, uap)
NDFREE(&nd, 0);
return (error);
}
- error = VOP_SETEXTATTR(nd.ni_vp, attrname, NULL, p->p_cred->pc_ucred,
- p);
+ error = VOP_SETEXTATTR(nd.ni_vp, SCARG(uap, namespace), attrname,
+ NULL, p->p_cred->pc_ucred, p);
NDFREE(&nd, 0);
vn_finished_write(mp);
return(error);
diff --git a/sys/kern/vfs_vnops.c b/sys/kern/vfs_vnops.c
index 760df67..6c8c0f9 100644
--- a/sys/kern/vfs_vnops.c
+++ b/sys/kern/vfs_vnops.c
@@ -808,8 +808,8 @@ vn_kqfilter(struct file *fp, struct knote *kn)
* Set IO_NODELOCKED in ioflg if the vnode is already locked.
*/
int
-vn_extattr_get(struct vnode *vp, int ioflg, const char *attrname, int *buflen,
- char *buf, struct proc *p)
+vn_extattr_get(struct vnode *vp, int ioflg, int namespace,
+ const char *attrname, int *buflen, char *buf, struct proc *p)
{
struct uio auio;
struct iovec iov;
@@ -830,7 +830,7 @@ vn_extattr_get(struct vnode *vp, int ioflg, const char *attrname, int *buflen,
vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, p);
/* authorize attribute retrieval as kernel */
- error = VOP_GETEXTATTR(vp, attrname, &auio, NULL, p);
+ error = VOP_GETEXTATTR(vp, namespace, attrname, &auio, NULL, p);
if ((ioflg & IO_NODELOCKED) == 0)
VOP_UNLOCK(vp, 0, p);
@@ -846,8 +846,8 @@ vn_extattr_get(struct vnode *vp, int ioflg, const char *attrname, int *buflen,
* XXX failure mode if partially written?
*/
int
-vn_extattr_set(struct vnode *vp, int ioflg, const char *attrname, int buflen,
- char *buf, struct proc *p)
+vn_extattr_set(struct vnode *vp, int ioflg, int namespace,
+ const char *attrname, int buflen, char *buf, struct proc *p)
{
struct uio auio;
struct iovec iov;
@@ -872,7 +872,7 @@ vn_extattr_set(struct vnode *vp, int ioflg, const char *attrname, int buflen,
}
/* authorize attribute setting as kernel */
- error = VOP_SETEXTATTR(vp, attrname, &auio, NULL, p);
+ error = VOP_SETEXTATTR(vp, namespace, attrname, &auio, NULL, p);
if ((ioflg & IO_NODELOCKED) == 0) {
vn_finished_write(mp);
@@ -883,7 +883,8 @@ vn_extattr_set(struct vnode *vp, int ioflg, const char *attrname, int buflen,
}
int
-vn_extattr_rm(struct vnode *vp, int ioflg, const char *attrname, struct proc *p)
+vn_extattr_rm(struct vnode *vp, int ioflg, int namespace, const char *attrname,
+ struct proc *p)
{
struct mount *mp;
int error;
@@ -895,7 +896,7 @@ vn_extattr_rm(struct vnode *vp, int ioflg, const char *attrname, struct proc *p)
}
/* authorize attribute removal as kernel */
- error = VOP_SETEXTATTR(vp, attrname, NULL, NULL, p);
+ error = VOP_SETEXTATTR(vp, namespace, attrname, NULL, NULL, p);
if ((ioflg & IO_NODELOCKED) == 0) {
vn_finished_write(mp);
diff --git a/sys/kern/vnode_if.src b/sys/kern/vnode_if.src
index 87fe31c..9cbe079 100644
--- a/sys/kern/vnode_if.src
+++ b/sys/kern/vnode_if.src
@@ -529,6 +529,7 @@ vop_aclcheck {
#
vop_getextattr {
IN struct vnode *vp;
+ IN int namespace;
IN const char *name;
INOUT struct uio *uio;
IN struct ucred *cred;
@@ -540,6 +541,7 @@ vop_getextattr {
#
vop_setextattr {
IN struct vnode *vp;
+ IN int namespace;
IN const char *name;
INOUT struct uio *uio;
IN struct ucred *cred;
OpenPOWER on IntegriCloud