Page MenuHomeFreeBSD

D13209.id35645.diff
No OneTemporary

D13209.id35645.diff

Index: sys/amd64/linux/linux_dummy.c
===================================================================
--- sys/amd64/linux/linux_dummy.c
+++ sys/amd64/linux/linux_dummy.c
@@ -155,24 +155,3 @@
DUMMY(pkey_mprotect);
DUMMY(pkey_alloc);
DUMMY(pkey_free);
-
-#define DUMMY_XATTR(s) \
-int \
-linux_ ## s ## xattr( \
- struct thread *td, struct linux_ ## s ## xattr_args *arg) \
-{ \
- \
- return (ENOATTR); \
-}
-DUMMY_XATTR(set);
-DUMMY_XATTR(lset);
-DUMMY_XATTR(fset);
-DUMMY_XATTR(get);
-DUMMY_XATTR(lget);
-DUMMY_XATTR(fget);
-DUMMY_XATTR(list);
-DUMMY_XATTR(llist);
-DUMMY_XATTR(flist);
-DUMMY_XATTR(remove);
-DUMMY_XATTR(lremove);
-DUMMY_XATTR(fremove);
Index: sys/amd64/linux/linux_proto.h
===================================================================
--- sys/amd64/linux/linux_proto.h
+++ sys/amd64/linux/linux_proto.h
@@ -618,40 +618,70 @@
register_t dummy;
};
struct linux_setxattr_args {
- register_t dummy;
+ char path_l_[PADL_(const char *)]; const char * path; char path_r_[PADR_(const char *)];
+ char name_l_[PADL_(const char *)]; const char * name; char name_r_[PADR_(const char *)];
+ char value_l_[PADL_(void *)]; void * value; char value_r_[PADR_(void *)];
+ char size_l_[PADL_(l_size_t)]; l_size_t size; char size_r_[PADR_(l_size_t)];
+ char flags_l_[PADL_(l_int)]; l_int flags; char flags_r_[PADR_(l_int)];
};
struct linux_lsetxattr_args {
- register_t dummy;
+ char path_l_[PADL_(const char *)]; const char * path; char path_r_[PADR_(const char *)];
+ char name_l_[PADL_(const char *)]; const char * name; char name_r_[PADR_(const char *)];
+ char value_l_[PADL_(void *)]; void * value; char value_r_[PADR_(void *)];
+ char size_l_[PADL_(l_size_t)]; l_size_t size; char size_r_[PADR_(l_size_t)];
+ char flags_l_[PADL_(l_int)]; l_int flags; char flags_r_[PADR_(l_int)];
};
struct linux_fsetxattr_args {
- register_t dummy;
+ char fd_l_[PADL_(l_uint)]; l_uint fd; char fd_r_[PADR_(l_uint)];
+ char name_l_[PADL_(const char *)]; const char * name; char name_r_[PADR_(const char *)];
+ char value_l_[PADL_(void *)]; void * value; char value_r_[PADR_(void *)];
+ char size_l_[PADL_(l_size_t)]; l_size_t size; char size_r_[PADR_(l_size_t)];
+ char flags_l_[PADL_(l_int)]; l_int flags; char flags_r_[PADR_(l_int)];
};
struct linux_getxattr_args {
- register_t dummy;
+ char path_l_[PADL_(const char *)]; const char * path; char path_r_[PADR_(const char *)];
+ char name_l_[PADL_(const char *)]; const char * name; char name_r_[PADR_(const char *)];
+ char value_l_[PADL_(void *)]; void * value; char value_r_[PADR_(void *)];
+ char size_l_[PADL_(l_size_t)]; l_size_t size; char size_r_[PADR_(l_size_t)];
};
struct linux_lgetxattr_args {
- register_t dummy;
+ char path_l_[PADL_(const char *)]; const char * path; char path_r_[PADR_(const char *)];
+ char name_l_[PADL_(const char *)]; const char * name; char name_r_[PADR_(const char *)];
+ char value_l_[PADL_(void *)]; void * value; char value_r_[PADR_(void *)];
+ char size_l_[PADL_(l_size_t)]; l_size_t size; char size_r_[PADR_(l_size_t)];
};
struct linux_fgetxattr_args {
- register_t dummy;
+ char fd_l_[PADL_(l_uint)]; l_uint fd; char fd_r_[PADR_(l_uint)];
+ char name_l_[PADL_(const char *)]; const char * name; char name_r_[PADR_(const char *)];
+ char value_l_[PADL_(void *)]; void * value; char value_r_[PADR_(void *)];
+ char size_l_[PADL_(l_size_t)]; l_size_t size; char size_r_[PADR_(l_size_t)];
};
struct linux_listxattr_args {
- register_t dummy;
+ char path_l_[PADL_(const char *)]; const char * path; char path_r_[PADR_(const char *)];
+ char list_l_[PADL_(const char *)]; char * list; char list_r_[PADR_(const char *)];
+ char size_l_[PADL_(l_size_t)]; l_size_t size; char size_r_[PADR_(l_size_t)];
};
struct linux_llistxattr_args {
- register_t dummy;
+ char path_l_[PADL_(const char *)]; const char * path; char path_r_[PADR_(const char *)];
+ char list_l_[PADL_(const char *)]; char * list; char list_r_[PADR_(const char *)];
+ char size_l_[PADL_(l_size_t)]; l_size_t size; char size_r_[PADR_(l_size_t)];
};
struct linux_flistxattr_args {
- register_t dummy;
+ char fd_l_[PADL_(l_uint)]; l_uint fd; char fd_r_[PADR_(l_uint)];
+ char list_l_[PADL_(const char *)]; char * list; char list_r_[PADR_(const char *)];
+ char size_l_[PADL_(l_size_t)]; l_size_t size; char size_r_[PADR_(l_size_t)];
};
struct linux_removexattr_args {
- register_t dummy;
+ char path_l_[PADL_(const char *)]; const char * path; char path_r_[PADR_(const char *)];
+ char name_l_[PADL_(const char *)]; const char * name; char name_r_[PADR_(const char *)];
};
struct linux_lremovexattr_args {
- register_t dummy;
+ char path_l_[PADL_(const char *)]; const char * path; char path_r_[PADR_(const char *)];
+ char name_l_[PADL_(const char *)]; const char * name; char name_r_[PADR_(const char *)];
};
struct linux_fremovexattr_args {
- register_t dummy;
+ char fd_l_[PADL_(l_uint)]; l_uint fd; char fd_r_[PADR_(l_uint)];
+ char name_l_[PADL_(const char *)]; const char * name; char name_r_[PADR_(const char *)];
};
struct linux_tkill_args {
char tid_l_[PADL_(int)]; int tid; char tid_r_[PADR_(int)];
Index: sys/amd64/linux/linux_sysent.c
===================================================================
--- sys/amd64/linux/linux_sysent.c
+++ sys/amd64/linux/linux_sysent.c
@@ -205,18 +205,18 @@
{ 0, (sy_call_t *)nosys, AUE_NULL, NULL, 0, 0, 0, SY_THR_ABSENT }, /* 185 = security */
{ 0, (sy_call_t *)linux_gettid, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 186 = linux_gettid */
{ 0, (sy_call_t *)nosys, AUE_NULL, NULL, 0, 0, 0, SY_THR_ABSENT }, /* 187 = linux_readahead */
- { 0, (sy_call_t *)linux_setxattr, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 188 = linux_setxattr */
- { 0, (sy_call_t *)linux_lsetxattr, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 189 = linux_lsetxattr */
- { 0, (sy_call_t *)linux_fsetxattr, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 190 = linux_fsetxattr */
- { 0, (sy_call_t *)linux_getxattr, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 191 = linux_getxattr */
- { 0, (sy_call_t *)linux_lgetxattr, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 192 = linux_lgetxattr */
- { 0, (sy_call_t *)linux_fgetxattr, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 193 = linux_fgetxattr */
- { 0, (sy_call_t *)linux_listxattr, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 194 = linux_listxattr */
- { 0, (sy_call_t *)linux_llistxattr, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 195 = linux_llistxattr */
- { 0, (sy_call_t *)linux_flistxattr, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 196 = linux_flistxattr */
- { 0, (sy_call_t *)linux_removexattr, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 197 = linux_removexattr */
- { 0, (sy_call_t *)linux_lremovexattr, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 198 = linux_lremovexattr */
- { 0, (sy_call_t *)linux_fremovexattr, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 199 = linux_fremovexattr */
+ { AS(linux_setxattr_args), (sy_call_t *)linux_setxattr, AUE_SETXATTR, NULL, 0, 0, 0, SY_THR_STATIC }, /* 188 = linux_setxattr */
+ { AS(linux_lsetxattr_args), (sy_call_t *)linux_lsetxattr, AUE_LSETXATTR, NULL, 0, 0, 0, SY_THR_STATIC }, /* 189 = linux_lsetxattr */
+ { AS(linux_fsetxattr_args), (sy_call_t *)linux_fsetxattr, AUE_FSETXATTR, NULL, 0, 0, 0, SY_THR_STATIC }, /* 190 = linux_fsetxattr */
+ { AS(linux_getxattr_args), (sy_call_t *)linux_getxattr, AUE_GETXATTR, NULL, 0, 0, 0, SY_THR_STATIC }, /* 191 = linux_getxattr */
+ { AS(linux_lgetxattr_args), (sy_call_t *)linux_lgetxattr, AUE_LGETXATTR, NULL, 0, 0, 0, SY_THR_STATIC }, /* 192 = linux_lgetxattr */
+ { AS(linux_fgetxattr_args), (sy_call_t *)linux_fgetxattr, AUE_FGETXATTR, NULL, 0, 0, 0, SY_THR_STATIC }, /* 193 = linux_fgetxattr */
+ { AS(linux_listxattr_args), (sy_call_t *)linux_listxattr, AUE_LISTXATTR, NULL, 0, 0, 0, SY_THR_STATIC }, /* 194 = linux_listxattr */
+ { AS(linux_llistxattr_args), (sy_call_t *)linux_llistxattr, AUE_LLISTXATTR, NULL, 0, 0, 0, SY_THR_STATIC }, /* 195 = linux_llistxattr */
+ { AS(linux_flistxattr_args), (sy_call_t *)linux_flistxattr, AUE_FLISTXATTR, NULL, 0, 0, 0, SY_THR_STATIC }, /* 196 = linux_flistxattr */
+ { AS(linux_removexattr_args), (sy_call_t *)linux_removexattr, AUE_REMOVEXATTR, NULL, 0, 0, 0, SY_THR_STATIC }, /* 197 = linux_removexattr */
+ { AS(linux_lremovexattr_args), (sy_call_t *)linux_lremovexattr, AUE_LREMOVEXATTR, NULL, 0, 0, 0, SY_THR_STATIC }, /* 198 = linux_lremovexattr */
+ { AS(linux_fremovexattr_args), (sy_call_t *)linux_fremovexattr, AUE_FREMOVEXATTR, NULL, 0, 0, 0, SY_THR_STATIC }, /* 199 = linux_fremovexattr */
{ AS(linux_tkill_args), (sy_call_t *)linux_tkill, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 200 = linux_tkill */
{ AS(linux_time_args), (sy_call_t *)linux_time, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 201 = linux_time */
{ AS(linux_sys_futex_args), (sy_call_t *)linux_sys_futex, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 202 = linux_sys_futex */
Index: sys/amd64/linux/linux_sysvec.c
===================================================================
--- sys/amd64/linux/linux_sysvec.c
+++ sys/amd64/linux/linux_sysvec.c
@@ -147,7 +147,7 @@
-100,-101,-102,-103,-104,-105,-106,-107,-108,-109,
-110,-111, -40, -36,-112,-113, -39, -11, -87,-122,
-116, -66, -6, -6, -6, -6, -6, -37, -38, -9,
- -6, -6, -43, -42, -75,-125, -84, -95, -16, -74,
+ -6, -6, -43, -42, -75,-125, -84, -61, -16, -74,
-72, -67, -71
};
Index: sys/amd64/linux32/linux32_dummy.c
===================================================================
--- sys/amd64/linux32/linux32_dummy.c
+++ sys/amd64/linux32/linux32_dummy.c
@@ -163,24 +163,3 @@
DUMMY(pkey_mprotect);
DUMMY(pkey_alloc);
DUMMY(pkey_free);
-
-#define DUMMY_XATTR(s) \
-int \
-linux_ ## s ## xattr( \
- struct thread *td, struct linux_ ## s ## xattr_args *arg) \
-{ \
- \
- return (ENOATTR); \
-}
-DUMMY_XATTR(set);
-DUMMY_XATTR(lset);
-DUMMY_XATTR(fset);
-DUMMY_XATTR(get);
-DUMMY_XATTR(lget);
-DUMMY_XATTR(fget);
-DUMMY_XATTR(list);
-DUMMY_XATTR(llist);
-DUMMY_XATTR(flist);
-DUMMY_XATTR(remove);
-DUMMY_XATTR(lremove);
-DUMMY_XATTR(fremove);
Index: sys/amd64/linux32/linux32_proto.h
===================================================================
--- sys/amd64/linux32/linux32_proto.h
+++ sys/amd64/linux32/linux32_proto.h
@@ -693,40 +693,70 @@
register_t dummy;
};
struct linux_setxattr_args {
- register_t dummy;
+ char path_l_[PADL_(const char *)]; const char * path; char path_r_[PADR_(const char *)];
+ char name_l_[PADL_(const char *)]; const char * name; char name_r_[PADR_(const char *)];
+ char value_l_[PADL_(void *)]; void * value; char value_r_[PADR_(void *)];
+ char size_l_[PADL_(l_size_t)]; l_size_t size; char size_r_[PADR_(l_size_t)];
+ char flags_l_[PADL_(l_int)]; l_int flags; char flags_r_[PADR_(l_int)];
};
struct linux_lsetxattr_args {
- register_t dummy;
+ char path_l_[PADL_(const char *)]; const char * path; char path_r_[PADR_(const char *)];
+ char name_l_[PADL_(const char *)]; const char * name; char name_r_[PADR_(const char *)];
+ char value_l_[PADL_(void *)]; void * value; char value_r_[PADR_(void *)];
+ char size_l_[PADL_(l_size_t)]; l_size_t size; char size_r_[PADR_(l_size_t)];
+ char flags_l_[PADL_(l_int)]; l_int flags; char flags_r_[PADR_(l_int)];
};
struct linux_fsetxattr_args {
- register_t dummy;
+ char fd_l_[PADL_(l_uint)]; l_uint fd; char fd_r_[PADR_(l_uint)];
+ char name_l_[PADL_(const char *)]; const char * name; char name_r_[PADR_(const char *)];
+ char value_l_[PADL_(void *)]; void * value; char value_r_[PADR_(void *)];
+ char size_l_[PADL_(l_size_t)]; l_size_t size; char size_r_[PADR_(l_size_t)];
+ char flags_l_[PADL_(l_int)]; l_int flags; char flags_r_[PADR_(l_int)];
};
struct linux_getxattr_args {
- register_t dummy;
+ char path_l_[PADL_(const char *)]; const char * path; char path_r_[PADR_(const char *)];
+ char name_l_[PADL_(const char *)]; const char * name; char name_r_[PADR_(const char *)];
+ char value_l_[PADL_(void *)]; void * value; char value_r_[PADR_(void *)];
+ char size_l_[PADL_(l_size_t)]; l_size_t size; char size_r_[PADR_(l_size_t)];
};
struct linux_lgetxattr_args {
- register_t dummy;
+ char path_l_[PADL_(const char *)]; const char * path; char path_r_[PADR_(const char *)];
+ char name_l_[PADL_(const char *)]; const char * name; char name_r_[PADR_(const char *)];
+ char value_l_[PADL_(void *)]; void * value; char value_r_[PADR_(void *)];
+ char size_l_[PADL_(l_size_t)]; l_size_t size; char size_r_[PADR_(l_size_t)];
};
struct linux_fgetxattr_args {
- register_t dummy;
+ char fd_l_[PADL_(l_uint)]; l_uint fd; char fd_r_[PADR_(l_uint)];
+ char name_l_[PADL_(const char *)]; const char * name; char name_r_[PADR_(const char *)];
+ char value_l_[PADL_(void *)]; void * value; char value_r_[PADR_(void *)];
+ char size_l_[PADL_(l_size_t)]; l_size_t size; char size_r_[PADR_(l_size_t)];
};
struct linux_listxattr_args {
- register_t dummy;
+ char path_l_[PADL_(const char *)]; const char * path; char path_r_[PADR_(const char *)];
+ char list_l_[PADL_(const char *)]; char * list; char list_r_[PADR_(const char *)];
+ char size_l_[PADL_(l_size_t)]; l_size_t size; char size_r_[PADR_(l_size_t)];
};
struct linux_llistxattr_args {
- register_t dummy;
+ char path_l_[PADL_(const char *)]; const char * path; char path_r_[PADR_(const char *)];
+ char list_l_[PADL_(const char *)]; char * list; char list_r_[PADR_(const char *)];
+ char size_l_[PADL_(l_size_t)]; l_size_t size; char size_r_[PADR_(l_size_t)];
};
struct linux_flistxattr_args {
- register_t dummy;
+ char fd_l_[PADL_(l_uint)]; l_uint fd; char fd_r_[PADR_(l_uint)];
+ char list_l_[PADL_(const char *)]; char * list; char list_r_[PADR_(const char *)];
+ char size_l_[PADL_(l_size_t)]; l_size_t size; char size_r_[PADR_(l_size_t)];
};
struct linux_removexattr_args {
- register_t dummy;
+ char path_l_[PADL_(const char *)]; const char * path; char path_r_[PADR_(const char *)];
+ char name_l_[PADL_(const char *)]; const char * name; char name_r_[PADR_(const char *)];
};
struct linux_lremovexattr_args {
- register_t dummy;
+ char path_l_[PADL_(const char *)]; const char * path; char path_r_[PADR_(const char *)];
+ char name_l_[PADL_(const char *)]; const char * name; char name_r_[PADR_(const char *)];
};
struct linux_fremovexattr_args {
- register_t dummy;
+ char fd_l_[PADL_(l_uint)]; l_uint fd; char fd_r_[PADR_(l_uint)];
+ char name_l_[PADL_(const char *)]; const char * name; char name_r_[PADR_(const char *)];
};
struct linux_tkill_args {
char tid_l_[PADL_(int)]; int tid; char tid_r_[PADR_(int)];
Index: sys/amd64/linux32/linux32_sysvec.c
===================================================================
--- sys/amd64/linux32/linux32_sysvec.c
+++ sys/amd64/linux32/linux32_sysvec.c
@@ -146,7 +146,7 @@
-100,-101,-102,-103,-104,-105,-106,-107,-108,-109,
-110,-111, -40, -36,-112,-113, -39, -11, -87,-122,
-116, -66, -6, -6, -6, -6, -6, -37, -38, -9,
- -6, -6, -43, -42, -75,-125, -84, -95, -16, -74,
+ -6, -6, -43, -42, -75,-125, -84, -61, -16, -74,
-72, -67, -71
};
Index: sys/bsm/audit_kevents.h
===================================================================
--- sys/bsm/audit_kevents.h
+++ sys/bsm/audit_kevents.h
@@ -772,6 +772,10 @@
#define AUE_ISSETUGID AUE_NULL
#define AUE_LIOLISTIO AUE_NULL
#define AUE_LISTXATTR AUE_NULL
+#define AUE_LGETXATTR AUE_NULL
+#define AUE_LLISTXATTR AUE_NULL
+#define AUE_LREMOVEXATTR AUE_NULL
+#define AUE_LSETXATTR AUE_NULL
#define AUE_LSTATV AUE_NULL
#define AUE_LSTAT64 AUE_NULL
#define AUE_LSTAT64_EXTENDED AUE_NULL
Index: sys/compat/linux/linux_xattr.h
===================================================================
--- /dev/null
+++ sys/compat/linux/linux_xattr.h
@@ -0,0 +1,38 @@
+/*-
+ * Copyright (c) 2017 Fedor Uporov
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer
+ * in this position and unchanged.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ */
+
+#define XATTR_NAME_MAX EXTATTR_MAXNAMELEN /* Chars in an xattr name */
+#define XATTR_SIZE_MAX 65536 /* Size of an extended attribute value (64k). */
+
+#define XATTR_NAMESPACE_SECURITY_STRING "security"
+#define LINUX_BSD_USER_NAMESPACE EXTATTR_NAMESPACE_USER
+
+static const char linux_xattr_name_separator = '.';
+
+#define XATTR_CREATE 0x1 /* Set value, fail if attr already exists. */
+#define XATTR_REPLACE 0x2 /* Set value, fail if attr does not exist. */
Index: sys/compat/linux/linux_xattr.c
===================================================================
--- /dev/null
+++ sys/compat/linux/linux_xattr.c
@@ -0,0 +1,696 @@
+/*-
+ * Copyright (c) 2017 Fedor Uporov
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer
+ * in this position and unchanged.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ */
+
+#include "opt_compat.h"
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/capsicum.h>
+#include <sys/conf.h>
+#include <sys/dirent.h>
+#include <sys/extattr.h>
+#include <sys/fcntl.h>
+#include <sys/file.h>
+#include <sys/filedesc.h>
+#include <sys/lock.h>
+#include <sys/malloc.h>
+#include <sys/mount.h>
+#include <sys/mutex.h>
+#include <sys/namei.h>
+#include <sys/proc.h>
+#include <sys/stat.h>
+#include <sys/sx.h>
+#include <sys/syscallsubr.h>
+#include <sys/sysproto.h>
+#include <sys/tty.h>
+#include <sys/unistd.h>
+#include <sys/vnode.h>
+
+#include <security/audit/audit.h>
+
+#ifdef COMPAT_LINUX32
+#include <machine/../linux32/linux.h>
+#include <machine/../linux32/linux32_proto.h>
+#else
+#include <machine/../linux/linux.h>
+#include <machine/../linux/linux_proto.h>
+#endif
+
+#include <compat/linux/linux_util.h>
+#include <compat/linux/linux_xattr.h>
+
+static int
+linux_xattr_namespace_from_linux(const char *linux_name, int *attrnamespace,
+ const char **bsd_name)
+{
+ int prefix_len;
+
+ /*
+ * The only 'user.' linux namespace is supported for now.
+ */
+ if (bcmp(linux_name, EXTATTR_NAMESPACE_USER_STRING,
+ strlen(EXTATTR_NAMESPACE_USER_STRING)) == 0 &&
+ linux_name[strlen(EXTATTR_NAMESPACE_USER_STRING)] ==
+ linux_xattr_name_separator) {
+ *attrnamespace = EXTATTR_NAMESPACE_USER;
+ prefix_len = strlen(EXTATTR_NAMESPACE_USER_STRING) + 1;
+ *bsd_name = &linux_name[prefix_len];
+ return (0);
+ }
+
+ return (EOPNOTSUPP);
+}
+
+static int
+linux_setxattr_common(struct vnode *vp, const char *attrname,
+ char *value, size_t size, int flags, struct thread *td)
+{
+ struct mount *mp;
+ struct uio auio;
+ struct iovec aiov;
+ const char *bsd_attrname;
+ struct vattr vattr, *vap;
+ bool do_write_finish = false;
+ int attrnamespace, error;
+
+ /* Validate fs objects types. */
+ if (vp->v_type != VREG && vp->v_type != VDIR && vp->v_type != VLNK)
+ return (EPERM);
+
+ /* Validate xattr value size. */
+ if (size > XATTR_SIZE_MAX)
+ return (E2BIG);
+
+ /* Validate create/replace flags. */
+ if (flags && (flags != XATTR_CREATE && flags != XATTR_REPLACE))
+ return (EINVAL);
+
+ vn_lock(vp, LK_SHARED | LK_RETRY);
+
+ /*
+ * Check stat immutable/append flags.
+ */
+ vap = &vattr;
+ vap->va_birthtime.tv_sec = -1;
+ vap->va_birthtime.tv_nsec = 0;
+ vap->va_fsid = VNOVAL;
+ vap->va_rdev = NODEV;
+ error = VOP_GETATTR(vp, vap, NOCRED);
+ if (error)
+ goto done;
+
+ if (vap->va_flags & (IMMUTABLE | APPEND)) {
+ error = EPERM;
+ goto done;
+ }
+
+ error = linux_xattr_namespace_from_linux(attrname, &attrnamespace,
+ &bsd_attrname);
+ if (error)
+ goto done;
+
+ /*
+ * Check create/replace file flags.
+ */
+ if (flags) {
+ error = VOP_GETEXTATTR(vp, attrnamespace, bsd_attrname, NULL, NULL,
+ td->td_ucred, td);
+ if (error && error != ENOATTR)
+ goto done;
+ else if (error == ENOATTR && (flags & XATTR_REPLACE))
+ goto done;
+ else if (error == 0 && !(flags & XATTR_REPLACE)) {
+ error = EEXIST;
+ goto done;
+ }
+ }
+
+ error = vn_start_write(vp, &mp, V_WAIT | PCATCH);
+ if (error)
+ goto done;
+ else
+ do_write_finish = true;
+ vn_lock(vp, LK_TRYUPGRADE);
+
+ aiov.iov_base = value;
+ aiov.iov_len = size;
+ auio.uio_iov = &aiov;
+ auio.uio_iovcnt = 1;
+ auio.uio_offset = 0;
+ if (size > IOSIZE_MAX) {
+ error = ERANGE;
+ goto done;
+ }
+ auio.uio_resid = size;
+ auio.uio_rw = UIO_WRITE;
+ auio.uio_segflg = UIO_USERSPACE;
+ auio.uio_td = td;
+
+ error = VOP_SETEXTATTR(vp, attrnamespace, bsd_attrname, &auio,
+ td->td_ucred, td);
+
+done:
+ VOP_UNLOCK(vp, 0);
+ do_write_finish ? vn_finished_write(mp) : 0;
+ return (error);
+}
+
+int
+linux_setxattr(struct thread *td, struct linux_setxattr_args *args)
+{
+ struct nameidata nd;
+ char attrname[EXTATTR_MAXNAMELEN];
+ int error;
+
+ error = copyinstr(args->name, attrname, EXTATTR_MAXNAMELEN, NULL);
+ if (error && error == ENAMETOOLONG)
+ return (ERANGE);
+ else if (error)
+ return (error);
+
+ AUDIT_ARG_TEXT(attrname);
+
+ NDINIT(&nd, LOOKUP, FOLLOW | AUDITVNODE1, UIO_USERSPACE,
+ args->path, td);
+ error = namei(&nd);
+ if (error)
+ return (error);
+ NDFREE(&nd, NDF_ONLY_PNBUF);
+
+ error = linux_setxattr_common(nd.ni_vp, attrname, args->value,
+ args->size, args->flags, td);
+
+ vrele(nd.ni_vp);
+ return (error);
+}
+
+int
+linux_lsetxattr(struct thread *td, struct linux_lsetxattr_args *args)
+{
+ struct nameidata nd;
+ char attrname[EXTATTR_MAXNAMELEN];
+ int error;
+
+ error = copyinstr(args->name, attrname, EXTATTR_MAXNAMELEN, NULL);
+ if (error && error == ENAMETOOLONG)
+ return (ERANGE);
+ else if (error)
+ return (error);
+
+ AUDIT_ARG_TEXT(attrname);
+
+ NDINIT(&nd, LOOKUP, NOFOLLOW | AUDITVNODE1, UIO_USERSPACE,
+ args->path, td);
+ error = namei(&nd);
+ if (error)
+ return (error);
+ NDFREE(&nd, NDF_ONLY_PNBUF);
+
+ error = linux_setxattr_common(nd.ni_vp, attrname, args->value,
+ args->size, args->flags, td);
+
+ vrele(nd.ni_vp);
+ return (error);
+}
+
+int
+linux_fsetxattr(struct thread *td, struct linux_fsetxattr_args *args)
+{
+ struct file *fp;
+ char attrname[EXTATTR_MAXNAMELEN];
+ cap_rights_t rights;
+ int error;
+
+ AUDIT_ARG_FD(args->fd);
+ error = copyinstr(args->name, attrname, EXTATTR_MAXNAMELEN, NULL);
+ if (error && error == ENAMETOOLONG)
+ return (ERANGE);
+ else if (error)
+ return (error);
+
+ AUDIT_ARG_TEXT(attrname);
+
+ error = getvnode(td, args->fd,
+ cap_rights_init(&rights, CAP_EXTATTR_SET), &fp);
+ if (error)
+ return (error);
+
+ error = linux_setxattr_common(fp->f_vnode, attrname, args->value,
+ args->size, args->flags, td);
+
+ fdrop(fp, td);
+ return (error);
+}
+
+static int
+linux_getxattr_common(struct vnode *vp, const char *attrname,
+ char *value, size_t size, struct thread *td)
+{
+ struct uio auio;
+ struct iovec aiov;
+ const char *bsd_attrname;
+ size_t bsd_size = 0;
+ int attrnamespace, error;
+
+ error = linux_xattr_namespace_from_linux(attrname, &attrnamespace,
+ &bsd_attrname);
+ if (error)
+ return (error);
+
+ /*
+ * The only files and directories can have 'user.' xattrs.
+ */
+ if (attrnamespace == EXTATTR_NAMESPACE_USER &&
+ vp->v_type != VREG && vp->v_type != VDIR && vp->v_type != VLNK)
+ return (EPERM);
+
+ vn_lock(vp, LK_SHARED | LK_RETRY);
+
+ /*
+ * Request xattr value size and check that the input buffer size is
+ * not less then xattr value size.
+ */
+ error = VOP_GETEXTATTR(vp, attrnamespace, bsd_attrname, NULL, &bsd_size,
+ td->td_ucred, td);
+ if (error)
+ goto done;
+
+ if (size && bsd_size > size) {
+ error = ERANGE;
+ goto done;
+ }
+ else if(value == NULL)
+ goto done;
+
+ aiov.iov_base = value;
+ aiov.iov_len = bsd_size;
+ auio.uio_iov = &aiov;
+ auio.uio_iovcnt = 1;
+ auio.uio_offset = 0;
+ if (bsd_size > IOSIZE_MAX) {
+ error = ERANGE;
+ goto done;
+ }
+ auio.uio_resid = bsd_size;
+ auio.uio_rw = UIO_READ;
+ auio.uio_segflg = UIO_USERSPACE;
+ auio.uio_td = td;
+
+ error = VOP_GETEXTATTR(vp, attrnamespace, bsd_attrname, &auio, NULL,
+ td->td_ucred, td);
+
+done:
+ if (bsd_size)
+ td->td_retval[0] = bsd_size;
+ else
+ td->td_retval[0] = 0;
+
+ VOP_UNLOCK(vp, 0);
+ return (error);
+}
+
+int
+linux_getxattr(struct thread *td, struct linux_getxattr_args *args)
+{
+ struct nameidata nd;
+ char attrname[EXTATTR_MAXNAMELEN];
+ int error;
+
+ error = copyinstr(args->name, attrname, EXTATTR_MAXNAMELEN, NULL);
+ if (error)
+ return (error);
+ AUDIT_ARG_TEXT(attrname);
+
+ NDINIT(&nd, LOOKUP, FOLLOW | AUDITVNODE1, UIO_USERSPACE, args->path, td);
+ error = namei(&nd);
+ if (error)
+ return (error);
+ NDFREE(&nd, NDF_ONLY_PNBUF);
+
+ error = linux_getxattr_common(nd.ni_vp, attrname, args->value,
+ args->size, td);
+
+ vrele(nd.ni_vp);
+ return (error);
+}
+
+int
+linux_lgetxattr(struct thread *td, struct linux_lgetxattr_args *args)
+{
+ struct nameidata nd;
+ char attrname[EXTATTR_MAXNAMELEN];
+ int error;
+
+ error = copyinstr(args->name, attrname, EXTATTR_MAXNAMELEN, NULL);
+ if (error)
+ return (error);
+ AUDIT_ARG_TEXT(attrname);
+
+ NDINIT(&nd, LOOKUP, NOFOLLOW | AUDITVNODE1, UIO_USERSPACE, args->path, td);
+ error = namei(&nd);
+ if (error)
+ return (error);
+ NDFREE(&nd, NDF_ONLY_PNBUF);
+
+ error = linux_getxattr_common(nd.ni_vp, attrname, args->value,
+ args->size, td);
+
+ vrele(nd.ni_vp);
+ return (error);
+}
+
+int
+linux_fgetxattr(struct thread *td, struct linux_fgetxattr_args *args)
+{
+ struct file *fp;
+ char attrname[EXTATTR_MAXNAMELEN];
+ cap_rights_t rights;
+ int error;
+
+ AUDIT_ARG_FD(args->fd);
+ error = copyinstr(args->name, attrname, EXTATTR_MAXNAMELEN, NULL);
+ if (error)
+ return (error);
+ AUDIT_ARG_TEXT(attrname);
+
+ error = getvnode(td, args->fd,
+ cap_rights_init(&rights, CAP_EXTATTR_GET), &fp);
+ if (error)
+ return (error);
+
+ error = linux_getxattr_common(fp->f_vnode, attrname, args->value,
+ args->size, td);
+
+ fdrop(fp, td);
+ return (error);
+}
+
+/*
+ * This function is used to covert bsd attr names list to linux compatible.
+ * The conversion consist of the next steps:
+ * 1) Adding the terminating zero in the end of the string.
+ * 2) Removing byte with characters number.
+ * 3) Adding namespace prefix.
+ *
+ * <name0_len>name0<name1_len>name1 ...
+ * to
+ * user.name0\0user.name1\0 ...
+ *
+ * Also, this function could be used to retrieve the size
+ * of linux attr names buffer form bsd-compatible one.
+ * Let's pass the linux_buf == NULL in this case.
+ */
+static int
+linux_xattrs_names_convert_to_linux(int attrnamespace,
+ const char *bsd_buf, size_t bsd_buf_size,
+ char *linux_buf, size_t* linux_buf_size)
+{
+ const char *attrnamespace_prefix, *bsd_p;
+ char *linux_p;
+ unsigned int size;
+
+ bsd_p = bsd_buf;
+ linux_p = linux_buf;
+ size = 0;
+
+ if (linux_buf_size == NULL)
+ return (EINVAL);
+
+ *linux_buf_size = 0;
+
+ if (attrnamespace == EXTATTR_NAMESPACE_USER)
+ attrnamespace_prefix = EXTATTR_NAMESPACE_USER_STRING;
+ else if (attrnamespace == EXTATTR_NAMESPACE_SYSTEM)
+ attrnamespace_prefix = EXTATTR_NAMESPACE_SYSTEM_STRING;
+ else
+ return (EINVAL);
+
+ while (bsd_p < bsd_buf + bsd_buf_size) {
+ /* Add namespace prefix. */
+ size = strlen(attrnamespace_prefix);
+
+ /* Add separator. */
+ size += sizeof(linux_xattr_name_separator);
+
+ /* Fill the name. */
+ size += *bsd_p;
+
+ /* Add terminating zero. */
+ size += 1;
+
+ /* Fill name if linux_buf was passed. */
+ if (linux_p != NULL) {
+ snprintf(linux_p, size, "%s%c%s",
+ attrnamespace_prefix, linux_xattr_name_separator,
+ bsd_p + 1);
+ linux_p[size] = '\0';
+ linux_p += size;
+ }
+
+ bsd_p += *bsd_p;
+ bsd_p += 1;
+ *linux_buf_size += size;
+ }
+
+ return (0);
+}
+
+static int
+linux_listxattr_common(struct vnode *vp, char *buf, size_t size, struct thread *td)
+{
+ struct uio auio;
+ struct iovec aiov;
+ char *bsd_buf = NULL;
+ size_t bsd_size, linux_size;
+ int error;
+
+ vn_lock(vp, LK_EXCLUSIVE | LK_RETRY);
+
+ /*
+ * Unfortunately we should do two listxattr() calls per one system call,
+ * because it is impossible to get linux compatible xattrs list size
+ * without bsd list reading.
+ */
+ error = VOP_LISTEXTATTR(vp, LINUX_BSD_USER_NAMESPACE, NULL, &bsd_size,
+ td->td_ucred, td);
+ if (error)
+ goto done;
+
+ bsd_buf = malloc(bsd_size, M_TEMP, M_WAITOK);
+ if (bsd_buf == NULL) {
+ error = ENOMEM;
+ goto done;
+ }
+
+ aiov.iov_base = bsd_buf;
+ aiov.iov_len = bsd_size;
+ auio.uio_iov = &aiov;
+ auio.uio_iovcnt = 1;
+ auio.uio_offset = 0;
+ if (bsd_size > IOSIZE_MAX) {
+ error = ERANGE;
+ goto done;
+ }
+ auio.uio_resid = bsd_size;
+ auio.uio_rw = UIO_READ;
+ auio.uio_segflg = UIO_SYSSPACE;
+ auio.uio_td = td;
+
+ error = VOP_LISTEXTATTR(vp, LINUX_BSD_USER_NAMESPACE, &auio, NULL,
+ td->td_ucred, td);
+ if (error)
+ goto done;
+
+ error = linux_xattrs_names_convert_to_linux(LINUX_BSD_USER_NAMESPACE,
+ bsd_buf, bsd_size, buf, &linux_size);
+ if (error) {
+ td->td_retval[0] = 0;
+ } else {
+ /* Check, that we have space in the input buffer. */
+ if (size && size < linux_size) {
+ td->td_retval[0] = 0;
+ error = ERANGE;
+ } else
+ td->td_retval[0] = linux_size;
+ }
+
+done:
+ free(bsd_buf, M_TEMP);
+ VOP_UNLOCK(vp, 0);
+ return (error);
+}
+
+int
+linux_listxattr(struct thread *td, struct linux_listxattr_args *args)
+{
+ struct nameidata nd;
+ int error;
+
+ NDINIT(&nd, LOOKUP, FOLLOW | AUDITVNODE1, UIO_USERSPACE, args->path, td);
+ error = namei(&nd);
+ if (error)
+ return (error);
+ NDFREE(&nd, NDF_ONLY_PNBUF);
+
+ error = linux_listxattr_common(nd.ni_vp, args->list, args->size, td);
+
+ vrele(nd.ni_vp);
+ return (error);
+}
+
+int
+linux_llistxattr(struct thread *td, struct linux_llistxattr_args *args)
+{
+ struct nameidata nd;
+ int error;
+
+ NDINIT(&nd, LOOKUP, NOFOLLOW | AUDITVNODE1, UIO_USERSPACE, args->path,
+ td);
+ error = namei(&nd);
+ if (error)
+ return (error);
+ NDFREE(&nd, NDF_ONLY_PNBUF);
+
+ error = linux_listxattr_common(nd.ni_vp, args->list, args->size, td);
+
+ vrele(nd.ni_vp);
+ return (error);
+}
+
+int
+linux_flistxattr(struct thread *td, struct linux_flistxattr_args *args)
+{
+ struct file *fp;
+ cap_rights_t rights;
+ int error;
+
+ AUDIT_ARG_FD(args->fd);
+ error = getvnode(td, args->fd,
+ cap_rights_init(&rights, CAP_EXTATTR_LIST), &fp);
+ if (error)
+ return (error);
+
+ error = linux_listxattr_common(fp->f_vnode, args->list, args->size, td);
+
+ fdrop(fp, td);
+ return (error);
+}
+
+int
+linux_removexattr(struct thread *td, struct linux_removexattr_args *args)
+{
+ struct nameidata nd;
+ char attrname[EXTATTR_MAXNAMELEN];
+ const char *bsd_attrname;
+ int attrnamespace, error;
+
+ error = copyinstr(args->name, attrname, EXTATTR_MAXNAMELEN, NULL);
+ if (error)
+ return (error);
+ AUDIT_ARG_TEXT(attrname);
+
+ NDINIT(&nd, LOOKUP, FOLLOW | AUDITVNODE1, UIO_USERSPACE, args->path, td);
+ error = namei(&nd);
+ if (error)
+ return (error);
+ NDFREE(&nd, NDF_ONLY_PNBUF);
+
+ error = linux_xattr_namespace_from_linux(attrname, &attrnamespace,
+ &bsd_attrname);
+ if (error)
+ goto done;
+
+ error = extattr_delete_vp(nd.ni_vp, attrnamespace, bsd_attrname, td);
+
+done:
+ vrele(nd.ni_vp);
+ return (error);
+}
+
+int
+linux_lremovexattr(struct thread *td, struct linux_lremovexattr_args *args)
+{
+ struct nameidata nd;
+ char attrname[EXTATTR_MAXNAMELEN];
+ const char *bsd_attrname;
+ int attrnamespace, error;
+
+ error = copyinstr(args->name, attrname, EXTATTR_MAXNAMELEN, NULL);
+ if (error)
+ return (error);
+ AUDIT_ARG_TEXT(attrname);
+
+ NDINIT(&nd, LOOKUP, NOFOLLOW | AUDITVNODE1, UIO_USERSPACE, args->path, td);
+ error = namei(&nd);
+ if (error)
+ return (error);
+ NDFREE(&nd, NDF_ONLY_PNBUF);
+
+ error = linux_xattr_namespace_from_linux(attrname, &attrnamespace,
+ &bsd_attrname);
+ if (error)
+ goto done;
+
+ error = extattr_delete_vp(nd.ni_vp, attrnamespace, bsd_attrname, td);
+
+done:
+ vrele(nd.ni_vp);
+ return (error);
+}
+
+int
+linux_fremovexattr(struct thread *td, struct linux_fremovexattr_args *args)
+{
+ struct file *fp;
+ char attrname[EXTATTR_MAXNAMELEN];
+ cap_rights_t rights;
+ const char *bsd_attrname;
+ int attrnamespace, error;
+
+ AUDIT_ARG_FD(args->fd);
+ error = copyinstr(args->name, attrname, EXTATTR_MAXNAMELEN, NULL);
+ if (error)
+ return (error);
+ AUDIT_ARG_TEXT(attrname);
+
+ error = getvnode(td, args->fd,
+ cap_rights_init(&rights, CAP_EXTATTR_GET), &fp);
+ if (error)
+ return (error);
+
+ error = linux_xattr_namespace_from_linux(attrname, &attrnamespace,
+ &bsd_attrname);
+ if (error)
+ goto done;
+
+ error = extattr_delete_vp(fp->f_vnode, attrnamespace, bsd_attrname, td);
+
+done:
+ fdrop(fp, td);
+ return (error);
+}
Index: sys/conf/files.amd64
===================================================================
--- sys/conf/files.amd64
+++ sys/conf/files.amd64
@@ -632,6 +632,7 @@
compat/linux/linux_uid16.c optional compat_linux32
compat/linux/linux_util.c optional compat_linux32
compat/linux/linux_vdso.c optional compat_linux32
+compat/linux/linux_xattr.c optional compat_linux32
compat/linux/linux_common.c optional compat_linux32
compat/linux/linux_event.c optional compat_linux32
compat/linux/linux.c optional compat_linux32
Index: sys/conf/files.i386
===================================================================
--- sys/conf/files.i386
+++ sys/conf/files.i386
@@ -106,6 +106,7 @@
compat/linux/linux_uid16.c optional compat_linux
compat/linux/linux_util.c optional compat_linux
compat/linux/linux_vdso.c optional compat_linux
+compat/linux/linux_xattr.c optional compat_linux
compat/linux/linux.c optional compat_linux
compat/ndis/kern_ndis.c optional ndisapi pci
compat/ndis/kern_windrv.c optional ndisapi pci
Index: sys/i386/linux/linux_dummy.c
===================================================================
--- sys/i386/linux/linux_dummy.c
+++ sys/i386/linux/linux_dummy.c
@@ -159,24 +159,3 @@
DUMMY(pkey_mprotect);
DUMMY(pkey_alloc);
DUMMY(pkey_free);
-
-#define DUMMY_XATTR(s) \
-int \
-linux_ ## s ## xattr( \
- struct thread *td, struct linux_ ## s ## xattr_args *arg) \
-{ \
- \
- return (ENOATTR); \
-}
-DUMMY_XATTR(set);
-DUMMY_XATTR(lset);
-DUMMY_XATTR(fset);
-DUMMY_XATTR(get);
-DUMMY_XATTR(lget);
-DUMMY_XATTR(fget);
-DUMMY_XATTR(list);
-DUMMY_XATTR(llist);
-DUMMY_XATTR(flist);
-DUMMY_XATTR(remove);
-DUMMY_XATTR(lremove);
-DUMMY_XATTR(fremove);
Index: sys/i386/linux/linux_proto.h
===================================================================
--- sys/i386/linux/linux_proto.h
+++ sys/i386/linux/linux_proto.h
@@ -694,40 +694,70 @@
register_t dummy;
};
struct linux_setxattr_args {
- register_t dummy;
+ char path_l_[PADL_(const char *)]; const char * path; char path_r_[PADR_(const char *)];
+ char name_l_[PADL_(const char *)]; const char * name; char name_r_[PADR_(const char *)];
+ char value_l_[PADL_(void *)]; const void * value; char value_r_[PADR_(void *)];
+ char size_l_[PADL_(l_size_t)]; l_size_t size; char size_r_[PADR_(l_size_t)];
+ char flags_l_[PADL_(l_int)]; l_int flags; char flags_r_[PADR_(l_int)];
};
struct linux_lsetxattr_args {
- register_t dummy;
+ char path_l_[PADL_(const char *)]; const char * path; char path_r_[PADR_(const char *)];
+ char name_l_[PADL_(const char *)]; const char * name; char name_r_[PADR_(const char *)];
+ char value_l_[PADL_(void *)]; const void * value; char value_r_[PADR_(void *)];
+ char size_l_[PADL_(l_size_t)]; l_size_t size; char size_r_[PADR_(l_size_t)];
+ char flags_l_[PADL_(l_int)]; l_int flags; char flags_r_[PADR_(l_int)];
};
struct linux_fsetxattr_args {
- register_t dummy;
+ char fd_l_[PADL_(l_uint)]; l_uint fd; char fd_r_[PADR_(l_uint)];
+ char name_l_[PADL_(const char *)]; const char * name; char name_r_[PADR_(const char *)];
+ char value_l_[PADL_(void *)]; const void * value; char value_r_[PADR_(void *)];
+ char size_l_[PADL_(l_size_t)]; l_size_t size; char size_r_[PADR_(l_size_t)];
+ char flags_l_[PADL_(l_int)]; l_int flags; char flags_r_[PADR_(l_int)];
};
struct linux_getxattr_args {
- register_t dummy;
+ char path_l_[PADL_(const char *)]; const char * path; char path_r_[PADR_(const char *)];
+ char name_l_[PADL_(const char *)]; const char * name; char name_r_[PADR_(const char *)];
+ char value_l_[PADL_(void *)]; void * value; char value_r_[PADR_(void *)];
+ char size_l_[PADL_(l_size_t)]; l_size_t size; char size_r_[PADR_(l_size_t)];
};
struct linux_lgetxattr_args {
- register_t dummy;
+ char path_l_[PADL_(const char *)]; const char * path; char path_r_[PADR_(const char *)];
+ char name_l_[PADL_(const char *)]; const char * name; char name_r_[PADR_(const char *)];
+ char value_l_[PADL_(void *)]; void * value; char value_r_[PADR_(void *)];
+ char size_l_[PADL_(l_size_t)]; l_size_t size; char size_r_[PADR_(l_size_t)];
};
struct linux_fgetxattr_args {
- register_t dummy;
+ char fd_l_[PADL_(l_uint)]; l_uint fd; char fd_r_[PADR_(l_uint)];
+ char name_l_[PADL_(const char *)]; const char * name; char name_r_[PADR_(const char *)];
+ char value_l_[PADL_(void *)]; void * value; char value_r_[PADR_(void *)];
+ char size_l_[PADL_(l_size_t)]; l_size_t size; char size_r_[PADR_(l_size_t)];
};
struct linux_listxattr_args {
- register_t dummy;
+ char path_l_[PADL_(const char *)]; const char * path; char path_r_[PADR_(const char *)];
+ char list_l_[PADL_(const char *)]; char * list; char list_r_[PADR_(const char *)];
+ char size_l_[PADL_(l_size_t)]; l_size_t size; char size_r_[PADR_(l_size_t)];
};
struct linux_llistxattr_args {
- register_t dummy;
+ char path_l_[PADL_(const char *)]; const char * path; char path_r_[PADR_(const char *)];
+ char list_l_[PADL_(const char *)]; char * list; char list_r_[PADR_(const char *)];
+ char size_l_[PADL_(l_size_t)]; l_size_t size; char size_r_[PADR_(l_size_t)];
};
struct linux_flistxattr_args {
- register_t dummy;
+ char fd_l_[PADL_(l_uint)]; l_uint fd; char fd_r_[PADR_(l_uint)];
+ char list_l_[PADL_(const char *)]; char * list; char list_r_[PADR_(const char *)];
+ char size_l_[PADL_(l_size_t)]; l_size_t size; char size_r_[PADR_(l_size_t)];
};
struct linux_removexattr_args {
- register_t dummy;
+ char path_l_[PADL_(const char *)]; const char * path; char path_r_[PADR_(const char *)];
+ char name_l_[PADL_(const char *)]; const char * name; char name_r_[PADR_(const char *)];
};
struct linux_lremovexattr_args {
- register_t dummy;
+ char path_l_[PADL_(const char *)]; const char * path; char path_r_[PADR_(const char *)];
+ char name_l_[PADL_(const char *)]; const char * name; char name_r_[PADR_(const char *)];
};
struct linux_fremovexattr_args {
- register_t dummy;
+ char fd_l_[PADL_(l_uint)]; l_uint fd; char fd_r_[PADR_(l_uint)];
+ char name_l_[PADL_(const char *)]; const char * name; char name_r_[PADR_(const char *)];
};
struct linux_tkill_args {
char tid_l_[PADL_(int)]; int tid; char tid_r_[PADR_(int)];
Index: sys/i386/linux/linux_sysent.c
===================================================================
--- sys/i386/linux/linux_sysent.c
+++ sys/i386/linux/linux_sysent.c
@@ -243,18 +243,18 @@
{ 0, (sy_call_t *)nosys, AUE_NULL, NULL, 0, 0, 0, SY_THR_ABSENT }, /* 223 = */
{ 0, (sy_call_t *)linux_gettid, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 224 = linux_gettid */
{ 0, (sy_call_t *)nosys, AUE_NULL, NULL, 0, 0, 0, SY_THR_ABSENT }, /* 225 = linux_readahead */
- { 0, (sy_call_t *)linux_setxattr, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 226 = linux_setxattr */
- { 0, (sy_call_t *)linux_lsetxattr, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 227 = linux_lsetxattr */
- { 0, (sy_call_t *)linux_fsetxattr, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 228 = linux_fsetxattr */
- { 0, (sy_call_t *)linux_getxattr, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 229 = linux_getxattr */
- { 0, (sy_call_t *)linux_lgetxattr, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 230 = linux_lgetxattr */
- { 0, (sy_call_t *)linux_fgetxattr, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 231 = linux_fgetxattr */
- { 0, (sy_call_t *)linux_listxattr, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 232 = linux_listxattr */
- { 0, (sy_call_t *)linux_llistxattr, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 233 = linux_llistxattr */
- { 0, (sy_call_t *)linux_flistxattr, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 234 = linux_flistxattr */
- { 0, (sy_call_t *)linux_removexattr, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 235 = linux_removexattr */
- { 0, (sy_call_t *)linux_lremovexattr, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 236 = linux_lremovexattr */
- { 0, (sy_call_t *)linux_fremovexattr, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 237 = linux_fremovexattr */
+ { AS(linux_setxattr_args), (sy_call_t *)linux_setxattr, AUE_SETXATTR, NULL, 0, 0, 0, SY_THR_STATIC }, /* 226 = linux_setxattr */
+ { AS(linux_lsetxattr_args), (sy_call_t *)linux_lsetxattr, AUE_LSETXATTR, NULL, 0, 0, 0, SY_THR_STATIC }, /* 227 = linux_lsetxattr */
+ { AS(linux_fsetxattr_args), (sy_call_t *)linux_fsetxattr, AUE_FSETXATTR, NULL, 0, 0, 0, SY_THR_STATIC }, /* 228 = linux_fsetxattr */
+ { AS(linux_getxattr_args), (sy_call_t *)linux_getxattr, AUE_GETXATTR, NULL, 0, 0, 0, SY_THR_STATIC }, /* 229 = linux_getxattr */
+ { AS(linux_lgetxattr_args), (sy_call_t *)linux_lgetxattr, AUE_LGETXATTR, NULL, 0, 0, 0, SY_THR_STATIC }, /* 230 = linux_lgetxattr */
+ { AS(linux_fgetxattr_args), (sy_call_t *)linux_fgetxattr, AUE_FGETXATTR, NULL, 0, 0, 0, SY_THR_STATIC }, /* 231 = linux_fgetxattr */
+ { AS(linux_listxattr_args), (sy_call_t *)linux_listxattr, AUE_LISTXATTR, NULL, 0, 0, 0, SY_THR_STATIC }, /* 232 = linux_listxattr */
+ { AS(linux_llistxattr_args), (sy_call_t *)linux_llistxattr, AUE_LLISTXATTR, NULL, 0, 0, 0, SY_THR_STATIC }, /* 233 = linux_llistxattr */
+ { AS(linux_flistxattr_args), (sy_call_t *)linux_flistxattr, AUE_FLISTXATTR, NULL, 0, 0, 0, SY_THR_STATIC }, /* 234 = linux_flistxattr */
+ { AS(linux_removexattr_args), (sy_call_t *)linux_removexattr, AUE_REMOVEXATTR, NULL, 0, 0, 0, SY_THR_STATIC }, /* 235 = linux_removexattr */
+ { AS(linux_lremovexattr_args), (sy_call_t *)linux_lremovexattr, AUE_LREMOVEXATTR, NULL, 0, 0, 0, SY_THR_STATIC }, /* 236 = linux_lremovexattr */
+ { AS(linux_fremovexattr_args), (sy_call_t *)linux_fremovexattr, AUE_FREMOVEXATTR, NULL, 0, 0, 0, SY_THR_STATIC }, /* 237 = linux_fremovexattr */
{ AS(linux_tkill_args), (sy_call_t *)linux_tkill, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 238 = linux_tkill */
{ 0, (sy_call_t *)nosys, AUE_NULL, NULL, 0, 0, 0, SY_THR_ABSENT }, /* 239 = linux_sendfile64 */
{ AS(linux_sys_futex_args), (sy_call_t *)linux_sys_futex, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 240 = linux_sys_futex */
Index: sys/i386/linux/linux_sysvec.c
===================================================================
--- sys/i386/linux/linux_sysvec.c
+++ sys/i386/linux/linux_sysvec.c
@@ -145,7 +145,7 @@
-100,-101,-102,-103,-104,-105,-106,-107,-108,-109,
-110,-111, -40, -36,-112,-113, -39, -11, -87,-122,
-116, -66, -6, -6, -6, -6, -6, -37, -38, -9,
- -6, -6, -43, -42, -75,-125, -84, -95, -16, -74,
+ -6, -6, -43, -42, -75,-125, -84, -61, -16, -74,
-72, -67, -71
};
Index: sys/kern/vfs_extattr.c
===================================================================
--- sys/kern/vfs_extattr.c
+++ sys/kern/vfs_extattr.c
@@ -155,9 +155,9 @@
* Locks: none
* References: vp must be a valid reference for the duration of the call
*/
-static int
+int
extattr_set_vp(struct vnode *vp, int attrnamespace, const char *attrname,
- void *data, size_t nbytes, struct thread *td)
+ void *data, size_t nbytes, enum uio_seg segflg, struct thread *td)
{
struct mount *mp;
struct uio auio;
@@ -181,7 +181,7 @@
}
auio.uio_resid = nbytes;
auio.uio_rw = UIO_WRITE;
- auio.uio_segflg = UIO_USERSPACE;
+ auio.uio_segflg = segflg;
auio.uio_td = td;
cnt = nbytes;
@@ -232,7 +232,7 @@
return (error);
error = extattr_set_vp(fp->f_vnode, uap->attrnamespace,
- attrname, uap->data, uap->nbytes, td);
+ attrname, uap->data, uap->nbytes, UIO_USERSPACE, td);
fdrop(fp, td);
return (error);
@@ -267,7 +267,7 @@
NDFREE(&nd, NDF_ONLY_PNBUF);
error = extattr_set_vp(nd.ni_vp, uap->attrnamespace, attrname,
- uap->data, uap->nbytes, td);
+ uap->data, uap->nbytes, UIO_USERSPACE, td);
vrele(nd.ni_vp);
return (error);
@@ -302,7 +302,7 @@
NDFREE(&nd, NDF_ONLY_PNBUF);
error = extattr_set_vp(nd.ni_vp, uap->attrnamespace, attrname,
- uap->data, uap->nbytes, td);
+ uap->data, uap->nbytes, UIO_USERSPACE, td);
vrele(nd.ni_vp);
return (error);
@@ -318,9 +318,9 @@
* Locks: none
* References: vp must be a valid reference for the duration of the call
*/
-static int
+int
extattr_get_vp(struct vnode *vp, int attrnamespace, const char *attrname,
- void *data, size_t nbytes, struct thread *td)
+ void *data, size_t nbytes, enum uio_seg segflg, struct thread *td)
{
struct uio auio, *auiop;
struct iovec aiov;
@@ -350,7 +350,7 @@
}
auio.uio_resid = nbytes;
auio.uio_rw = UIO_READ;
- auio.uio_segflg = UIO_USERSPACE;
+ auio.uio_segflg = segflg;
auio.uio_td = td;
auiop = &auio;
cnt = nbytes;
@@ -407,7 +407,7 @@
return (error);
error = extattr_get_vp(fp->f_vnode, uap->attrnamespace,
- attrname, uap->data, uap->nbytes, td);
+ attrname, uap->data, uap->nbytes, UIO_USERSPACE, td);
fdrop(fp, td);
return (error);
@@ -441,7 +441,7 @@
NDFREE(&nd, NDF_ONLY_PNBUF);
error = extattr_get_vp(nd.ni_vp, uap->attrnamespace, attrname,
- uap->data, uap->nbytes, td);
+ uap->data, uap->nbytes, UIO_USERSPACE, td);
vrele(nd.ni_vp);
return (error);
@@ -476,7 +476,7 @@
NDFREE(&nd, NDF_ONLY_PNBUF);
error = extattr_get_vp(nd.ni_vp, uap->attrnamespace, attrname,
- uap->data, uap->nbytes, td);
+ uap->data, uap->nbytes, UIO_USERSPACE, td);
vrele(nd.ni_vp);
return (error);
@@ -492,7 +492,7 @@
* Locks: none
* References: vp must be a valid reference for the duration of the call
*/
-static int
+int
extattr_delete_vp(struct vnode *vp, int attrnamespace, const char *attrname,
struct thread *td)
{
@@ -626,9 +626,9 @@
* Locks: none
* References: vp must be a valid reference for the duration of the call
*/
-static int
+int
extattr_list_vp(struct vnode *vp, int attrnamespace, void *data,
- size_t nbytes, struct thread *td)
+ size_t nbytes, enum uio_seg segflg, struct thread *td)
{
struct uio auio, *auiop;
size_t size, *sizep;
@@ -653,7 +653,7 @@
}
auio.uio_resid = nbytes;
auio.uio_rw = UIO_READ;
- auio.uio_segflg = UIO_USERSPACE;
+ auio.uio_segflg = segflg;
auio.uio_td = td;
auiop = &auio;
cnt = nbytes;
@@ -680,7 +680,6 @@
return (error);
}
-
int
sys_extattr_list_fd(td, uap)
struct thread *td;
@@ -703,7 +702,7 @@
return (error);
error = extattr_list_vp(fp->f_vnode, uap->attrnamespace, uap->data,
- uap->nbytes, td);
+ uap->nbytes, UIO_USERSPACE, td);
fdrop(fp, td);
return (error);
@@ -730,7 +729,7 @@
NDFREE(&nd, NDF_ONLY_PNBUF);
error = extattr_list_vp(nd.ni_vp, uap->attrnamespace, uap->data,
- uap->nbytes, td);
+ uap->nbytes, UIO_USERSPACE, td);
vrele(nd.ni_vp);
return (error);
@@ -758,7 +757,7 @@
NDFREE(&nd, NDF_ONLY_PNBUF);
error = extattr_list_vp(nd.ni_vp, uap->attrnamespace, uap->data,
- uap->nbytes, td);
+ uap->nbytes, UIO_USERSPACE, td);
vrele(nd.ni_vp);
return (error);
Index: sys/modules/linux/Makefile
===================================================================
--- sys/modules/linux/Makefile
+++ sys/modules/linux/Makefile
@@ -15,7 +15,7 @@
linux${SFX}_machdep.c linux_misc.c linux_signal.c \
linux_socket.c linux_stats.c linux_sysctl.c linux${SFX}_sysent.c \
linux${SFX}_sysvec.c linux_uid16.c linux_time.c \
- linux_timer.c linux_vdso.c \
+ linux_timer.c linux_vdso.c linux_xattr.c \
opt_inet6.h opt_compat.h opt_posix.h opt_usb.h vnode_if.h \
device_if.h bus_if.h assym.s \
linux${SFX}_support.s
Index: sys/modules/linux64/Makefile
===================================================================
--- sys/modules/linux64/Makefile
+++ sys/modules/linux64/Makefile
@@ -9,7 +9,8 @@
linux_futex.c linux_getcwd.c linux_ioctl.c linux_ipc.c \
linux_machdep.c linux_misc.c linux_ptrace.c linux_signal.c \
linux_socket.c linux_stats.c linux_sysctl.c linux_sysent.c \
- linux_sysvec.c linux_time.c linux_vdso.c linux_timer.c \
+ linux_sysvec.c linux_time.c linux_timer.c linux_vdso.c \
+ linux_xattr.c \
opt_inet6.h opt_compat.h opt_posix.h opt_usb.h \
vnode_if.h device_if.h bus_if.h assym.s \
linux_support.s
Index: sys/sys/extattr.h
===================================================================
--- sys/sys/extattr.h
+++ sys/sys/extattr.h
@@ -61,13 +61,23 @@
#ifdef _KERNEL
#include <sys/types.h>
+#include <sys/uio.h>
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 extattr_delete_vp(struct vnode *vp, int attrnamespace,
+ const char *attrname, struct thread *td);
+int extattr_get_vp(struct vnode *vp, int attrnamespace,
+ const char *attrname, void *data, size_t nbytes,
+ enum uio_seg segflg, struct thread *td);
+int extattr_list_vp(struct vnode *vp, int attrnamespace, void *data,
+ size_t nbytes, enum uio_seg segflg, struct thread *td);
+int extattr_set_vp(struct vnode *vp, int attrnamespace,
+ const char *attrname, void *data, size_t nbytes,
+ enum uio_seg segflg, struct thread *td);
#else
#include <sys/cdefs.h>

File Metadata

Mime Type
text/plain
Expires
Thu, Sep 3, 1:10 PM (8 h, 16 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
38012332
Default Alt Text
D13209.id35645.diff (50 KB)

Event Timeline