hc
2024-05-10 9999e48639b3cecb08ffb37358bcba3b48161b29
kernel/fs/xattr.c
....@@ -1,3 +1,4 @@
1
+// SPDX-License-Identifier: GPL-2.0-only
12 /*
23 File: fs/xattr.c
34
....@@ -130,8 +131,35 @@
130131 return -EPERM;
131132 }
132133
133
- return inode_permission2(ERR_PTR(-EOPNOTSUPP), inode, mask);
134
+ return inode_permission(inode, mask);
134135 }
136
+
137
+/*
138
+ * Look for any handler that deals with the specified namespace.
139
+ */
140
+int
141
+xattr_supported_namespace(struct inode *inode, const char *prefix)
142
+{
143
+ const struct xattr_handler **handlers = inode->i_sb->s_xattr;
144
+ const struct xattr_handler *handler;
145
+ size_t preflen;
146
+
147
+ if (!(inode->i_opflags & IOP_XATTR)) {
148
+ if (unlikely(is_bad_inode(inode)))
149
+ return -EIO;
150
+ return -EOPNOTSUPP;
151
+ }
152
+
153
+ preflen = strlen(prefix);
154
+
155
+ for_each_xattr_handler(handlers, handler) {
156
+ if (!strncmp(xattr_prefix(handler), prefix, preflen))
157
+ return 0;
158
+ }
159
+
160
+ return -EOPNOTSUPP;
161
+}
162
+EXPORT_SYMBOL(xattr_supported_namespace);
135163
136164 int
137165 __vfs_setxattr(struct dentry *dentry, struct inode *inode, const char *name,
....@@ -204,15 +232,15 @@
204232 }
205233
206234 /**
207
- * __vfs_setxattr_locked: set an extended attribute while holding the inode
235
+ * __vfs_setxattr_locked - set an extended attribute while holding the inode
208236 * lock
209237 *
210
- * @dentry - object to perform setxattr on
211
- * @name - xattr name to set
212
- * @value - value to set @name to
213
- * @size - size of @value
214
- * @flags - flags to pass into filesystem operations
215
- * @delegated_inode - on return, will contain an inode pointer that
238
+ * @dentry: object to perform setxattr on
239
+ * @name: xattr name to set
240
+ * @value: value to set @name to
241
+ * @size: size of @value
242
+ * @flags: flags to pass into filesystem operations
243
+ * @delegated_inode: on return, will contain an inode pointer that
216244 * a delegation was broken on, NULL if none.
217245 */
218246 int
....@@ -263,7 +291,7 @@
263291 }
264292 return error;
265293 }
266
-EXPORT_SYMBOL_GPL(vfs_setxattr);
294
+EXPORT_SYMBOL_NS_GPL(vfs_setxattr, ANDROID_GKI_VFS_EXPORT_ONLY);
267295
268296 static ssize_t
269297 xattr_getsecurity(struct inode *inode, const char *name, void *value,
....@@ -317,7 +345,7 @@
317345 return PTR_ERR(handler);
318346 if (!handler->get)
319347 return -EOPNOTSUPP;
320
- error = handler->get(handler, dentry, inode, name, NULL, 0);
348
+ error = handler->get(handler, dentry, inode, name, NULL, 0, 0);
321349 if (error < 0)
322350 return error;
323351
....@@ -328,36 +356,20 @@
328356 memset(value, 0, error + 1);
329357 }
330358
331
- error = handler->get(handler, dentry, inode, name, value, error);
359
+ error = handler->get(handler, dentry, inode, name, value, error, 0);
332360 *xattr_value = value;
333361 return error;
334362 }
335363
336364 ssize_t
337365 __vfs_getxattr(struct dentry *dentry, struct inode *inode, const char *name,
338
- void *value, size_t size)
366
+ void *value, size_t size, int flags)
339367 {
340368 const struct xattr_handler *handler;
341
-
342
- handler = xattr_resolve_name(inode, &name);
343
- if (IS_ERR(handler))
344
- return PTR_ERR(handler);
345
- if (unlikely(handler->__get))
346
- return handler->__get(handler, dentry, inode, name, value,
347
- size);
348
- if (!handler->get)
349
- return -EOPNOTSUPP;
350
- return handler->get(handler, dentry, inode, name, value, size);
351
-}
352
-EXPORT_SYMBOL(__vfs_getxattr);
353
-
354
-ssize_t
355
-vfs_getxattr(struct dentry *dentry, const char *name, void *value, size_t size)
356
-{
357
- struct inode *inode = dentry->d_inode;
358369 int error;
359
- const struct xattr_handler *handler;
360370
371
+ if (flags & XATTR_NOSECURITY)
372
+ goto nolsm;
361373 error = xattr_permission(inode, name, MAY_READ);
362374 if (error)
363375 return error;
....@@ -384,9 +396,16 @@
384396 return PTR_ERR(handler);
385397 if (!handler->get)
386398 return -EOPNOTSUPP;
387
- return handler->get(handler, dentry, inode, name, value, size);
399
+ return handler->get(handler, dentry, inode, name, value, size, flags);
388400 }
389
-EXPORT_SYMBOL_GPL(vfs_getxattr);
401
+EXPORT_SYMBOL(__vfs_getxattr);
402
+
403
+ssize_t
404
+vfs_getxattr(struct dentry *dentry, const char *name, void *value, size_t size)
405
+{
406
+ return __vfs_getxattr(dentry, dentry->d_inode, name, value, size, 0);
407
+}
408
+EXPORT_SYMBOL_NS_GPL(vfs_getxattr, ANDROID_GKI_VFS_EXPORT_ONLY);
390409
391410 ssize_t
392411 vfs_listxattr(struct dentry *dentry, char *list, size_t size)
....@@ -406,7 +425,7 @@
406425 }
407426 return error;
408427 }
409
-EXPORT_SYMBOL_GPL(vfs_listxattr);
428
+EXPORT_SYMBOL_NS_GPL(vfs_listxattr, ANDROID_GKI_VFS_EXPORT_ONLY);
410429
411430 int
412431 __vfs_removexattr(struct dentry *dentry, const char *name)
....@@ -424,12 +443,12 @@
424443 EXPORT_SYMBOL(__vfs_removexattr);
425444
426445 /**
427
- * __vfs_removexattr_locked: set an extended attribute while holding the inode
446
+ * __vfs_removexattr_locked - set an extended attribute while holding the inode
428447 * lock
429448 *
430
- * @dentry - object to perform setxattr on
431
- * @name - name of xattr to remove
432
- * @delegated_inode - on return, will contain an inode pointer that
449
+ * @dentry: object to perform setxattr on
450
+ * @name: name of xattr to remove
451
+ * @delegated_inode: on return, will contain an inode pointer that
433452 * a delegation was broken on, NULL if none.
434453 */
435454 int
....@@ -895,7 +914,7 @@
895914 if (len < sizeof(*new_xattr))
896915 return NULL;
897916
898
- new_xattr = kmalloc(len, GFP_KERNEL);
917
+ new_xattr = kvmalloc(len, GFP_KERNEL);
899918 if (!new_xattr)
900919 return NULL;
901920
....@@ -938,6 +957,7 @@
938957 * @value: value of the xattr. If %NULL, will remove the attribute.
939958 * @size: size of the new xattr
940959 * @flags: %XATTR_{CREATE|REPLACE}
960
+ * @removed_size: returns size of the removed xattr, -1 if none removed
941961 *
942962 * %XATTR_CREATE is set, the xattr shouldn't exist already; otherwise fails
943963 * with -EEXIST. If %XATTR_REPLACE is set, the xattr should exist;
....@@ -946,11 +966,15 @@
946966 * Returns 0 on success, -errno on failure.
947967 */
948968 int simple_xattr_set(struct simple_xattrs *xattrs, const char *name,
949
- const void *value, size_t size, int flags)
969
+ const void *value, size_t size, int flags,
970
+ ssize_t *removed_size)
950971 {
951972 struct simple_xattr *xattr;
952973 struct simple_xattr *new_xattr = NULL;
953974 int err = 0;
975
+
976
+ if (removed_size)
977
+ *removed_size = -1;
954978
955979 /* value == NULL means remove */
956980 if (value) {
....@@ -960,7 +984,7 @@
960984
961985 new_xattr->name = kstrdup(name, GFP_KERNEL);
962986 if (!new_xattr->name) {
963
- kfree(new_xattr);
987
+ kvfree(new_xattr);
964988 return -ENOMEM;
965989 }
966990 }
....@@ -973,8 +997,12 @@
973997 err = -EEXIST;
974998 } else if (new_xattr) {
975999 list_replace(&xattr->list, &new_xattr->list);
1000
+ if (removed_size)
1001
+ *removed_size = xattr->size;
9761002 } else {
9771003 list_del(&xattr->list);
1004
+ if (removed_size)
1005
+ *removed_size = xattr->size;
9781006 }
9791007 goto out;
9801008 }
....@@ -990,7 +1018,7 @@
9901018 spin_unlock(&xattrs->lock);
9911019 if (xattr) {
9921020 kfree(xattr->name);
993
- kfree(xattr);
1021
+ kvfree(xattr);
9941022 }
9951023 return err;
9961024
....@@ -1021,7 +1049,7 @@
10211049 ssize_t simple_xattr_list(struct inode *inode, struct simple_xattrs *xattrs,
10221050 char *buffer, size_t size)
10231051 {
1024
- bool trusted = capable(CAP_SYS_ADMIN);
1052
+ bool trusted = ns_capable_noaudit(&init_user_ns, CAP_SYS_ADMIN);
10251053 struct simple_xattr *xattr;
10261054 ssize_t remaining_size = size;
10271055 int err = 0;