xref: /linux/fs/overlayfs/xattrs.c (revision 7fc2cd2e4b398c57c9cf961cfea05eadbf34c05c)
1 // SPDX-License-Identifier: GPL-2.0-only
2 
3 #include <linux/fs.h>
4 #include <linux/xattr.h>
5 #include "overlayfs.h"
6 
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 - 1) == 0;
17 }
18 
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 
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 
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 
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 	with_ovl_creds(dentry->d_sb)
88 		return vfs_getxattr(mnt_idmap(realpath.mnt), realpath.dentry, name, value, size);
89 }
90 
91 static bool ovl_can_list(struct super_block *sb, const char *s)
92 {
93 	/* Never list private (.overlay) */
94 	if (ovl_is_private_xattr(sb, s))
95 		return false;
96 
97 	/* List all non-trusted xattrs */
98 	if (strncmp(s, XATTR_TRUSTED_PREFIX, XATTR_TRUSTED_PREFIX_LEN) != 0)
99 		return true;
100 
101 	/* list other trusted for superuser only */
102 	return ns_capable_noaudit(&init_user_ns, CAP_SYS_ADMIN);
103 }
104 
105 ssize_t ovl_listxattr(struct dentry *dentry, char *list, size_t size)
106 {
107 	struct dentry *realdentry = ovl_dentry_real(dentry);
108 	struct ovl_fs *ofs = OVL_FS(dentry->d_sb);
109 	ssize_t res;
110 	size_t len;
111 	char *s;
112 	size_t prefix_len, name_len;
113 
114 	with_ovl_creds(dentry->d_sb)
115 		res = vfs_listxattr(realdentry, list, size);
116 	if (res <= 0 || size == 0)
117 		return res;
118 
119 	prefix_len = ofs->config.userxattr ?
120 		OVL_XATTR_USER_PREFIX_LEN : OVL_XATTR_TRUSTED_PREFIX_LEN;
121 
122 	/* filter out private xattrs */
123 	for (s = list, len = res; len;) {
124 		size_t slen = strnlen(s, len) + 1;
125 
126 		/* underlying fs providing us with an broken xattr list? */
127 		if (WARN_ON(slen > len))
128 			return -EIO;
129 
130 		len -= slen;
131 		if (!ovl_can_list(dentry->d_sb, s)) {
132 			res -= slen;
133 			memmove(s, s + slen, len);
134 		} else if (ovl_is_escaped_xattr(dentry->d_sb, s)) {
135 			res -= OVL_XATTR_ESCAPE_PREFIX_LEN;
136 			name_len = slen - prefix_len - OVL_XATTR_ESCAPE_PREFIX_LEN;
137 			s += prefix_len;
138 			memmove(s, s + OVL_XATTR_ESCAPE_PREFIX_LEN, name_len + len);
139 			s += name_len;
140 		} else {
141 			s += slen;
142 		}
143 	}
144 
145 	return res;
146 }
147 
148 static char *ovl_xattr_escape_name(const char *prefix, const char *name)
149 {
150 	size_t prefix_len = strlen(prefix);
151 	size_t name_len = strlen(name);
152 	size_t escaped_len;
153 	char *escaped, *s;
154 
155 	escaped_len = prefix_len + OVL_XATTR_ESCAPE_PREFIX_LEN + name_len;
156 	if (escaped_len > XATTR_NAME_MAX)
157 		return ERR_PTR(-EOPNOTSUPP);
158 
159 	escaped = kmalloc(escaped_len + 1, GFP_KERNEL);
160 	if (escaped == NULL)
161 		return ERR_PTR(-ENOMEM);
162 
163 	s = escaped;
164 	memcpy(s, prefix, prefix_len);
165 	s += prefix_len;
166 	memcpy(s, OVL_XATTR_ESCAPE_PREFIX, OVL_XATTR_ESCAPE_PREFIX_LEN);
167 	s += OVL_XATTR_ESCAPE_PREFIX_LEN;
168 	memcpy(s, name, name_len + 1);
169 
170 	return escaped;
171 }
172 
173 static int ovl_own_xattr_get(const struct xattr_handler *handler,
174 			     struct dentry *dentry, struct inode *inode,
175 			     const char *name, void *buffer, size_t size)
176 {
177 	char *escaped;
178 	int r;
179 
180 	escaped = ovl_xattr_escape_name(handler->prefix, name);
181 	if (IS_ERR(escaped))
182 		return PTR_ERR(escaped);
183 
184 	r = ovl_xattr_get(dentry, inode, escaped, buffer, size);
185 
186 	kfree(escaped);
187 
188 	return r;
189 }
190 
191 static int ovl_own_xattr_set(const struct xattr_handler *handler,
192 			     struct mnt_idmap *idmap,
193 			     struct dentry *dentry, struct inode *inode,
194 			     const char *name, const void *value,
195 			     size_t size, int flags)
196 {
197 	char *escaped;
198 	int r;
199 
200 	escaped = ovl_xattr_escape_name(handler->prefix, name);
201 	if (IS_ERR(escaped))
202 		return PTR_ERR(escaped);
203 
204 	r = ovl_xattr_set(dentry, inode, escaped, value, size, flags);
205 
206 	kfree(escaped);
207 
208 	return r;
209 }
210 
211 static int ovl_other_xattr_get(const struct xattr_handler *handler,
212 			       struct dentry *dentry, struct inode *inode,
213 			       const char *name, void *buffer, size_t size)
214 {
215 	return ovl_xattr_get(dentry, inode, name, buffer, size);
216 }
217 
218 static int ovl_other_xattr_set(const struct xattr_handler *handler,
219 			       struct mnt_idmap *idmap,
220 			       struct dentry *dentry, struct inode *inode,
221 			       const char *name, const void *value,
222 			       size_t size, int flags)
223 {
224 	return ovl_xattr_set(dentry, inode, name, value, size, flags);
225 }
226 
227 static const struct xattr_handler ovl_own_trusted_xattr_handler = {
228 	.prefix	= OVL_XATTR_TRUSTED_PREFIX,
229 	.get = ovl_own_xattr_get,
230 	.set = ovl_own_xattr_set,
231 };
232 
233 static const struct xattr_handler ovl_own_user_xattr_handler = {
234 	.prefix	= OVL_XATTR_USER_PREFIX,
235 	.get = ovl_own_xattr_get,
236 	.set = ovl_own_xattr_set,
237 };
238 
239 static const struct xattr_handler ovl_other_xattr_handler = {
240 	.prefix	= "", /* catch all */
241 	.get = ovl_other_xattr_get,
242 	.set = ovl_other_xattr_set,
243 };
244 
245 static const struct xattr_handler * const ovl_trusted_xattr_handlers[] = {
246 	&ovl_own_trusted_xattr_handler,
247 	&ovl_other_xattr_handler,
248 	NULL
249 };
250 
251 static const struct xattr_handler * const ovl_user_xattr_handlers[] = {
252 	&ovl_own_user_xattr_handler,
253 	&ovl_other_xattr_handler,
254 	NULL
255 };
256 
257 const struct xattr_handler * const *ovl_xattr_handlers(struct ovl_fs *ofs)
258 {
259 	return ofs->config.userxattr ? ovl_user_xattr_handlers :
260 		ovl_trusted_xattr_handlers;
261 }
262