1 // SPDX-License-Identifier: GPL-2.0-only
2
3 #include <linux/fs.h>
4 #include <linux/xattr.h>
5 #include "overlayfs.h"
6
ovl_is_escaped_xattr(struct super_block * sb,const char * name)7 static bool ovl_is_escaped_xattr(struct super_block *sb, const char *name)
8 {
9 struct ovl_fs *ofs = sb->s_fs_info;
10
11 if (ofs->config.userxattr)
12 return strncmp(name, OVL_XATTR_ESCAPE_USER_PREFIX,
13 OVL_XATTR_ESCAPE_USER_PREFIX_LEN) == 0;
14 else
15 return strncmp(name, OVL_XATTR_ESCAPE_TRUSTED_PREFIX,
16 OVL_XATTR_ESCAPE_TRUSTED_PREFIX_LEN) == 0;
17 }
18
ovl_is_own_xattr(struct super_block * sb,const char * name)19 static bool ovl_is_own_xattr(struct super_block *sb, const char *name)
20 {
21 struct ovl_fs *ofs = OVL_FS(sb);
22
23 if (ofs->config.userxattr)
24 return strncmp(name, OVL_XATTR_USER_PREFIX,
25 OVL_XATTR_USER_PREFIX_LEN) == 0;
26 else
27 return strncmp(name, OVL_XATTR_TRUSTED_PREFIX,
28 OVL_XATTR_TRUSTED_PREFIX_LEN) == 0;
29 }
30
ovl_is_private_xattr(struct super_block * sb,const char * name)31 bool ovl_is_private_xattr(struct super_block *sb, const char *name)
32 {
33 return ovl_is_own_xattr(sb, name) && !ovl_is_escaped_xattr(sb, name);
34 }
35
ovl_xattr_set(struct dentry * dentry,struct inode * inode,const char * name,const void * value,size_t size,int flags)36 static int ovl_xattr_set(struct dentry *dentry, struct inode *inode, const char *name,
37 const void *value, size_t size, int flags)
38 {
39 int err;
40 struct ovl_fs *ofs = OVL_FS(dentry->d_sb);
41 struct dentry *upperdentry = ovl_i_dentry_upper(inode);
42 struct dentry *realdentry = upperdentry ?: ovl_dentry_lower(dentry);
43 struct path realpath;
44
45 if (!value && !upperdentry) {
46 ovl_path_lower(dentry, &realpath);
47 with_ovl_creds(dentry->d_sb)
48 err = vfs_getxattr(mnt_idmap(realpath.mnt), realdentry, name, NULL, 0);
49 if (err < 0)
50 goto out;
51 }
52
53 if (!upperdentry) {
54 err = ovl_copy_up(dentry);
55 if (err)
56 goto out;
57
58 realdentry = ovl_dentry_upper(dentry);
59 }
60
61 err = ovl_want_write(dentry);
62 if (err)
63 goto out;
64
65 with_ovl_creds(dentry->d_sb) {
66 if (value) {
67 err = ovl_do_setxattr(ofs, realdentry, name, value, size, flags);
68 } else {
69 WARN_ON(flags != XATTR_REPLACE);
70 err = ovl_do_removexattr(ofs, realdentry, name);
71 }
72 }
73 ovl_drop_write(dentry);
74
75 /* copy c/mtime */
76 ovl_copyattr(inode);
77 out:
78 return err;
79 }
80
ovl_xattr_get(struct dentry * dentry,struct inode * inode,const char * name,void * value,size_t size)81 static int ovl_xattr_get(struct dentry *dentry, struct inode *inode, const char *name,
82 void *value, size_t size)
83 {
84 struct path realpath;
85
86 ovl_i_path_real(inode, &realpath);
87 /* Use vfs_getxattr(), not __vfs_getxattr(): it idmaps the security.capability rootid. */
88 with_ovl_creds(dentry->d_sb)
89 return vfs_getxattr(mnt_idmap(realpath.mnt), realpath.dentry, name, value, size);
90 }
91
ovl_can_list(struct super_block * sb,const char * s)92 static bool ovl_can_list(struct super_block *sb, const char *s)
93 {
94 /* Never list private (.overlay) */
95 if (ovl_is_private_xattr(sb, s))
96 return false;
97
98 /* List all non-trusted xattrs */
99 if (strncmp(s, XATTR_TRUSTED_PREFIX, XATTR_TRUSTED_PREFIX_LEN) != 0)
100 return true;
101
102 /* list other trusted for superuser only */
103 return ns_capable_noaudit(&init_user_ns, CAP_SYS_ADMIN);
104 }
105
ovl_listxattr(struct dentry * dentry,char * list,size_t size)106 ssize_t ovl_listxattr(struct dentry *dentry, char *list, size_t size)
107 {
108 struct dentry *realdentry = ovl_dentry_real(dentry);
109 struct ovl_fs *ofs = OVL_FS(dentry->d_sb);
110 ssize_t res;
111 size_t len;
112 char *s;
113 size_t prefix_len, name_len;
114
115 with_ovl_creds(dentry->d_sb)
116 res = vfs_listxattr(realdentry, list, size);
117 if (res <= 0 || size == 0)
118 return res;
119
120 prefix_len = ofs->config.userxattr ?
121 OVL_XATTR_USER_PREFIX_LEN : OVL_XATTR_TRUSTED_PREFIX_LEN;
122
123 /* filter out private xattrs */
124 for (s = list, len = res; len;) {
125 size_t slen = strnlen(s, len) + 1;
126
127 /* underlying fs providing us with an broken xattr list? */
128 if (WARN_ON(slen > len))
129 return -EIO;
130
131 len -= slen;
132 if (!ovl_can_list(dentry->d_sb, s)) {
133 res -= slen;
134 memmove(s, s + slen, len);
135 } else if (ovl_is_escaped_xattr(dentry->d_sb, s)) {
136 res -= OVL_XATTR_ESCAPE_PREFIX_LEN;
137 name_len = slen - prefix_len - OVL_XATTR_ESCAPE_PREFIX_LEN;
138 s += prefix_len;
139 memmove(s, s + OVL_XATTR_ESCAPE_PREFIX_LEN, name_len + len);
140 s += name_len;
141 } else {
142 s += slen;
143 }
144 }
145
146 return res;
147 }
148
ovl_xattr_escape_name(const char * prefix,const char * name)149 static char *ovl_xattr_escape_name(const char *prefix, const char *name)
150 {
151 size_t prefix_len = strlen(prefix);
152 size_t name_len = strlen(name);
153 size_t escaped_len;
154 char *escaped, *s;
155
156 escaped_len = prefix_len + OVL_XATTR_ESCAPE_PREFIX_LEN + name_len;
157 if (escaped_len > XATTR_NAME_MAX)
158 return ERR_PTR(-EOPNOTSUPP);
159
160 escaped = kmalloc(escaped_len + 1, GFP_KERNEL);
161 if (escaped == NULL)
162 return ERR_PTR(-ENOMEM);
163
164 s = escaped;
165 memcpy(s, prefix, prefix_len);
166 s += prefix_len;
167 memcpy(s, OVL_XATTR_ESCAPE_PREFIX, OVL_XATTR_ESCAPE_PREFIX_LEN);
168 s += OVL_XATTR_ESCAPE_PREFIX_LEN;
169 memcpy(s, name, name_len + 1);
170
171 return escaped;
172 }
173
ovl_own_xattr_get(const struct xattr_handler * handler,struct dentry * dentry,struct inode * inode,const char * name,void * buffer,size_t size)174 static int ovl_own_xattr_get(const struct xattr_handler *handler,
175 struct dentry *dentry, struct inode *inode,
176 const char *name, void *buffer, size_t size)
177 {
178 char *escaped;
179 int r;
180
181 escaped = ovl_xattr_escape_name(handler->prefix, name);
182 if (IS_ERR(escaped))
183 return PTR_ERR(escaped);
184
185 r = ovl_xattr_get(dentry, inode, escaped, buffer, size);
186
187 kfree(escaped);
188
189 return r;
190 }
191
ovl_own_xattr_set(const struct xattr_handler * handler,struct mnt_idmap * idmap,struct dentry * dentry,struct inode * inode,const char * name,const void * value,size_t size,int flags)192 static int ovl_own_xattr_set(const struct xattr_handler *handler,
193 struct mnt_idmap *idmap,
194 struct dentry *dentry, struct inode *inode,
195 const char *name, const void *value,
196 size_t size, int flags)
197 {
198 char *escaped;
199 int r;
200
201 escaped = ovl_xattr_escape_name(handler->prefix, name);
202 if (IS_ERR(escaped))
203 return PTR_ERR(escaped);
204
205 r = ovl_xattr_set(dentry, inode, escaped, value, size, flags);
206
207 kfree(escaped);
208
209 return r;
210 }
211
ovl_other_xattr_get(const struct xattr_handler * handler,struct dentry * dentry,struct inode * inode,const char * name,void * buffer,size_t size)212 static int ovl_other_xattr_get(const struct xattr_handler *handler,
213 struct dentry *dentry, struct inode *inode,
214 const char *name, void *buffer, size_t size)
215 {
216 return ovl_xattr_get(dentry, inode, name, buffer, size);
217 }
218
ovl_other_xattr_set(const struct xattr_handler * handler,struct mnt_idmap * idmap,struct dentry * dentry,struct inode * inode,const char * name,const void * value,size_t size,int flags)219 static int ovl_other_xattr_set(const struct xattr_handler *handler,
220 struct mnt_idmap *idmap,
221 struct dentry *dentry, struct inode *inode,
222 const char *name, const void *value,
223 size_t size, int flags)
224 {
225 return ovl_xattr_set(dentry, inode, name, value, size, flags);
226 }
227
228 static const struct xattr_handler ovl_own_trusted_xattr_handler = {
229 .prefix = OVL_XATTR_TRUSTED_PREFIX,
230 .get = ovl_own_xattr_get,
231 .set = ovl_own_xattr_set,
232 };
233
234 static const struct xattr_handler ovl_own_user_xattr_handler = {
235 .prefix = OVL_XATTR_USER_PREFIX,
236 .get = ovl_own_xattr_get,
237 .set = ovl_own_xattr_set,
238 };
239
240 static const struct xattr_handler ovl_other_xattr_handler = {
241 .prefix = "", /* catch all */
242 .get = ovl_other_xattr_get,
243 .set = ovl_other_xattr_set,
244 };
245
246 static const struct xattr_handler * const ovl_trusted_xattr_handlers[] = {
247 &ovl_own_trusted_xattr_handler,
248 &ovl_other_xattr_handler,
249 NULL
250 };
251
252 static const struct xattr_handler * const ovl_user_xattr_handlers[] = {
253 &ovl_own_user_xattr_handler,
254 &ovl_other_xattr_handler,
255 NULL
256 };
257
ovl_xattr_handlers(struct ovl_fs * ofs)258 const struct xattr_handler * const *ovl_xattr_handlers(struct ovl_fs *ofs)
259 {
260 return ofs->config.userxattr ? ovl_user_xattr_handlers :
261 ovl_trusted_xattr_handlers;
262 }
263