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