1 /* 2 * 9p system.posix* xattr callback 3 * 4 * Copyright IBM, Corp. 2010 5 * 6 * Authors: 7 * Aneesh Kumar K.V <aneesh.kumar@linux.vnet.ibm.com> 8 * 9 * This work is licensed under the terms of the GNU GPL, version 2. See 10 * the COPYING file in the top-level directory. 11 * 12 */ 13 14 /* 15 * Not so fast! You might want to read the 9p developer docs first: 16 * https://wiki.qemu.org/Documentation/9p 17 */ 18 19 #include "qemu/osdep.h" 20 #include "qemu/xattr.h" 21 #include "9p.h" 22 #include "fsdev/file-op-9p.h" 23 #include "9p-xattr.h" 24 25 #define MAP_ACL_ACCESS "user.virtfs.system.posix_acl_access" 26 #define MAP_ACL_DEFAULT "user.virtfs.system.posix_acl_default" 27 #define ACL_ACCESS "system.posix_acl_access" 28 #define ACL_DEFAULT "system.posix_acl_default" 29 30 static ssize_t mp_pacl_getxattr(FsContext *ctx, const char *path, 31 const char *name, void *value, size_t size) 32 { 33 return local_getxattr_nofollow(ctx, path, MAP_ACL_ACCESS, value, size); 34 } 35 36 static ssize_t mp_pacl_listxattr(FsContext *ctx, const char *path, 37 char *name, void *value, size_t osize) 38 { 39 ssize_t len = sizeof(ACL_ACCESS); 40 41 if (!value) { 42 return len; 43 } 44 45 if (osize < len) { 46 errno = ERANGE; 47 return -1; 48 } 49 50 /* len includes the trailing NUL */ 51 memcpy(value, ACL_ACCESS, len); 52 return 0; 53 } 54 55 static int mp_pacl_setxattr(FsContext *ctx, const char *path, const char *name, 56 void *value, size_t size, int flags) 57 { 58 return local_setxattr_nofollow(ctx, path, MAP_ACL_ACCESS, value, size, 59 flags); 60 } 61 62 static int mp_pacl_removexattr(FsContext *ctx, 63 const char *path, const char *name) 64 { 65 int ret; 66 67 ret = local_removexattr_nofollow(ctx, path, MAP_ACL_ACCESS); 68 /* 69 * macOS returns ENOATTR (!=ENODATA on macOS), whereas Linux returns 70 * ENODATA (==ENOATTR on Linux), so checking for ENOATTR is fine 71 */ 72 if (ret == -1 && errno == ENOATTR) { 73 /* 74 * We don't get ENODATA error when trying to remove a 75 * posix acl that is not present. So don't throw the error 76 * even in case of mapped security model 77 */ 78 errno = 0; 79 ret = 0; 80 } 81 return ret; 82 } 83 84 static ssize_t mp_dacl_getxattr(FsContext *ctx, const char *path, 85 const char *name, void *value, size_t size) 86 { 87 return local_getxattr_nofollow(ctx, path, MAP_ACL_DEFAULT, value, size); 88 } 89 90 static ssize_t mp_dacl_listxattr(FsContext *ctx, const char *path, 91 char *name, void *value, size_t osize) 92 { 93 ssize_t len = sizeof(ACL_DEFAULT); 94 95 if (!value) { 96 return len; 97 } 98 99 if (osize < len) { 100 errno = ERANGE; 101 return -1; 102 } 103 104 /* len includes the trailing NUL */ 105 memcpy(value, ACL_DEFAULT, len); 106 return 0; 107 } 108 109 static int mp_dacl_setxattr(FsContext *ctx, const char *path, const char *name, 110 void *value, size_t size, int flags) 111 { 112 return local_setxattr_nofollow(ctx, path, MAP_ACL_DEFAULT, value, size, 113 flags); 114 } 115 116 static int mp_dacl_removexattr(FsContext *ctx, 117 const char *path, const char *name) 118 { 119 int ret; 120 121 ret = local_removexattr_nofollow(ctx, path, MAP_ACL_DEFAULT); 122 /* 123 * macOS returns ENOATTR (!=ENODATA on macOS), whereas Linux returns 124 * ENODATA (==ENOATTR on Linux), so checking for ENOATTR is fine 125 */ 126 if (ret == -1 && errno == ENOATTR) { 127 /* 128 * We don't get ENODATA error when trying to remove a 129 * posix acl that is not present. So don't throw the error 130 * even in case of mapped security model 131 */ 132 errno = 0; 133 ret = 0; 134 } 135 return ret; 136 } 137 138 139 XattrOperations mapped_pacl_xattr = { 140 .name = "system.posix_acl_access", 141 .getxattr = mp_pacl_getxattr, 142 .setxattr = mp_pacl_setxattr, 143 .listxattr = mp_pacl_listxattr, 144 .removexattr = mp_pacl_removexattr, 145 }; 146 147 XattrOperations mapped_dacl_xattr = { 148 .name = "system.posix_acl_default", 149 .getxattr = mp_dacl_getxattr, 150 .setxattr = mp_dacl_setxattr, 151 .listxattr = mp_dacl_listxattr, 152 .removexattr = mp_dacl_removexattr, 153 }; 154 155 XattrOperations passthrough_acl_xattr = { 156 .name = "system.posix_acl_", 157 .getxattr = pt_getxattr, 158 .setxattr = pt_setxattr, 159 .listxattr = pt_listxattr, 160 .removexattr = pt_removexattr, 161 }; 162 163 XattrOperations none_acl_xattr = { 164 .name = "system.posix_acl_", 165 .getxattr = notsup_getxattr, 166 .setxattr = notsup_setxattr, 167 .listxattr = notsup_listxattr, 168 .removexattr = notsup_removexattr, 169 }; 170