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