Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F102006850
D35543.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
14 KB
Referenced Files
None
Subscribers
None
D35543.diff
View Options
diff --git a/sys/kern/vfs_extattr.c b/sys/kern/vfs_extattr.c
--- a/sys/kern/vfs_extattr.c
+++ b/sys/kern/vfs_extattr.c
@@ -49,15 +49,15 @@
#include <security/audit/audit.h>
#include <security/mac/mac_framework.h>
-static int kern_extattr_set_path(struct thread *td, const char *path,
+static int user_extattr_set_path(struct thread *td, const char *path,
int attrnamespace, const char *attrname, void *data,
size_t nbytes, int follow);
-static int kern_extattr_get_path(struct thread *td, const char *path,
+static int user_extattr_get_path(struct thread *td, const char *path,
int attrnamespace, const char *attrname, void *data,
size_t nbytes, int follow);
-static int kern_extattr_delete_path(struct thread *td, const char *path,
+static int user_extattr_delete_path(struct thread *td, const char *path,
int attrnamespace, const char *attrname, int follow);
-static int kern_extattr_list_path(struct thread *td, const char *path,
+static int user_extattr_list_path(struct thread *td, const char *path,
int attrnamespace, void *data, size_t nbytes, int follow);
/*
@@ -232,25 +232,35 @@
int
sys_extattr_set_fd(struct thread *td, struct extattr_set_fd_args *uap)
{
- struct file *fp;
char attrname[EXTATTR_MAXNAMELEN + 1];
- cap_rights_t rights;
int error;
- AUDIT_ARG_FD(uap->fd);
- AUDIT_ARG_VALUE(uap->attrnamespace);
error = copyinstr(uap->attrname, attrname, sizeof(attrname), NULL);
if (error)
return (error);
+ return (kern_extattr_set_fd(td, uap->fd, uap->attrnamespace,
+ attrname, uap->data, uap->nbytes));
+}
+
+int
+kern_extattr_set_fd(struct thread *td, int fd, int attrnamespace,
+ const char *attrname, void *data, size_t nbytes)
+{
+ struct file *fp;
+ cap_rights_t rights;
+ int error;
+
+ AUDIT_ARG_FD(fd);
+ AUDIT_ARG_VALUE(attrnamespace);
AUDIT_ARG_TEXT(attrname);
- error = getvnode_path(td, uap->fd,
+ error = getvnode_path(td, fd,
cap_rights_init_one(&rights, CAP_EXTATTR_SET), &fp);
if (error)
return (error);
- error = extattr_set_vp(fp->f_vnode, uap->attrnamespace,
- attrname, uap->data, uap->nbytes, td);
+ error = extattr_set_vp(fp->f_vnode, attrnamespace,
+ attrname, data, nbytes, td);
fdrop(fp, td);
return (error);
@@ -269,7 +279,7 @@
sys_extattr_set_file(struct thread *td, struct extattr_set_file_args *uap)
{
- return (kern_extattr_set_path(td, uap->path, uap->attrnamespace,
+ return (user_extattr_set_path(td, uap->path, uap->attrnamespace,
uap->attrname, uap->data, uap->nbytes, FOLLOW));
}
@@ -286,25 +296,36 @@
sys_extattr_set_link(struct thread *td, struct extattr_set_link_args *uap)
{
- return (kern_extattr_set_path(td, uap->path, uap->attrnamespace,
+ return (user_extattr_set_path(td, uap->path, uap->attrnamespace,
uap->attrname, uap->data, uap->nbytes, NOFOLLOW));
}
static int
-kern_extattr_set_path(struct thread *td, const char *path, int attrnamespace,
+user_extattr_set_path(struct thread *td, const char *path, int attrnamespace,
const char *uattrname, void *data, size_t nbytes, int follow)
{
- struct nameidata nd;
char attrname[EXTATTR_MAXNAMELEN + 1];
int error;
- AUDIT_ARG_VALUE(attrnamespace);
error = copyinstr(uattrname, attrname, sizeof(attrname), NULL);
if (error)
return (error);
+ return (kern_extattr_set_path(td, path, attrnamespace,
+ attrname, data, nbytes, follow, UIO_USERSPACE));
+}
+
+int
+kern_extattr_set_path(struct thread *td, const char *path, int attrnamespace,
+ const char *attrname, void *data, size_t nbytes, int follow,
+ enum uio_seg pathseg)
+{
+ struct nameidata nd;
+ int error;
+
+ AUDIT_ARG_VALUE(attrnamespace);
AUDIT_ARG_TEXT(attrname);
- NDINIT(&nd, LOOKUP, follow | AUDITVNODE1, UIO_USERSPACE, path);
+ NDINIT(&nd, LOOKUP, follow | AUDITVNODE1, pathseg, path);
error = namei(&nd);
if (error)
return (error);
@@ -399,25 +420,35 @@
int
sys_extattr_get_fd(struct thread *td, struct extattr_get_fd_args *uap)
{
- struct file *fp;
char attrname[EXTATTR_MAXNAMELEN + 1];
- cap_rights_t rights;
int error;
- AUDIT_ARG_FD(uap->fd);
- AUDIT_ARG_VALUE(uap->attrnamespace);
error = copyinstr(uap->attrname, attrname, sizeof(attrname), NULL);
if (error)
return (error);
+ return (kern_extattr_get_fd(td, uap->fd, uap->attrnamespace,
+ attrname, uap->data, uap->nbytes));
+}
+
+int
+kern_extattr_get_fd(struct thread *td, int fd, int attrnamespace,
+ const char *attrname, void *data, size_t nbytes)
+{
+ struct file *fp;
+ cap_rights_t rights;
+ int error;
+
+ AUDIT_ARG_FD(fd);
+ AUDIT_ARG_VALUE(attrnamespace);
AUDIT_ARG_TEXT(attrname);
- error = getvnode_path(td, uap->fd,
+ error = getvnode_path(td, fd,
cap_rights_init_one(&rights, CAP_EXTATTR_GET), &fp);
if (error)
return (error);
- error = extattr_get_vp(fp->f_vnode, uap->attrnamespace,
- attrname, uap->data, uap->nbytes, td);
+ error = extattr_get_vp(fp->f_vnode, attrnamespace,
+ attrname, data, nbytes, td);
fdrop(fp, td);
return (error);
@@ -435,7 +466,7 @@
int
sys_extattr_get_file(struct thread *td, struct extattr_get_file_args *uap)
{
- return (kern_extattr_get_path(td, uap->path, uap->attrnamespace,
+ return (user_extattr_get_path(td, uap->path, uap->attrnamespace,
uap->attrname, uap->data, uap->nbytes, FOLLOW));
}
@@ -451,25 +482,36 @@
int
sys_extattr_get_link(struct thread *td, struct extattr_get_link_args *uap)
{
- return (kern_extattr_get_path(td, uap->path, uap->attrnamespace,
+ return (user_extattr_get_path(td, uap->path, uap->attrnamespace,
uap->attrname, uap->data, uap->nbytes, NOFOLLOW));
}
static int
-kern_extattr_get_path(struct thread *td, const char *path, int attrnamespace,
+user_extattr_get_path(struct thread *td, const char *path, int attrnamespace,
const char *uattrname, void *data, size_t nbytes, int follow)
{
- struct nameidata nd;
char attrname[EXTATTR_MAXNAMELEN + 1];
int error;
- AUDIT_ARG_VALUE(attrnamespace);
error = copyinstr(uattrname, attrname, sizeof(attrname), NULL);
if (error)
return (error);
+ return (kern_extattr_get_path(td, path, attrnamespace,
+ attrname, data, nbytes, follow, UIO_USERSPACE));
+}
+
+int
+kern_extattr_get_path(struct thread *td, const char *path, int attrnamespace,
+ const char *attrname, void *data, size_t nbytes, int follow,
+ enum uio_seg pathseg)
+{
+ struct nameidata nd;
+ int error;
+
+ AUDIT_ARG_VALUE(attrnamespace);
AUDIT_ARG_TEXT(attrname);
- NDINIT(&nd, LOOKUP, follow | AUDITVNODE1, UIO_USERSPACE, path);
+ NDINIT(&nd, LOOKUP, follow | AUDITVNODE1, pathseg, path);
error = namei(&nd);
if (error)
return (error);
@@ -534,24 +576,34 @@
int
sys_extattr_delete_fd(struct thread *td, struct extattr_delete_fd_args *uap)
{
- struct file *fp;
char attrname[EXTATTR_MAXNAMELEN + 1];
- cap_rights_t rights;
int error;
- AUDIT_ARG_FD(uap->fd);
- AUDIT_ARG_VALUE(uap->attrnamespace);
error = copyinstr(uap->attrname, attrname, sizeof(attrname), NULL);
if (error)
return (error);
+ return (kern_extattr_delete_fd(td, uap->fd, uap->attrnamespace,
+ attrname));
+}
+
+int
+kern_extattr_delete_fd(struct thread *td, int fd, int attrnamespace,
+ const char *attrname)
+{
+ struct file *fp;
+ cap_rights_t rights;
+ int error;
+
+ AUDIT_ARG_FD(fd);
+ AUDIT_ARG_VALUE(attrnamespace);
AUDIT_ARG_TEXT(attrname);
- error = getvnode_path(td, uap->fd,
+ error = getvnode_path(td, fd,
cap_rights_init_one(&rights, CAP_EXTATTR_DELETE), &fp);
if (error)
return (error);
- error = extattr_delete_vp(fp->f_vnode, uap->attrnamespace,
+ error = extattr_delete_vp(fp->f_vnode, attrnamespace,
attrname, td);
fdrop(fp, td);
return (error);
@@ -568,7 +620,7 @@
sys_extattr_delete_file(struct thread *td, struct extattr_delete_file_args *uap)
{
- return (kern_extattr_delete_path(td, uap->path, uap->attrnamespace,
+ return (user_extattr_delete_path(td, uap->path, uap->attrnamespace,
uap->attrname, FOLLOW));
}
@@ -583,25 +635,35 @@
sys_extattr_delete_link(struct thread *td, struct extattr_delete_link_args *uap)
{
- return (kern_extattr_delete_path(td, uap->path, uap->attrnamespace,
+ return (user_extattr_delete_path(td, uap->path, uap->attrnamespace,
uap->attrname, NOFOLLOW));
}
-static int
-kern_extattr_delete_path(struct thread *td, const char *path, int attrnamespace,
+int
+user_extattr_delete_path(struct thread *td, const char *path, int attrnamespace,
const char *uattrname, int follow)
{
- struct nameidata nd;
char attrname[EXTATTR_MAXNAMELEN + 1];
int error;
- AUDIT_ARG_VALUE(attrnamespace);
error = copyinstr(uattrname, attrname, sizeof(attrname), NULL);
if (error)
return(error);
+ return (kern_extattr_delete_path(td, path, attrnamespace,
+ attrname, follow, UIO_USERSPACE));
+}
+
+int
+kern_extattr_delete_path(struct thread *td, const char *path, int attrnamespace,
+ const char *attrname, int follow, enum uio_seg pathseg)
+{
+ struct nameidata nd;
+ int error;
+
+ AUDIT_ARG_VALUE(attrnamespace);
AUDIT_ARG_TEXT(attrname);
- NDINIT(&nd, LOOKUP, follow | AUDITVNODE1, UIO_USERSPACE, path);
+ NDINIT(&nd, LOOKUP, follow | AUDITVNODE1, pathseg, path);
error = namei(&nd);
if (error)
return(error);
@@ -623,33 +685,19 @@
* References: vp must be a valid reference for the duration of the call
*/
static int
-extattr_list_vp(struct vnode *vp, int attrnamespace, void *data,
- size_t nbytes, struct thread *td)
+extattr_list_vp(struct vnode *vp, int attrnamespace, struct uio *auiop,
+ struct thread *td)
{
- struct uio auio, *auiop;
size_t size, *sizep;
- struct iovec aiov;
ssize_t cnt;
int error;
- if (nbytes > IOSIZE_MAX)
- return (EINVAL);
-
- auiop = NULL;
sizep = NULL;
cnt = 0;
- if (data != NULL) {
- aiov.iov_base = data;
- aiov.iov_len = nbytes;
- auio.uio_iov = &aiov;
- auio.uio_iovcnt = 1;
- auio.uio_offset = 0;
- auio.uio_resid = nbytes;
- auio.uio_rw = UIO_READ;
- auio.uio_segflg = UIO_USERSPACE;
- auio.uio_td = td;
- auiop = &auio;
- cnt = nbytes;
+ if (auiop != NULL) {
+ if (auiop->uio_resid > IOSIZE_MAX)
+ return (EINVAL);
+ cnt = auiop->uio_resid;
} else
sizep = &size;
@@ -668,7 +716,7 @@
VOP_UNLOCK(vp);
if (auiop != NULL) {
- cnt -= auio.uio_resid;
+ cnt -= auiop->uio_resid;
td->td_retval[0] = cnt;
} else
td->td_retval[0] = size;
@@ -685,20 +733,44 @@
#endif
int
sys_extattr_list_fd(struct thread *td, struct extattr_list_fd_args *uap)
+{
+ struct uio auio, *auiop;
+ struct iovec aiov;
+
+ if (uap->data != NULL) {
+ aiov.iov_base = uap->data;
+ aiov.iov_len = uap->nbytes;
+ auio.uio_iov = &aiov;
+ auio.uio_iovcnt = 1;
+ auio.uio_offset = 0;
+ auio.uio_resid = uap->nbytes;
+ auio.uio_rw = UIO_READ;
+ auio.uio_segflg = UIO_USERSPACE;
+ auio.uio_td = td;
+ auiop = &auio;
+ } else
+ auiop = NULL;
+
+ return (kern_extattr_list_fd(td, uap->fd, uap->attrnamespace,
+ auiop));
+}
+
+int
+kern_extattr_list_fd(struct thread *td, int fd, int attrnamespace,
+ struct uio *auiop)
{
struct file *fp;
cap_rights_t rights;
int error;
- AUDIT_ARG_FD(uap->fd);
- AUDIT_ARG_VALUE(uap->attrnamespace);
- error = getvnode_path(td, uap->fd,
+ AUDIT_ARG_FD(fd);
+ AUDIT_ARG_VALUE(attrnamespace);
+ error = getvnode_path(td, fd,
cap_rights_init_one(&rights, CAP_EXTATTR_LIST), &fp);
if (error)
return (error);
- error = extattr_list_vp(fp->f_vnode, uap->attrnamespace, uap->data,
- uap->nbytes, td);
+ error = extattr_list_vp(fp->f_vnode, attrnamespace, auiop, td);
fdrop(fp, td);
return (error);
@@ -716,7 +788,7 @@
sys_extattr_list_file(struct thread *td, struct extattr_list_file_args *uap)
{
- return (kern_extattr_list_path(td, uap->path, uap->attrnamespace,
+ return (user_extattr_list_path(td, uap->path, uap->attrnamespace,
uap->data, uap->nbytes, FOLLOW));
}
@@ -732,25 +804,50 @@
sys_extattr_list_link(struct thread *td, struct extattr_list_link_args *uap)
{
- return (kern_extattr_list_path(td, uap->path, uap->attrnamespace,
+ return (user_extattr_list_path(td, uap->path, uap->attrnamespace,
uap->data, uap->nbytes, NOFOLLOW));
}
static int
-kern_extattr_list_path(struct thread *td, const char *path, int attrnamespace,
+user_extattr_list_path(struct thread *td, const char *path, int attrnamespace,
void *data, size_t nbytes, int follow)
+{
+ struct uio auio, *auiop;
+ struct iovec aiov;
+
+ if (data != NULL) {
+ aiov.iov_base = data;
+ aiov.iov_len = nbytes;
+ auio.uio_iov = &aiov;
+ auio.uio_iovcnt = 1;
+ auio.uio_offset = 0;
+ auio.uio_resid = nbytes;
+ auio.uio_rw = UIO_READ;
+ auio.uio_segflg = UIO_USERSPACE;
+ auio.uio_td = td;
+ auiop = &auio;
+ } else
+ auiop = NULL;
+
+ return (kern_extattr_list_path(td, path, attrnamespace,
+ auiop, follow, UIO_USERSPACE));
+}
+
+int
+kern_extattr_list_path(struct thread *td, const char *path, int attrnamespace,
+ struct uio *auiop, int follow, enum uio_seg pathseg)
{
struct nameidata nd;
int error;
AUDIT_ARG_VALUE(attrnamespace);
- NDINIT(&nd, LOOKUP, follow | AUDITVNODE1, UIO_USERSPACE, path);
+ NDINIT(&nd, LOOKUP, follow | AUDITVNODE1, pathseg, path);
error = namei(&nd);
if (error)
return (error);
NDFREE_PNBUF(&nd);
- error = extattr_list_vp(nd.ni_vp, attrnamespace, data, nbytes, td);
+ error = extattr_list_vp(nd.ni_vp, attrnamespace, auiop, td);
vrele(nd.ni_vp);
return (error);
diff --git a/sys/sys/extattr.h b/sys/sys/extattr.h
--- a/sys/sys/extattr.h
+++ b/sys/sys/extattr.h
@@ -64,11 +64,33 @@
#ifdef _KERNEL
#include <sys/types.h>
+enum uio_seg;
+struct uio;
struct thread;
struct ucred;
struct vnode;
int extattr_check_cred(struct vnode *vp, int attrnamespace,
struct ucred *cred, struct thread *td, accmode_t accmode);
+int kern_extattr_set_path(struct thread *td, const char *path,
+ int attrnamespace, const char *attrname, void *data,
+ size_t nbytes, int follow, enum uio_seg pathseg);
+int kern_extattr_set_fd(struct thread *td, int fd, int attrnamespace,
+ const char *attrname, void *data, size_t nbytes);
+int kern_extattr_get_path(struct thread *td, const char *path,
+ int attrnamespace, const char *attrname, void *data,
+ size_t nbytes, int follow, enum uio_seg pathseg);
+int kern_extattr_get_fd(struct thread *td, int fd, int attrnamespace,
+ const char *attrname, void *data, size_t nbytes);
+int kern_extattr_delete_path(struct thread *td, const char *path,
+ int attrnamespace, const char *attrname, int follow,
+ enum uio_seg pathseg);
+int kern_extattr_delete_fd(struct thread *td, int fd, int attrnamespace,
+ const char *attrname);
+int kern_extattr_list_path(struct thread *td, const char *path,
+ int attrnamespace, struct uio *auiop, int follow,
+ enum uio_seg pathseg);
+int kern_extattr_list_fd(struct thread *td, int fd, int attrnamespace,
+ struct uio *auiop);
#else
#include <sys/cdefs.h>
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Thu, Nov 7, 11:33 AM (21 h, 59 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
14511166
Default Alt Text
D35543.diff (14 KB)
Attached To
Mode
D35543: vfs: Export exattr methods to reuse by Linuxulator
Attached
Detach File
Event Timeline
Log In to Comment