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