xref: /aosp_15_r20/external/erofs-utils/lib/xattr.c (revision 33b1fccf6a0fada2c2875d400ed01119b7676ee5)
1 // SPDX-License-Identifier: GPL-2.0+ OR Apache-2.0
2 /*
3  * Originally contributed by an anonymous person,
4  * heavily changed by Li Guifu <[email protected]>
5  *                and Gao Xiang <[email protected]>
6  */
7 #define _GNU_SOURCE
8 #include <stdlib.h>
9 #include <sys/xattr.h>
10 #ifdef HAVE_LINUX_XATTR_H
11 #include <linux/xattr.h>
12 #endif
13 #include <sys/stat.h>
14 #include <dirent.h>
15 #include "erofs/print.h"
16 #include "erofs/hashtable.h"
17 #include "erofs/xattr.h"
18 #include "erofs/cache.h"
19 #include "erofs/fragments.h"
20 #include "xxhash.h"
21 #include "liberofs_private.h"
22 
23 #ifndef XATTR_SYSTEM_PREFIX
24 #define XATTR_SYSTEM_PREFIX	"system."
25 #endif
26 #ifndef XATTR_SYSTEM_PREFIX_LEN
27 #define XATTR_SYSTEM_PREFIX_LEN (sizeof(XATTR_SYSTEM_PREFIX) - 1)
28 #endif
29 #ifndef XATTR_USER_PREFIX
30 #define XATTR_USER_PREFIX	"user."
31 #endif
32 #ifndef XATTR_USER_PREFIX_LEN
33 #define XATTR_USER_PREFIX_LEN (sizeof(XATTR_USER_PREFIX) - 1)
34 #endif
35 #ifndef XATTR_SECURITY_PREFIX
36 #define XATTR_SECURITY_PREFIX	"security."
37 #endif
38 #ifndef XATTR_SECURITY_PREFIX_LEN
39 #define XATTR_SECURITY_PREFIX_LEN (sizeof(XATTR_SECURITY_PREFIX) - 1)
40 #endif
41 #ifndef XATTR_TRUSTED_PREFIX
42 #define XATTR_TRUSTED_PREFIX	"trusted."
43 #endif
44 #ifndef XATTR_TRUSTED_PREFIX_LEN
45 #define XATTR_TRUSTED_PREFIX_LEN (sizeof(XATTR_TRUSTED_PREFIX) - 1)
46 #endif
47 #ifndef XATTR_NAME_POSIX_ACL_ACCESS
48 #define XATTR_NAME_POSIX_ACL_ACCESS "system.posix_acl_access"
49 #endif
50 #ifndef XATTR_NAME_POSIX_ACL_DEFAULT
51 #define XATTR_NAME_POSIX_ACL_DEFAULT "system.posix_acl_default"
52 #endif
53 #ifndef XATTR_NAME_SECURITY_SELINUX
54 #define XATTR_NAME_SECURITY_SELINUX "security.selinux"
55 #endif
56 #ifndef XATTR_NAME_SECURITY_CAPABILITY
57 #define XATTR_NAME_SECURITY_CAPABILITY "security.capability"
58 #endif
59 #ifndef OVL_XATTR_NAMESPACE
60 #define OVL_XATTR_NAMESPACE "overlay."
61 #endif
62 #ifndef OVL_XATTR_OPAQUE_POSTFIX
63 #define OVL_XATTR_OPAQUE_POSTFIX "opaque"
64 #endif
65 #ifndef OVL_XATTR_ORIGIN_POSTFIX
66 #define OVL_XATTR_ORIGIN_POSTFIX "origin"
67 #endif
68 #ifndef OVL_XATTR_TRUSTED_PREFIX
69 #define OVL_XATTR_TRUSTED_PREFIX XATTR_TRUSTED_PREFIX OVL_XATTR_NAMESPACE
70 #endif
71 #ifndef OVL_XATTR_OPAQUE
72 #define OVL_XATTR_OPAQUE OVL_XATTR_TRUSTED_PREFIX OVL_XATTR_OPAQUE_POSTFIX
73 #endif
74 #ifndef OVL_XATTR_ORIGIN
75 #define OVL_XATTR_ORIGIN OVL_XATTR_TRUSTED_PREFIX OVL_XATTR_ORIGIN_POSTFIX
76 #endif
77 
78 #define EA_HASHTABLE_BITS 16
79 
80 /* one extra byte for the trailing `\0` of attribute name */
81 #define EROFS_XATTR_KSIZE(kvlen)	(kvlen[0] + 1)
82 #define EROFS_XATTR_KVSIZE(kvlen)	(EROFS_XATTR_KSIZE(kvlen) + kvlen[1])
83 
84 /*
85  * @base_index:	the index of the matched predefined short prefix
86  * @prefix:	the index of the matched long prefix, if any;
87  *		same as base_index otherwise
88  * @prefix_len:	the length of the matched long prefix if any;
89  *		the length of the matched predefined short prefix otherwise
90  */
91 struct xattr_item {
92 	struct xattr_item *next_shared_xattr;
93 	const char *kvbuf;
94 	unsigned int hash[2], len[2], count;
95 	int shared_xattr_id;
96 	unsigned int prefix, base_index, prefix_len;
97 	struct hlist_node node;
98 };
99 
100 struct inode_xattr_node {
101 	struct list_head list;
102 	struct xattr_item *item;
103 };
104 
105 static DECLARE_HASHTABLE(ea_hashtable, EA_HASHTABLE_BITS);
106 
107 static struct xattr_item *shared_xattrs_list;
108 static unsigned int shared_xattrs_count;
109 
110 static struct xattr_prefix {
111 	const char *prefix;
112 	unsigned int prefix_len;
113 } xattr_types[] = {
114 	[EROFS_XATTR_INDEX_USER] = {
115 		XATTR_USER_PREFIX,
116 		XATTR_USER_PREFIX_LEN
117 	}, [EROFS_XATTR_INDEX_POSIX_ACL_ACCESS] = {
118 		XATTR_NAME_POSIX_ACL_ACCESS,
119 		sizeof(XATTR_NAME_POSIX_ACL_ACCESS) - 1
120 	}, [EROFS_XATTR_INDEX_POSIX_ACL_DEFAULT] = {
121 		XATTR_NAME_POSIX_ACL_DEFAULT,
122 		sizeof(XATTR_NAME_POSIX_ACL_DEFAULT) - 1
123 	}, [EROFS_XATTR_INDEX_TRUSTED] = {
124 		XATTR_TRUSTED_PREFIX,
125 		XATTR_TRUSTED_PREFIX_LEN
126 	}, [EROFS_XATTR_INDEX_SECURITY] = {
127 		XATTR_SECURITY_PREFIX,
128 		XATTR_SECURITY_PREFIX_LEN
129 	}
130 };
131 
132 struct ea_type_node {
133 	struct list_head list;
134 	struct xattr_prefix type;
135 	unsigned int index, base_index, base_len;
136 };
137 
138 static LIST_HEAD(ea_name_prefixes);
139 static unsigned int ea_prefix_count;
140 
match_prefix(const char * key,unsigned int * index,unsigned int * len)141 static bool match_prefix(const char *key, unsigned int *index,
142 			 unsigned int *len)
143 {
144 	struct xattr_prefix *p;
145 
146 	for (p = xattr_types; p < xattr_types + ARRAY_SIZE(xattr_types); ++p) {
147 		if (p->prefix && !strncmp(p->prefix, key, p->prefix_len)) {
148 			*len = p->prefix_len;
149 			*index = p - xattr_types;
150 			return true;
151 		}
152 	}
153 	return false;
154 }
155 
BKDRHash(char * str,unsigned int len)156 static unsigned int BKDRHash(char *str, unsigned int len)
157 {
158 	const unsigned int seed = 131313;
159 	unsigned int hash = 0;
160 
161 	while (len) {
162 		hash = hash * seed + (*str++);
163 		--len;
164 	}
165 	return hash;
166 }
167 
put_xattritem(struct xattr_item * item)168 static unsigned int put_xattritem(struct xattr_item *item)
169 {
170 	if (item->count > 1)
171 		return --item->count;
172 	free(item);
173 	return 0;
174 }
175 
get_xattritem(char * kvbuf,unsigned int len[2])176 static struct xattr_item *get_xattritem(char *kvbuf, unsigned int len[2])
177 {
178 	struct xattr_item *item;
179 	struct ea_type_node *tnode;
180 	unsigned int hash[2], hkey;
181 
182 	hash[0] = BKDRHash(kvbuf, len[0]);
183 	hash[1] = BKDRHash(kvbuf + EROFS_XATTR_KSIZE(len), len[1]);
184 	hkey = hash[0] ^ hash[1];
185 	hash_for_each_possible(ea_hashtable, item, node, hkey) {
186 		if (item->len[0] == len[0] && item->len[1] == len[1] &&
187 		    item->hash[0] == hash[0] && item->hash[1] == hash[1] &&
188 		    !memcmp(kvbuf, item->kvbuf, EROFS_XATTR_KVSIZE(len))) {
189 			free(kvbuf);
190 			++item->count;
191 			return item;
192 		}
193 	}
194 
195 	item = malloc(sizeof(*item));
196 	if (!item)
197 		return ERR_PTR(-ENOMEM);
198 
199 	if (!match_prefix(kvbuf, &item->base_index, &item->prefix_len)) {
200 		free(item);
201 		return ERR_PTR(-ENODATA);
202 	}
203 	DBG_BUGON(len[0] < item->prefix_len);
204 
205 	INIT_HLIST_NODE(&item->node);
206 	item->count = 1;
207 	item->kvbuf = kvbuf;
208 	item->len[0] = len[0];
209 	item->len[1] = len[1];
210 	item->hash[0] = hash[0];
211 	item->hash[1] = hash[1];
212 	item->shared_xattr_id = -1;
213 	item->prefix = item->base_index;
214 
215 	list_for_each_entry(tnode, &ea_name_prefixes, list) {
216 		if (item->base_index == tnode->base_index &&
217 		    !strncmp(tnode->type.prefix, kvbuf,
218 			     tnode->type.prefix_len)) {
219 			item->prefix = tnode->index;
220 			item->prefix_len = tnode->type.prefix_len;
221 			break;
222 		}
223 	}
224 	hash_add(ea_hashtable, &item->node, hkey);
225 	return item;
226 }
227 
parse_one_xattr(const char * path,const char * key,unsigned int keylen)228 static struct xattr_item *parse_one_xattr(const char *path, const char *key,
229 					  unsigned int keylen)
230 {
231 	ssize_t ret;
232 	struct xattr_item *item;
233 	unsigned int len[2];
234 	char *kvbuf;
235 
236 	erofs_dbg("parse xattr [%s] of %s", path, key);
237 
238 	/* length of the key */
239 	len[0] = keylen;
240 
241 	/* determine length of the value */
242 #ifdef HAVE_LGETXATTR
243 	ret = lgetxattr(path, key, NULL, 0);
244 #elif defined(__APPLE__)
245 	ret = getxattr(path, key, NULL, 0, 0, XATTR_NOFOLLOW);
246 #else
247 	return ERR_PTR(-EOPNOTSUPP);
248 #endif
249 	if (ret < 0)
250 		return ERR_PTR(-errno);
251 	len[1] = ret;
252 
253 	/* allocate key-value buffer */
254 	kvbuf = malloc(EROFS_XATTR_KVSIZE(len));
255 	if (!kvbuf)
256 		return ERR_PTR(-ENOMEM);
257 	memcpy(kvbuf, key, EROFS_XATTR_KSIZE(len));
258 	if (len[1]) {
259 		/* copy value to buffer */
260 #ifdef HAVE_LGETXATTR
261 		ret = lgetxattr(path, key, kvbuf + EROFS_XATTR_KSIZE(len),
262 				len[1]);
263 #elif defined(__APPLE__)
264 		ret = getxattr(path, key, kvbuf + EROFS_XATTR_KSIZE(len),
265 			       len[1], 0, XATTR_NOFOLLOW);
266 #else
267 		ret = -EOPNOTSUPP;
268 		goto out;
269 #endif
270 		if (ret < 0) {
271 			ret = -errno;
272 			goto out;
273 		}
274 		if (len[1] != ret) {
275 			erofs_warn("size of xattr value got changed just now (%u-> %ld)",
276 				  len[1], (long)ret);
277 			len[1] = ret;
278 		}
279 	}
280 
281 	item = get_xattritem(kvbuf, len);
282 	if (!IS_ERR(item))
283 		return item;
284 	if (item == ERR_PTR(-ENODATA)) {
285 		erofs_warn("skipped unidentified xattr: %s", key);
286 		ret = 0;
287 	} else {
288 		ret = PTR_ERR(item);
289 	}
290 out:
291 	free(kvbuf);
292 	return ERR_PTR(ret);
293 }
294 
erofs_get_selabel_xattr(const char * srcpath,mode_t mode)295 static struct xattr_item *erofs_get_selabel_xattr(const char *srcpath,
296 						  mode_t mode)
297 {
298 #ifdef HAVE_LIBSELINUX
299 	if (cfg.sehnd) {
300 		char *secontext;
301 		int ret;
302 		unsigned int len[2];
303 		char *kvbuf, *fspath;
304 		struct xattr_item *item;
305 
306 		if (cfg.mount_point)
307 			ret = asprintf(&fspath, "/%s/%s", cfg.mount_point,
308 				       erofs_fspath(srcpath));
309 		else
310 			ret = asprintf(&fspath, "/%s", erofs_fspath(srcpath));
311 		if (ret <= 0)
312 			return ERR_PTR(-ENOMEM);
313 
314 		ret = selabel_lookup(cfg.sehnd, &secontext, fspath, mode);
315 		free(fspath);
316 
317 		if (ret) {
318 			ret = -errno;
319 			if (ret != -ENOENT) {
320 				erofs_err("failed to lookup selabel for %s: %s",
321 					  srcpath, erofs_strerror(ret));
322 				return ERR_PTR(ret);
323 			}
324 			/* secontext = "u:object_r:unlabeled:s0"; */
325 			return NULL;
326 		}
327 
328 		len[0] = sizeof(XATTR_NAME_SECURITY_SELINUX) - 1;
329 		len[1] = strlen(secontext);
330 		kvbuf = malloc(EROFS_XATTR_KVSIZE(len));
331 		if (!kvbuf) {
332 			freecon(secontext);
333 			return ERR_PTR(-ENOMEM);
334 		}
335 		sprintf(kvbuf, "%s", XATTR_NAME_SECURITY_SELINUX);
336 		memcpy(kvbuf + EROFS_XATTR_KSIZE(len), secontext, len[1]);
337 		freecon(secontext);
338 		item = get_xattritem(kvbuf, len);
339 		if (IS_ERR(item))
340 			free(kvbuf);
341 		return item;
342 	}
343 #endif
344 	return NULL;
345 }
346 
inode_xattr_add(struct list_head * hlist,struct xattr_item * item)347 static int inode_xattr_add(struct list_head *hlist, struct xattr_item *item)
348 {
349 	struct inode_xattr_node *node = malloc(sizeof(*node));
350 
351 	if (!node)
352 		return -ENOMEM;
353 	init_list_head(&node->list);
354 	node->item = item;
355 	list_add(&node->list, hlist);
356 	return 0;
357 }
358 
shared_xattr_add(struct xattr_item * item)359 static int shared_xattr_add(struct xattr_item *item)
360 {
361 	item->next_shared_xattr = shared_xattrs_list;
362 	shared_xattrs_list = item;
363 	return ++shared_xattrs_count;
364 }
365 
erofs_xattr_add(struct list_head * ixattrs,struct xattr_item * item)366 static int erofs_xattr_add(struct list_head *ixattrs, struct xattr_item *item)
367 {
368 	if (ixattrs)
369 		return inode_xattr_add(ixattrs, item);
370 
371 	if (item->count == cfg.c_inline_xattr_tolerance + 1) {
372 		int ret = shared_xattr_add(item);
373 
374 		if (ret < 0)
375 			return ret;
376 	}
377 	return 0;
378 }
379 
erofs_is_skipped_xattr(const char * key)380 static bool erofs_is_skipped_xattr(const char *key)
381 {
382 #ifdef HAVE_LIBSELINUX
383 	/* if sehnd is valid, selabels will be overridden */
384 	if (cfg.sehnd && !strcmp(key, XATTR_SECURITY_PREFIX "selinux"))
385 		return true;
386 #endif
387 	return false;
388 }
389 
read_xattrs_from_file(const char * path,mode_t mode,struct list_head * ixattrs)390 static int read_xattrs_from_file(const char *path, mode_t mode,
391 				 struct list_head *ixattrs)
392 {
393 #ifdef HAVE_LLISTXATTR
394 	ssize_t kllen = llistxattr(path, NULL, 0);
395 #elif defined(__APPLE__)
396 	ssize_t kllen = listxattr(path, NULL, 0, XATTR_NOFOLLOW);
397 #else
398 	ssize_t kllen = 0;
399 #endif
400 	int ret;
401 	char *keylst, *key, *klend;
402 	unsigned int keylen;
403 	struct xattr_item *item;
404 
405 	if (kllen < 0 && errno != ENODATA && errno != EOPNOTSUPP) {
406 		erofs_err("llistxattr to get the size of names for %s failed",
407 			  path);
408 		return -errno;
409 	}
410 
411 	ret = 0;
412 	if (kllen <= 1)
413 		goto out;
414 
415 	keylst = malloc(kllen);
416 	if (!keylst)
417 		return -ENOMEM;
418 
419 	/* copy the list of attribute keys to the buffer.*/
420 #ifdef HAVE_LLISTXATTR
421 	kllen = llistxattr(path, keylst, kllen);
422 #elif defined(__APPLE__)
423 	kllen = listxattr(path, keylst, kllen, XATTR_NOFOLLOW);
424 	if (kllen < 0) {
425 		erofs_err("llistxattr to get names for %s failed", path);
426 		ret = -errno;
427 		goto err;
428 	}
429 #else
430 	ret = -EOPNOTSUPP;
431 	goto err;
432 #endif
433 	/*
434 	 * loop over the list of zero terminated strings with the
435 	 * attribute keys. Use the remaining buffer length to determine
436 	 * the end of the list.
437 	 */
438 	klend = keylst + kllen;
439 	ret = 0;
440 
441 	for (key = keylst; key != klend; key += keylen + 1) {
442 		keylen = strlen(key);
443 		if (erofs_is_skipped_xattr(key))
444 			continue;
445 
446 		item = parse_one_xattr(path, key, keylen);
447 		if (IS_ERR(item)) {
448 			ret = PTR_ERR(item);
449 			goto err;
450 		}
451 
452 		ret = erofs_xattr_add(ixattrs, item);
453 		if (ret < 0)
454 			goto err;
455 	}
456 	free(keylst);
457 
458 out:
459 	/* if some selabel is avilable, need to add right now */
460 	item = erofs_get_selabel_xattr(path, mode);
461 	if (IS_ERR(item))
462 		return PTR_ERR(item);
463 	if (item)
464 		ret = erofs_xattr_add(ixattrs, item);
465 	return ret;
466 
467 err:
468 	free(keylst);
469 	return ret;
470 }
471 
erofs_setxattr(struct erofs_inode * inode,char * key,const void * value,size_t size)472 int erofs_setxattr(struct erofs_inode *inode, char *key,
473 		   const void *value, size_t size)
474 {
475 	char *kvbuf;
476 	unsigned int len[2];
477 	struct xattr_item *item;
478 
479 	len[0] = strlen(key);
480 	len[1] = size;
481 
482 	kvbuf = malloc(EROFS_XATTR_KVSIZE(len));
483 	if (!kvbuf)
484 		return -ENOMEM;
485 
486 	memcpy(kvbuf, key, EROFS_XATTR_KSIZE(len));
487 	memcpy(kvbuf + EROFS_XATTR_KSIZE(len), value, size);
488 
489 	item = get_xattritem(kvbuf, len);
490 	if (IS_ERR(item)) {
491 		free(kvbuf);
492 		return PTR_ERR(item);
493 	}
494 	DBG_BUGON(!item);
495 
496 	return erofs_xattr_add(&inode->i_xattrs, item);
497 }
498 
erofs_removexattr(struct erofs_inode * inode,const char * key)499 static void erofs_removexattr(struct erofs_inode *inode, const char *key)
500 {
501 	struct inode_xattr_node *node, *n;
502 
503 	list_for_each_entry_safe(node, n, &inode->i_xattrs, list) {
504 		if (!strcmp(node->item->kvbuf, key)) {
505 			list_del(&node->list);
506 			put_xattritem(node->item);
507 			free(node);
508 		}
509 	}
510 }
511 
erofs_set_opaque_xattr(struct erofs_inode * inode)512 int erofs_set_opaque_xattr(struct erofs_inode *inode)
513 {
514 	return erofs_setxattr(inode, OVL_XATTR_OPAQUE, "y", 1);
515 }
516 
erofs_clear_opaque_xattr(struct erofs_inode * inode)517 void erofs_clear_opaque_xattr(struct erofs_inode *inode)
518 {
519 	erofs_removexattr(inode, OVL_XATTR_OPAQUE);
520 }
521 
erofs_set_origin_xattr(struct erofs_inode * inode)522 int erofs_set_origin_xattr(struct erofs_inode *inode)
523 {
524 	return erofs_setxattr(inode, OVL_XATTR_ORIGIN, NULL, 0);
525 }
526 
527 #ifdef WITH_ANDROID
erofs_droid_xattr_set_caps(struct erofs_inode * inode)528 static int erofs_droid_xattr_set_caps(struct erofs_inode *inode)
529 {
530 	const u64 capabilities = inode->capabilities;
531 	char *kvbuf;
532 	unsigned int len[2];
533 	struct vfs_cap_data caps;
534 	struct xattr_item *item;
535 
536 	if (!capabilities)
537 		return 0;
538 
539 	len[0] = sizeof(XATTR_NAME_SECURITY_CAPABILITY) - 1;
540 	len[1] = sizeof(caps);
541 
542 	kvbuf = malloc(EROFS_XATTR_KVSIZE(len));
543 	if (!kvbuf)
544 		return -ENOMEM;
545 
546 	sprintf(kvbuf, "%s", XATTR_NAME_SECURITY_CAPABILITY);
547 	caps.magic_etc = VFS_CAP_REVISION_2 | VFS_CAP_FLAGS_EFFECTIVE;
548 	caps.data[0].permitted = (u32) capabilities;
549 	caps.data[0].inheritable = 0;
550 	caps.data[1].permitted = (u32) (capabilities >> 32);
551 	caps.data[1].inheritable = 0;
552 	memcpy(kvbuf + EROFS_XATTR_KSIZE(len), &caps, len[1]);
553 
554 	item = get_xattritem(kvbuf, len);
555 	if (IS_ERR(item)) {
556 		free(kvbuf);
557 		return PTR_ERR(item);
558 	}
559 	DBG_BUGON(!item);
560 
561 	return erofs_xattr_add(&inode->i_xattrs, item);
562 }
563 #else
erofs_droid_xattr_set_caps(struct erofs_inode * inode)564 static int erofs_droid_xattr_set_caps(struct erofs_inode *inode)
565 {
566 	return 0;
567 }
568 #endif
569 
erofs_scan_file_xattrs(struct erofs_inode * inode)570 int erofs_scan_file_xattrs(struct erofs_inode *inode)
571 {
572 	int ret;
573 	struct list_head *ixattrs = &inode->i_xattrs;
574 
575 	/* check if xattr is disabled */
576 	if (cfg.c_inline_xattr_tolerance < 0)
577 		return 0;
578 
579 	ret = read_xattrs_from_file(inode->i_srcpath, inode->i_mode, ixattrs);
580 	if (ret < 0)
581 		return ret;
582 
583 	return erofs_droid_xattr_set_caps(inode);
584 }
585 
erofs_read_xattrs_from_disk(struct erofs_inode * inode)586 int erofs_read_xattrs_from_disk(struct erofs_inode *inode)
587 {
588 	ssize_t kllen;
589 	char *keylst, *key;
590 	int ret;
591 
592 	init_list_head(&inode->i_xattrs);
593 	kllen = erofs_listxattr(inode, NULL, 0);
594 	if (kllen < 0)
595 		return kllen;
596 	if (kllen <= 1)
597 		return 0;
598 
599 	keylst = malloc(kllen);
600 	if (!keylst)
601 		return -ENOMEM;
602 
603 	ret = erofs_listxattr(inode, keylst, kllen);
604 	if (ret < 0)
605 		goto out;
606 
607 	for (key = keylst; key < keylst + kllen; key += strlen(key) + 1) {
608 		void *value = NULL;
609 		size_t size = 0;
610 
611 		if (!strcmp(key, OVL_XATTR_OPAQUE)) {
612 			if (!S_ISDIR(inode->i_mode)) {
613 				erofs_dbg("file %s: opaque xattr on non-dir",
614 					  inode->i_srcpath);
615 				ret = -EINVAL;
616 				goto out;
617 			}
618 			inode->opaque = true;
619 		}
620 
621 		ret = erofs_getxattr(inode, key, NULL, 0);
622 		if (ret < 0)
623 			goto out;
624 		if (ret) {
625 			size = ret;
626 			value = malloc(size);
627 			if (!value) {
628 				ret = -ENOMEM;
629 				goto out;
630 			}
631 
632 			ret = erofs_getxattr(inode, key, value, size);
633 			if (ret < 0) {
634 				free(value);
635 				goto out;
636 			}
637 			DBG_BUGON(ret != size);
638 		} else if (S_ISDIR(inode->i_mode) &&
639 			   !strcmp(key, OVL_XATTR_ORIGIN)) {
640 			ret = 0;
641 			inode->whiteouts = true;
642 			continue;
643 		}
644 
645 		ret = erofs_setxattr(inode, key, value, size);
646 		free(value);
647 		if (ret)
648 			break;
649 	}
650 out:
651 	free(keylst);
652 	return ret;
653 }
654 
erofs_next_xattr_align(unsigned int pos,struct xattr_item * item)655 static inline unsigned int erofs_next_xattr_align(unsigned int pos,
656 						  struct xattr_item *item)
657 {
658 	return EROFS_XATTR_ALIGN(pos + sizeof(struct erofs_xattr_entry) +
659 			item->len[0] + item->len[1] - item->prefix_len);
660 }
661 
erofs_prepare_xattr_ibody(struct erofs_inode * inode,bool noroom)662 int erofs_prepare_xattr_ibody(struct erofs_inode *inode, bool noroom)
663 {
664 	unsigned int target_xattr_isize = inode->xattr_isize;
665 	struct list_head *ixattrs = &inode->i_xattrs;
666 	struct inode_xattr_node *node;
667 	unsigned int h_shared_count;
668 	int ret;
669 
670 	if (list_empty(ixattrs)) {
671 		ret = 0;
672 		goto out;
673 	}
674 
675 	/* get xattr ibody size */
676 	h_shared_count = 0;
677 	ret = sizeof(struct erofs_xattr_ibody_header);
678 	list_for_each_entry(node, ixattrs, list) {
679 		struct xattr_item *item = node->item;
680 
681 		if (item->shared_xattr_id >= 0 && h_shared_count < UCHAR_MAX) {
682 			++h_shared_count;
683 			ret += sizeof(__le32);
684 			continue;
685 		}
686 		ret = erofs_next_xattr_align(ret, item);
687 	}
688 out:
689 	while (ret < target_xattr_isize) {
690 		ret += sizeof(struct erofs_xattr_entry);
691 		if (ret < target_xattr_isize)
692 			ret = EROFS_XATTR_ALIGN(ret +
693 				min_t(int, target_xattr_isize - ret, UINT16_MAX));
694 	}
695 	if (noroom && target_xattr_isize && ret > target_xattr_isize) {
696 		erofs_err("no enough space to keep xattrs @ nid %llu",
697 			  inode->nid | 0ULL);
698 		return -ENOSPC;
699 	}
700 	inode->xattr_isize = ret;
701 	return ret;
702 }
703 
erofs_count_all_xattrs_from_path(const char * path)704 static int erofs_count_all_xattrs_from_path(const char *path)
705 {
706 	int ret;
707 	DIR *_dir;
708 	struct stat st;
709 
710 	_dir = opendir(path);
711 	if (!_dir) {
712 		erofs_err("failed to opendir at %s: %s",
713 			  path, erofs_strerror(-errno));
714 		return -errno;
715 	}
716 
717 	ret = 0;
718 	while (1) {
719 		struct dirent *dp;
720 		char buf[PATH_MAX];
721 
722 		/*
723 		 * set errno to 0 before calling readdir() in order to
724 		 * distinguish end of stream and from an error.
725 		 */
726 		errno = 0;
727 		dp = readdir(_dir);
728 		if (!dp)
729 			break;
730 
731 		if (is_dot_dotdot(dp->d_name) ||
732 		    !strncmp(dp->d_name, "lost+found", strlen("lost+found")))
733 			continue;
734 
735 		ret = snprintf(buf, PATH_MAX, "%s/%s", path, dp->d_name);
736 
737 		if (ret < 0 || ret >= PATH_MAX) {
738 			/* ignore the too long path */
739 			ret = -ENOMEM;
740 			goto fail;
741 		}
742 
743 		ret = lstat(buf, &st);
744 		if (ret) {
745 			ret = -errno;
746 			goto fail;
747 		}
748 
749 		ret = read_xattrs_from_file(buf, st.st_mode, NULL);
750 		if (ret)
751 			goto fail;
752 
753 		if (!S_ISDIR(st.st_mode))
754 			continue;
755 
756 		ret = erofs_count_all_xattrs_from_path(buf);
757 		if (ret)
758 			goto fail;
759 	}
760 
761 	if (errno)
762 		ret = -errno;
763 
764 fail:
765 	closedir(_dir);
766 	return ret;
767 }
768 
erofs_cleanxattrs(bool sharedxattrs)769 static void erofs_cleanxattrs(bool sharedxattrs)
770 {
771 	unsigned int i;
772 	struct xattr_item *item;
773 	struct hlist_node *tmp;
774 
775 	hash_for_each_safe(ea_hashtable, i, tmp, item, node) {
776 		if (sharedxattrs && item->shared_xattr_id >= 0)
777 			continue;
778 
779 		hash_del(&item->node);
780 		free(item);
781 	}
782 
783 	if (sharedxattrs)
784 		return;
785 
786 	shared_xattrs_count = 0;
787 }
788 
comp_shared_xattr_item(const void * a,const void * b)789 static int comp_shared_xattr_item(const void *a, const void *b)
790 {
791 	const struct xattr_item *ia, *ib;
792 	unsigned int la, lb;
793 	int ret;
794 
795 	ia = *((const struct xattr_item **)a);
796 	ib = *((const struct xattr_item **)b);
797 	la = ia->len[0] + ia->len[1];
798 	lb = ib->len[0] + ib->len[1];
799 
800 	ret = strncmp(ia->kvbuf, ib->kvbuf, min(la, lb));
801 	if (ret != 0)
802 		return ret;
803 
804 	return la > lb;
805 }
806 
erofs_xattr_write_name_prefixes(struct erofs_sb_info * sbi,FILE * f)807 int erofs_xattr_write_name_prefixes(struct erofs_sb_info *sbi, FILE *f)
808 {
809 	struct ea_type_node *tnode;
810 	off_t offset;
811 
812 	if (!ea_prefix_count)
813 		return 0;
814 	offset = ftello(f);
815 	if (offset < 0)
816 		return -errno;
817 	if (offset > UINT32_MAX)
818 		return -EOVERFLOW;
819 
820 	offset = round_up(offset, 4);
821 	if (fseek(f, offset, SEEK_SET))
822 		return -errno;
823 	sbi->xattr_prefix_start = (u32)offset >> 2;
824 	sbi->xattr_prefix_count = ea_prefix_count;
825 
826 	list_for_each_entry(tnode, &ea_name_prefixes, list) {
827 		union {
828 			struct {
829 				__le16 size;
830 				struct erofs_xattr_long_prefix prefix;
831 			} s;
832 			u8 data[EROFS_NAME_LEN + 2 +
833 				sizeof(struct erofs_xattr_long_prefix)];
834 		} u;
835 		int len, infix_len;
836 
837 		u.s.prefix.base_index = tnode->base_index;
838 		infix_len = tnode->type.prefix_len - tnode->base_len;
839 		memcpy(u.s.prefix.infix, tnode->type.prefix + tnode->base_len,
840 		       infix_len);
841 		len = sizeof(struct erofs_xattr_long_prefix) + infix_len;
842 		u.s.size = cpu_to_le16(len);
843 		if (fwrite(&u.s, sizeof(__le16) + len, 1, f) != 1)
844 			return -EIO;
845 		offset = round_up(offset + sizeof(__le16) + len, 4);
846 		if (fseek(f, offset, SEEK_SET))
847 			return -errno;
848 	}
849 	erofs_sb_set_fragments(sbi);
850 	erofs_sb_set_xattr_prefixes(sbi);
851 	return 0;
852 }
853 
erofs_write_xattr_entry(char * buf,struct xattr_item * item)854 static void erofs_write_xattr_entry(char *buf, struct xattr_item *item)
855 {
856 	struct erofs_xattr_entry entry = {
857 		.e_name_index = item->prefix,
858 		.e_name_len = item->len[0] - item->prefix_len,
859 		.e_value_size = cpu_to_le16(item->len[1]),
860 	};
861 
862 	memcpy(buf, &entry, sizeof(entry));
863 	buf += sizeof(struct erofs_xattr_entry);
864 	memcpy(buf, item->kvbuf + item->prefix_len,
865 	       item->len[0] - item->prefix_len);
866 	buf += item->len[0] - item->prefix_len;
867 	memcpy(buf, item->kvbuf + item->len[0] + 1, item->len[1]);
868 
869 	erofs_dbg("writing xattr %d %s (%d %s)", item->base_index, item->kvbuf,
870 			item->prefix, item->kvbuf + item->prefix_len);
871 }
872 
erofs_build_shared_xattrs_from_path(struct erofs_sb_info * sbi,const char * path)873 int erofs_build_shared_xattrs_from_path(struct erofs_sb_info *sbi, const char *path)
874 {
875 	int ret;
876 	struct erofs_buffer_head *bh;
877 	struct xattr_item *item, *n, **sorted_n;
878 	char *buf;
879 	unsigned int p, i;
880 	erofs_off_t off;
881 	erofs_off_t shared_xattrs_size = 0;
882 
883 	/* check if xattr or shared xattr is disabled */
884 	if (cfg.c_inline_xattr_tolerance < 0 ||
885 	    cfg.c_inline_xattr_tolerance == INT_MAX)
886 		return 0;
887 
888 	if (shared_xattrs_count) {
889 		DBG_BUGON(1);
890 		return -EINVAL;
891 	}
892 
893 	ret = erofs_count_all_xattrs_from_path(path);
894 	if (ret)
895 		return ret;
896 
897 	if (!shared_xattrs_count)
898 		goto out;
899 
900 	sorted_n = malloc((shared_xattrs_count + 1) * sizeof(n));
901 	if (!sorted_n)
902 		return -ENOMEM;
903 
904 	i = 0;
905 	while (shared_xattrs_list) {
906 		item = shared_xattrs_list;
907 		sorted_n[i++] = item;
908 		shared_xattrs_list = item->next_shared_xattr;
909 		shared_xattrs_size = erofs_next_xattr_align(shared_xattrs_size,
910 							    item);
911 	}
912 	DBG_BUGON(i != shared_xattrs_count);
913 	sorted_n[i] = NULL;
914 	qsort(sorted_n, shared_xattrs_count, sizeof(n), comp_shared_xattr_item);
915 
916 	buf = calloc(1, shared_xattrs_size);
917 	if (!buf) {
918 		free(sorted_n);
919 		return -ENOMEM;
920 	}
921 
922 	bh = erofs_balloc(sbi->bmgr, XATTR, shared_xattrs_size, 0, 0);
923 	if (IS_ERR(bh)) {
924 		free(sorted_n);
925 		free(buf);
926 		return PTR_ERR(bh);
927 	}
928 	bh->op = &erofs_skip_write_bhops;
929 
930 	erofs_mapbh(NULL, bh->block);
931 	off = erofs_btell(bh, false);
932 
933 	sbi->xattr_blkaddr = off / erofs_blksiz(sbi);
934 	off %= erofs_blksiz(sbi);
935 	p = 0;
936 	for (i = 0; i < shared_xattrs_count; i++) {
937 		item = sorted_n[i];
938 		erofs_write_xattr_entry(buf + p, item);
939 		item->next_shared_xattr = sorted_n[i + 1];
940 		item->shared_xattr_id = (off + p) / sizeof(__le32);
941 		p = erofs_next_xattr_align(p, item);
942 	}
943 	shared_xattrs_list = sorted_n[0];
944 	free(sorted_n);
945 	bh->op = &erofs_drop_directly_bhops;
946 	ret = erofs_dev_write(sbi, buf, erofs_btell(bh, false), shared_xattrs_size);
947 	free(buf);
948 	erofs_bdrop(bh, false);
949 out:
950 	erofs_cleanxattrs(true);
951 	return ret;
952 }
953 
erofs_export_xattr_ibody(struct erofs_inode * inode)954 char *erofs_export_xattr_ibody(struct erofs_inode *inode)
955 {
956 	struct list_head *ixattrs = &inode->i_xattrs;
957 	unsigned int size = inode->xattr_isize;
958 	struct inode_xattr_node *node, *n;
959 	struct xattr_item *item;
960 	struct erofs_xattr_ibody_header *header;
961 	LIST_HEAD(ilst);
962 	unsigned int p;
963 	char *buf = calloc(1, size);
964 
965 	if (!buf)
966 		return ERR_PTR(-ENOMEM);
967 
968 	header = (struct erofs_xattr_ibody_header *)buf;
969 	header->h_shared_count = 0;
970 
971 	if (cfg.c_xattr_name_filter) {
972 		u32 name_filter = 0;
973 		int hashbit;
974 		unsigned int base_len;
975 
976 		list_for_each_entry(node, ixattrs, list) {
977 			item = node->item;
978 			base_len = xattr_types[item->base_index].prefix_len;
979 			hashbit = xxh32(item->kvbuf + base_len,
980 					item->len[0] - base_len,
981 					EROFS_XATTR_FILTER_SEED + item->base_index) &
982 				  (EROFS_XATTR_FILTER_BITS - 1);
983 			name_filter |= (1UL << hashbit);
984 		}
985 		name_filter = EROFS_XATTR_FILTER_DEFAULT & ~name_filter;
986 
987 		header->h_name_filter = cpu_to_le32(name_filter);
988 		if (header->h_name_filter)
989 			erofs_sb_set_xattr_filter(inode->sbi);
990 	}
991 
992 	p = sizeof(struct erofs_xattr_ibody_header);
993 	list_for_each_entry_safe(node, n, ixattrs, list) {
994 		item = node->item;
995 		list_del(&node->list);
996 
997 		/* move inline xattrs to the onstack list */
998 		if (item->shared_xattr_id < 0 ||
999 		    header->h_shared_count >= UCHAR_MAX) {
1000 			list_add(&node->list, &ilst);
1001 			continue;
1002 		}
1003 
1004 		*(__le32 *)(buf + p) = cpu_to_le32(item->shared_xattr_id);
1005 		p += sizeof(__le32);
1006 		++header->h_shared_count;
1007 		free(node);
1008 		put_xattritem(item);
1009 	}
1010 
1011 	list_for_each_entry_safe(node, n, &ilst, list) {
1012 		item = node->item;
1013 		erofs_write_xattr_entry(buf + p, item);
1014 		p = erofs_next_xattr_align(p, item);
1015 		list_del(&node->list);
1016 		free(node);
1017 		put_xattritem(item);
1018 	}
1019 	if (p < size) {
1020 		memset(buf + p, 0, size - p);
1021 	} else if (__erofs_unlikely(p > size)) {
1022 		DBG_BUGON(1);
1023 		free(buf);
1024 		return ERR_PTR(-EFAULT);
1025 	}
1026 	return buf;
1027 }
1028 
1029 struct xattr_iter {
1030 	char page[EROFS_MAX_BLOCK_SIZE];
1031 
1032 	void *kaddr;
1033 
1034 	erofs_blk_t blkaddr;
1035 	unsigned int ofs;
1036 	struct erofs_sb_info *sbi;
1037 };
1038 
init_inode_xattrs(struct erofs_inode * vi)1039 static int init_inode_xattrs(struct erofs_inode *vi)
1040 {
1041 	struct erofs_sb_info *sbi = vi->sbi;
1042 	struct xattr_iter it;
1043 	unsigned int i;
1044 	struct erofs_xattr_ibody_header *ih;
1045 	int ret = 0;
1046 
1047 	/* the most case is that xattrs of this inode are initialized. */
1048 	if (vi->flags & EROFS_I_EA_INITED)
1049 		return ret;
1050 
1051 	/*
1052 	 * bypass all xattr operations if ->xattr_isize is not greater than
1053 	 * sizeof(struct erofs_xattr_ibody_header), in detail:
1054 	 * 1) it is not enough to contain erofs_xattr_ibody_header then
1055 	 *    ->xattr_isize should be 0 (it means no xattr);
1056 	 * 2) it is just to contain erofs_xattr_ibody_header, which is on-disk
1057 	 *    undefined right now (maybe use later with some new sb feature).
1058 	 */
1059 	if (vi->xattr_isize == sizeof(struct erofs_xattr_ibody_header)) {
1060 		erofs_err("xattr_isize %d of nid %llu is not supported yet",
1061 			  vi->xattr_isize, vi->nid);
1062 		return -EOPNOTSUPP;
1063 	} else if (vi->xattr_isize < sizeof(struct erofs_xattr_ibody_header)) {
1064 		if (vi->xattr_isize) {
1065 			erofs_err("bogus xattr ibody @ nid %llu", vi->nid);
1066 			DBG_BUGON(1);
1067 			return -EFSCORRUPTED;	/* xattr ondisk layout error */
1068 		}
1069 		return -ENOATTR;
1070 	}
1071 
1072 	it.blkaddr = erofs_blknr(sbi, erofs_iloc(vi) + vi->inode_isize);
1073 	it.ofs = erofs_blkoff(sbi, erofs_iloc(vi) + vi->inode_isize);
1074 
1075 	ret = erofs_blk_read(sbi, 0, it.page, it.blkaddr, 1);
1076 	if (ret < 0)
1077 		return -EIO;
1078 
1079 	it.kaddr = it.page;
1080 	ih = (struct erofs_xattr_ibody_header *)(it.kaddr + it.ofs);
1081 
1082 	vi->xattr_shared_count = ih->h_shared_count;
1083 	vi->xattr_shared_xattrs = malloc(vi->xattr_shared_count * sizeof(uint));
1084 	if (!vi->xattr_shared_xattrs)
1085 		return -ENOMEM;
1086 
1087 	/* let's skip ibody header */
1088 	it.ofs += sizeof(struct erofs_xattr_ibody_header);
1089 
1090 	for (i = 0; i < vi->xattr_shared_count; ++i) {
1091 		if (it.ofs >= erofs_blksiz(sbi)) {
1092 			/* cannot be unaligned */
1093 			DBG_BUGON(it.ofs != erofs_blksiz(sbi));
1094 
1095 			ret = erofs_blk_read(sbi, 0, it.page, ++it.blkaddr, 1);
1096 			if (ret < 0) {
1097 				free(vi->xattr_shared_xattrs);
1098 				vi->xattr_shared_xattrs = NULL;
1099 				return -EIO;
1100 			}
1101 
1102 			it.kaddr = it.page;
1103 			it.ofs = 0;
1104 		}
1105 		vi->xattr_shared_xattrs[i] =
1106 			le32_to_cpu(*(__le32 *)(it.kaddr + it.ofs));
1107 		it.ofs += sizeof(__le32);
1108 	}
1109 
1110 	vi->flags |= EROFS_I_EA_INITED;
1111 
1112 	return ret;
1113 }
1114 
1115 /*
1116  * the general idea for these return values is
1117  * if    0 is returned, go on processing the current xattr;
1118  *       1 (> 0) is returned, skip this round to process the next xattr;
1119  *    -err (< 0) is returned, an error (maybe ENOXATTR) occurred
1120  *                            and need to be handled
1121  */
1122 struct xattr_iter_handlers {
1123 	int (*entry)(struct xattr_iter *_it, struct erofs_xattr_entry *entry);
1124 	int (*name)(struct xattr_iter *_it, unsigned int processed, char *buf,
1125 		    unsigned int len);
1126 	int (*alloc_buffer)(struct xattr_iter *_it, unsigned int value_sz);
1127 	void (*value)(struct xattr_iter *_it, unsigned int processed, char *buf,
1128 		      unsigned int len);
1129 };
1130 
xattr_iter_fixup(struct xattr_iter * it)1131 static inline int xattr_iter_fixup(struct xattr_iter *it)
1132 {
1133 	struct erofs_sb_info *sbi = it->sbi;
1134 	int ret;
1135 
1136 	if (it->ofs < erofs_blksiz(sbi))
1137 		return 0;
1138 
1139 	it->blkaddr += erofs_blknr(sbi, it->ofs);
1140 
1141 	ret = erofs_blk_read(sbi, 0, it->page, it->blkaddr, 1);
1142 	if (ret < 0)
1143 		return -EIO;
1144 
1145 	it->kaddr = it->page;
1146 	it->ofs = erofs_blkoff(sbi, it->ofs);
1147 	return 0;
1148 }
1149 
inline_xattr_iter_pre(struct xattr_iter * it,struct erofs_inode * vi)1150 static int inline_xattr_iter_pre(struct xattr_iter *it,
1151 				   struct erofs_inode *vi)
1152 {
1153 	struct erofs_sb_info *sbi = vi->sbi;
1154 	unsigned int xattr_header_sz, inline_xattr_ofs;
1155 	int ret;
1156 
1157 	xattr_header_sz = inlinexattr_header_size(vi);
1158 	if (xattr_header_sz >= vi->xattr_isize) {
1159 		DBG_BUGON(xattr_header_sz > vi->xattr_isize);
1160 		return -ENOATTR;
1161 	}
1162 
1163 	inline_xattr_ofs = vi->inode_isize + xattr_header_sz;
1164 
1165 	it->blkaddr = erofs_blknr(sbi, erofs_iloc(vi) + inline_xattr_ofs);
1166 	it->ofs = erofs_blkoff(sbi, erofs_iloc(vi) + inline_xattr_ofs);
1167 
1168 	ret = erofs_blk_read(sbi, 0, it->page, it->blkaddr, 1);
1169 	if (ret < 0)
1170 		return -EIO;
1171 
1172 	it->kaddr = it->page;
1173 	return vi->xattr_isize - xattr_header_sz;
1174 }
1175 
1176 /*
1177  * Regardless of success or failure, `xattr_foreach' will end up with
1178  * `ofs' pointing to the next xattr item rather than an arbitrary position.
1179  */
xattr_foreach(struct xattr_iter * it,const struct xattr_iter_handlers * op,unsigned int * tlimit)1180 static int xattr_foreach(struct xattr_iter *it,
1181 			 const struct xattr_iter_handlers *op,
1182 			 unsigned int *tlimit)
1183 {
1184 	struct erofs_sb_info *sbi = it->sbi;
1185 	struct erofs_xattr_entry entry;
1186 	unsigned int value_sz, processed, slice;
1187 	int err;
1188 
1189 	/* 0. fixup blkaddr, ofs, ipage */
1190 	err = xattr_iter_fixup(it);
1191 	if (err)
1192 		return err;
1193 
1194 	/*
1195 	 * 1. read xattr entry to the memory,
1196 	 *    since we do EROFS_XATTR_ALIGN
1197 	 *    therefore entry should be in the page
1198 	 */
1199 	entry = *(struct erofs_xattr_entry *)(it->kaddr + it->ofs);
1200 	if (tlimit) {
1201 		unsigned int entry_sz = erofs_xattr_entry_size(&entry);
1202 
1203 		/* xattr on-disk corruption: xattr entry beyond xattr_isize */
1204 		if (*tlimit < entry_sz) {
1205 			DBG_BUGON(1);
1206 			return -EFSCORRUPTED;
1207 		}
1208 		*tlimit -= entry_sz;
1209 	}
1210 
1211 	it->ofs += sizeof(struct erofs_xattr_entry);
1212 	value_sz = le16_to_cpu(entry.e_value_size);
1213 
1214 	/* handle entry */
1215 	err = op->entry(it, &entry);
1216 	if (err) {
1217 		it->ofs += entry.e_name_len + value_sz;
1218 		goto out;
1219 	}
1220 
1221 	/* 2. handle xattr name (ofs will finally be at the end of name) */
1222 	processed = 0;
1223 
1224 	while (processed < entry.e_name_len) {
1225 		if (it->ofs >= erofs_blksiz(sbi)) {
1226 			DBG_BUGON(it->ofs > erofs_blksiz(sbi));
1227 
1228 			err = xattr_iter_fixup(it);
1229 			if (err)
1230 				goto out;
1231 			it->ofs = 0;
1232 		}
1233 
1234 		slice = min_t(unsigned int, erofs_blksiz(sbi) - it->ofs,
1235 			      entry.e_name_len - processed);
1236 
1237 		/* handle name */
1238 		err = op->name(it, processed, it->kaddr + it->ofs, slice);
1239 		if (err) {
1240 			it->ofs += entry.e_name_len - processed + value_sz;
1241 			goto out;
1242 		}
1243 
1244 		it->ofs += slice;
1245 		processed += slice;
1246 	}
1247 
1248 	/* 3. handle xattr value */
1249 	processed = 0;
1250 
1251 	if (op->alloc_buffer) {
1252 		err = op->alloc_buffer(it, value_sz);
1253 		if (err) {
1254 			it->ofs += value_sz;
1255 			goto out;
1256 		}
1257 	}
1258 
1259 	while (processed < value_sz) {
1260 		if (it->ofs >= erofs_blksiz(sbi)) {
1261 			DBG_BUGON(it->ofs > erofs_blksiz(sbi));
1262 
1263 			err = xattr_iter_fixup(it);
1264 			if (err)
1265 				goto out;
1266 			it->ofs = 0;
1267 		}
1268 
1269 		slice = min_t(unsigned int, erofs_blksiz(sbi) - it->ofs,
1270 			      value_sz - processed);
1271 		op->value(it, processed, it->kaddr + it->ofs, slice);
1272 		it->ofs += slice;
1273 		processed += slice;
1274 	}
1275 
1276 out:
1277 	/* xattrs should be 4-byte aligned (on-disk constraint) */
1278 	it->ofs = EROFS_XATTR_ALIGN(it->ofs);
1279 	return err < 0 ? err : 0;
1280 }
1281 
1282 struct getxattr_iter {
1283 	struct xattr_iter it;
1284 
1285 	int buffer_size, index, infix_len;
1286 	char *buffer;
1287 	const char *name;
1288 	size_t len;
1289 };
1290 
erofs_xattr_long_entrymatch(struct getxattr_iter * it,struct erofs_xattr_entry * entry)1291 static int erofs_xattr_long_entrymatch(struct getxattr_iter *it,
1292 				       struct erofs_xattr_entry *entry)
1293 {
1294 	struct erofs_sb_info *sbi = it->it.sbi;
1295 	struct erofs_xattr_prefix_item *pf = sbi->xattr_prefixes +
1296 		(entry->e_name_index & EROFS_XATTR_LONG_PREFIX_MASK);
1297 
1298 	if (pf >= sbi->xattr_prefixes + sbi->xattr_prefix_count)
1299 		return -ENOATTR;
1300 
1301 	if (it->index != pf->prefix->base_index ||
1302 	    it->len != entry->e_name_len + pf->infix_len)
1303 		return -ENOATTR;
1304 
1305 	if (memcmp(it->name, pf->prefix->infix, pf->infix_len))
1306 		return -ENOATTR;
1307 
1308 	it->infix_len = pf->infix_len;
1309 	return 0;
1310 }
1311 
xattr_entrymatch(struct xattr_iter * _it,struct erofs_xattr_entry * entry)1312 static int xattr_entrymatch(struct xattr_iter *_it,
1313 			    struct erofs_xattr_entry *entry)
1314 {
1315 	struct getxattr_iter *it = container_of(_it, struct getxattr_iter, it);
1316 
1317 	/* should also match the infix for long name prefixes */
1318 	if (entry->e_name_index & EROFS_XATTR_LONG_PREFIX)
1319 		return erofs_xattr_long_entrymatch(it, entry);
1320 
1321 	if (it->index != entry->e_name_index ||
1322 	    it->len != entry->e_name_len)
1323 		return -ENOATTR;
1324 	it->infix_len = 0;
1325 	return 0;
1326 }
1327 
xattr_namematch(struct xattr_iter * _it,unsigned int processed,char * buf,unsigned int len)1328 static int xattr_namematch(struct xattr_iter *_it,
1329 			   unsigned int processed, char *buf, unsigned int len)
1330 {
1331 	struct getxattr_iter *it = container_of(_it, struct getxattr_iter, it);
1332 
1333 	if (memcmp(buf, it->name + it->infix_len + processed, len))
1334 		return -ENOATTR;
1335 	return 0;
1336 }
1337 
xattr_checkbuffer(struct xattr_iter * _it,unsigned int value_sz)1338 static int xattr_checkbuffer(struct xattr_iter *_it,
1339 			     unsigned int value_sz)
1340 {
1341 	struct getxattr_iter *it = container_of(_it, struct getxattr_iter, it);
1342 	int err = it->buffer_size < value_sz ? -ERANGE : 0;
1343 
1344 	it->buffer_size = value_sz;
1345 	return !it->buffer ? 1 : err;
1346 }
1347 
xattr_copyvalue(struct xattr_iter * _it,unsigned int processed,char * buf,unsigned int len)1348 static void xattr_copyvalue(struct xattr_iter *_it,
1349 			    unsigned int processed,
1350 			    char *buf, unsigned int len)
1351 {
1352 	struct getxattr_iter *it = container_of(_it, struct getxattr_iter, it);
1353 
1354 	memcpy(it->buffer + processed, buf, len);
1355 }
1356 
1357 static const struct xattr_iter_handlers find_xattr_handlers = {
1358 	.entry = xattr_entrymatch,
1359 	.name = xattr_namematch,
1360 	.alloc_buffer = xattr_checkbuffer,
1361 	.value = xattr_copyvalue
1362 };
1363 
inline_getxattr(struct erofs_inode * vi,struct getxattr_iter * it)1364 static int inline_getxattr(struct erofs_inode *vi, struct getxattr_iter *it)
1365 {
1366 	int ret;
1367 	unsigned int remaining;
1368 
1369 	ret = inline_xattr_iter_pre(&it->it, vi);
1370 	if (ret < 0)
1371 		return ret;
1372 
1373 	remaining = ret;
1374 	while (remaining) {
1375 		ret = xattr_foreach(&it->it, &find_xattr_handlers, &remaining);
1376 		if (ret != -ENOATTR)
1377 			break;
1378 	}
1379 
1380 	return ret ? ret : it->buffer_size;
1381 }
1382 
shared_getxattr(struct erofs_inode * vi,struct getxattr_iter * it)1383 static int shared_getxattr(struct erofs_inode *vi, struct getxattr_iter *it)
1384 {
1385 	unsigned int i;
1386 	int ret = -ENOATTR;
1387 
1388 	for (i = 0; i < vi->xattr_shared_count; ++i) {
1389 		erofs_blk_t blkaddr =
1390 			xattrblock_addr(vi, vi->xattr_shared_xattrs[i]);
1391 
1392 		it->it.ofs = xattrblock_offset(vi, vi->xattr_shared_xattrs[i]);
1393 
1394 		if (!i || blkaddr != it->it.blkaddr) {
1395 			ret = erofs_blk_read(vi->sbi, 0, it->it.page, blkaddr, 1);
1396 			if (ret < 0)
1397 				return -EIO;
1398 
1399 			it->it.kaddr = it->it.page;
1400 			it->it.blkaddr = blkaddr;
1401 		}
1402 
1403 		ret = xattr_foreach(&it->it, &find_xattr_handlers, NULL);
1404 		if (ret != -ENOATTR)
1405 			break;
1406 	}
1407 
1408 	return ret ? ret : it->buffer_size;
1409 }
1410 
erofs_getxattr(struct erofs_inode * vi,const char * name,char * buffer,size_t buffer_size)1411 int erofs_getxattr(struct erofs_inode *vi, const char *name, char *buffer,
1412 		   size_t buffer_size)
1413 {
1414 	int ret;
1415 	unsigned int prefix, prefixlen;
1416 	struct getxattr_iter it;
1417 
1418 	if (!name)
1419 		return -EINVAL;
1420 
1421 	ret = init_inode_xattrs(vi);
1422 	if (ret)
1423 		return ret;
1424 
1425 	if (!match_prefix(name, &prefix, &prefixlen))
1426 		return -ENODATA;
1427 
1428 	it.it.sbi = vi->sbi;
1429 	it.index = prefix;
1430 	it.name = name + prefixlen;
1431 	it.len = strlen(it.name);
1432 	if (it.len > EROFS_NAME_LEN)
1433 		return -ERANGE;
1434 
1435 	it.buffer = buffer;
1436 	it.buffer_size = buffer_size;
1437 
1438 	ret = inline_getxattr(vi, &it);
1439 	if (ret == -ENOATTR)
1440 		ret = shared_getxattr(vi, &it);
1441 	return ret;
1442 }
1443 
1444 struct listxattr_iter {
1445 	struct xattr_iter it;
1446 
1447 	char *buffer;
1448 	int buffer_size, buffer_ofs;
1449 };
1450 
xattr_entrylist(struct xattr_iter * _it,struct erofs_xattr_entry * entry)1451 static int xattr_entrylist(struct xattr_iter *_it,
1452 			   struct erofs_xattr_entry *entry)
1453 {
1454 	struct listxattr_iter *it =
1455 		container_of(_it, struct listxattr_iter, it);
1456 	unsigned int base_index = entry->e_name_index;
1457 	unsigned int prefix_len, infix_len = 0;
1458 	const char *prefix, *infix = NULL;
1459 
1460 	if (entry->e_name_index & EROFS_XATTR_LONG_PREFIX) {
1461 		struct erofs_sb_info *sbi = _it->sbi;
1462 		struct erofs_xattr_prefix_item *pf = sbi->xattr_prefixes +
1463 			(entry->e_name_index & EROFS_XATTR_LONG_PREFIX_MASK);
1464 
1465 		if (pf >= sbi->xattr_prefixes + sbi->xattr_prefix_count)
1466 			return 1;
1467 		infix = pf->prefix->infix;
1468 		infix_len = pf->infix_len;
1469 		base_index = pf->prefix->base_index;
1470 	}
1471 
1472 	if (!base_index || base_index >= ARRAY_SIZE(xattr_types))
1473 		return 1;
1474 	prefix = xattr_types[base_index].prefix;
1475 	prefix_len = xattr_types[base_index].prefix_len;
1476 
1477 	if (!it->buffer) {
1478 		it->buffer_ofs += prefix_len + infix_len +
1479 					entry->e_name_len + 1;
1480 		return 1;
1481 	}
1482 
1483 	if (it->buffer_ofs + prefix_len + infix_len
1484 		+ entry->e_name_len + 1 > it->buffer_size)
1485 		return -ERANGE;
1486 
1487 	memcpy(it->buffer + it->buffer_ofs, prefix, prefix_len);
1488 	memcpy(it->buffer + it->buffer_ofs + prefix_len, infix, infix_len);
1489 	it->buffer_ofs += prefix_len + infix_len;
1490 	return 0;
1491 }
1492 
xattr_namelist(struct xattr_iter * _it,unsigned int processed,char * buf,unsigned int len)1493 static int xattr_namelist(struct xattr_iter *_it,
1494 			  unsigned int processed, char *buf, unsigned int len)
1495 {
1496 	struct listxattr_iter *it =
1497 		container_of(_it, struct listxattr_iter, it);
1498 
1499 	memcpy(it->buffer + it->buffer_ofs, buf, len);
1500 	it->buffer_ofs += len;
1501 	return 0;
1502 }
1503 
xattr_skipvalue(struct xattr_iter * _it,unsigned int value_sz)1504 static int xattr_skipvalue(struct xattr_iter *_it,
1505 			   unsigned int value_sz)
1506 {
1507 	struct listxattr_iter *it =
1508 		container_of(_it, struct listxattr_iter, it);
1509 
1510 	it->buffer[it->buffer_ofs++] = '\0';
1511 	return 1;
1512 }
1513 
1514 static const struct xattr_iter_handlers list_xattr_handlers = {
1515 	.entry = xattr_entrylist,
1516 	.name = xattr_namelist,
1517 	.alloc_buffer = xattr_skipvalue,
1518 	.value = NULL
1519 };
1520 
inline_listxattr(struct erofs_inode * vi,struct listxattr_iter * it)1521 static int inline_listxattr(struct erofs_inode *vi, struct listxattr_iter *it)
1522 {
1523 	int ret;
1524 	unsigned int remaining;
1525 
1526 	ret = inline_xattr_iter_pre(&it->it, vi);
1527 	if (ret < 0)
1528 		return ret;
1529 
1530 	remaining = ret;
1531 	while (remaining) {
1532 		ret = xattr_foreach(&it->it, &list_xattr_handlers, &remaining);
1533 		if (ret)
1534 			break;
1535 	}
1536 
1537 	return ret ? ret : it->buffer_ofs;
1538 }
1539 
shared_listxattr(struct erofs_inode * vi,struct listxattr_iter * it)1540 static int shared_listxattr(struct erofs_inode *vi, struct listxattr_iter *it)
1541 {
1542 	unsigned int i;
1543 	int ret = 0;
1544 
1545 	for (i = 0; i < vi->xattr_shared_count; ++i) {
1546 		erofs_blk_t blkaddr =
1547 			xattrblock_addr(vi, vi->xattr_shared_xattrs[i]);
1548 
1549 		it->it.ofs = xattrblock_offset(vi, vi->xattr_shared_xattrs[i]);
1550 		if (!i || blkaddr != it->it.blkaddr) {
1551 			ret = erofs_blk_read(vi->sbi, 0, it->it.page, blkaddr, 1);
1552 			if (ret < 0)
1553 				return -EIO;
1554 
1555 			it->it.kaddr = it->it.page;
1556 			it->it.blkaddr = blkaddr;
1557 		}
1558 
1559 		ret = xattr_foreach(&it->it, &list_xattr_handlers, NULL);
1560 		if (ret)
1561 			break;
1562 	}
1563 
1564 	return ret ? ret : it->buffer_ofs;
1565 }
1566 
erofs_listxattr(struct erofs_inode * vi,char * buffer,size_t buffer_size)1567 int erofs_listxattr(struct erofs_inode *vi, char *buffer, size_t buffer_size)
1568 {
1569 	int ret;
1570 	struct listxattr_iter it;
1571 
1572 	ret = init_inode_xattrs(vi);
1573 	if (ret == -ENOATTR)
1574 		return 0;
1575 	if (ret)
1576 		return ret;
1577 
1578 	it.it.sbi = vi->sbi;
1579 	it.buffer = buffer;
1580 	it.buffer_size = buffer_size;
1581 	it.buffer_ofs = 0;
1582 
1583 	ret = inline_listxattr(vi, &it);
1584 	if (ret < 0 && ret != -ENOATTR)
1585 		return ret;
1586 	return shared_listxattr(vi, &it);
1587 }
1588 
erofs_xattr_insert_name_prefix(const char * prefix)1589 int erofs_xattr_insert_name_prefix(const char *prefix)
1590 {
1591 	struct ea_type_node *tnode;
1592 
1593 	if (ea_prefix_count >= 0x80 || strlen(prefix) > UINT8_MAX)
1594 		return -EOVERFLOW;
1595 
1596 	tnode = calloc(1, sizeof(*tnode));
1597 	if (!tnode)
1598 		return -ENOMEM;
1599 
1600 	if (!match_prefix(prefix, &tnode->base_index, &tnode->base_len)) {
1601 		free(tnode);
1602 		return -ENODATA;
1603 	}
1604 
1605 	tnode->type.prefix_len = strlen(prefix);
1606 	tnode->type.prefix = strdup(prefix);
1607 	if (!tnode->type.prefix) {
1608 		free(tnode);
1609 		return -ENOMEM;
1610 	}
1611 
1612 	tnode->index = EROFS_XATTR_LONG_PREFIX | ea_prefix_count;
1613 	ea_prefix_count++;
1614 	init_list_head(&tnode->list);
1615 	list_add_tail(&tnode->list, &ea_name_prefixes);
1616 	return 0;
1617 }
1618 
erofs_xattr_cleanup_name_prefixes(void)1619 void erofs_xattr_cleanup_name_prefixes(void)
1620 {
1621 	struct ea_type_node *tnode, *n;
1622 
1623 	list_for_each_entry_safe(tnode, n, &ea_name_prefixes, list) {
1624 		list_del(&tnode->list);
1625 		free((void *)tnode->type.prefix);
1626 		free(tnode);
1627 	}
1628 }
1629 
erofs_xattr_prefixes_cleanup(struct erofs_sb_info * sbi)1630 void erofs_xattr_prefixes_cleanup(struct erofs_sb_info *sbi)
1631 {
1632 	int i;
1633 
1634 	if (sbi->xattr_prefixes) {
1635 		for (i = 0; i < sbi->xattr_prefix_count; i++)
1636 			free(sbi->xattr_prefixes[i].prefix);
1637 		free(sbi->xattr_prefixes);
1638 		sbi->xattr_prefixes = NULL;
1639 	}
1640 }
1641 
erofs_xattr_prefixes_init(struct erofs_sb_info * sbi)1642 int erofs_xattr_prefixes_init(struct erofs_sb_info *sbi)
1643 {
1644 	erofs_off_t pos = (erofs_off_t)sbi->xattr_prefix_start << 2;
1645 	struct erofs_xattr_prefix_item *pfs;
1646 	erofs_nid_t nid = 0;
1647 	int ret = 0, i, len;
1648 	void *buf;
1649 
1650 	if (!sbi->xattr_prefix_count)
1651 		return 0;
1652 
1653 	if (sbi->packed_nid)
1654 		nid = sbi->packed_nid;
1655 
1656 	pfs = calloc(sbi->xattr_prefix_count, sizeof(*pfs));
1657 	if (!pfs)
1658 		return -ENOMEM;
1659 
1660 	for (i = 0; i < sbi->xattr_prefix_count; i++) {
1661 		buf = erofs_read_metadata(sbi, nid, &pos, &len);
1662 		if (IS_ERR(buf)) {
1663 			ret = PTR_ERR(buf);
1664 			goto out;
1665 		}
1666 		if (len < sizeof(*pfs->prefix) ||
1667 		    len > EROFS_NAME_LEN + sizeof(*pfs->prefix)) {
1668 			free(buf);
1669 			ret = -EFSCORRUPTED;
1670 			goto out;
1671 		}
1672 		pfs[i].prefix = buf;
1673 		pfs[i].infix_len = len - sizeof(struct erofs_xattr_long_prefix);
1674 	}
1675 out:
1676 	sbi->xattr_prefixes = pfs;
1677 	if (ret)
1678 		erofs_xattr_prefixes_cleanup(sbi);
1679 	return ret;
1680 }
1681