xref: /openbmc/linux/fs/btrfs/xattr.c (revision a9a08845)
1 /*
2  * Copyright (C) 2007 Red Hat.  All rights reserved.
3  *
4  * This program is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU General Public
6  * License v2 as published by the Free Software Foundation.
7  *
8  * This program is distributed in the hope that it will be useful,
9  * but WITHOUT ANY WARRANTY; without even the implied warranty of
10  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
11  * General Public License for more details.
12  *
13  * You should have received a copy of the GNU General Public
14  * License along with this program; if not, write to the
15  * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
16  * Boston, MA 021110-1307, USA.
17  */
18 
19 #include <linux/init.h>
20 #include <linux/fs.h>
21 #include <linux/slab.h>
22 #include <linux/rwsem.h>
23 #include <linux/xattr.h>
24 #include <linux/security.h>
25 #include <linux/posix_acl_xattr.h>
26 #include <linux/iversion.h>
27 #include "ctree.h"
28 #include "btrfs_inode.h"
29 #include "transaction.h"
30 #include "xattr.h"
31 #include "disk-io.h"
32 #include "props.h"
33 #include "locking.h"
34 
35 
36 ssize_t __btrfs_getxattr(struct inode *inode, const char *name,
37 				void *buffer, size_t size)
38 {
39 	struct btrfs_dir_item *di;
40 	struct btrfs_root *root = BTRFS_I(inode)->root;
41 	struct btrfs_path *path;
42 	struct extent_buffer *leaf;
43 	int ret = 0;
44 	unsigned long data_ptr;
45 
46 	path = btrfs_alloc_path();
47 	if (!path)
48 		return -ENOMEM;
49 
50 	/* lookup the xattr by name */
51 	di = btrfs_lookup_xattr(NULL, root, path, btrfs_ino(BTRFS_I(inode)),
52 			name, strlen(name), 0);
53 	if (!di) {
54 		ret = -ENODATA;
55 		goto out;
56 	} else if (IS_ERR(di)) {
57 		ret = PTR_ERR(di);
58 		goto out;
59 	}
60 
61 	leaf = path->nodes[0];
62 	/* if size is 0, that means we want the size of the attr */
63 	if (!size) {
64 		ret = btrfs_dir_data_len(leaf, di);
65 		goto out;
66 	}
67 
68 	/* now get the data out of our dir_item */
69 	if (btrfs_dir_data_len(leaf, di) > size) {
70 		ret = -ERANGE;
71 		goto out;
72 	}
73 
74 	/*
75 	 * The way things are packed into the leaf is like this
76 	 * |struct btrfs_dir_item|name|data|
77 	 * where name is the xattr name, so security.foo, and data is the
78 	 * content of the xattr.  data_ptr points to the location in memory
79 	 * where the data starts in the in memory leaf
80 	 */
81 	data_ptr = (unsigned long)((char *)(di + 1) +
82 				   btrfs_dir_name_len(leaf, di));
83 	read_extent_buffer(leaf, buffer, data_ptr,
84 			   btrfs_dir_data_len(leaf, di));
85 	ret = btrfs_dir_data_len(leaf, di);
86 
87 out:
88 	btrfs_free_path(path);
89 	return ret;
90 }
91 
92 static int do_setxattr(struct btrfs_trans_handle *trans,
93 		       struct inode *inode, const char *name,
94 		       const void *value, size_t size, int flags)
95 {
96 	struct btrfs_dir_item *di = NULL;
97 	struct btrfs_root *root = BTRFS_I(inode)->root;
98 	struct btrfs_fs_info *fs_info = root->fs_info;
99 	struct btrfs_path *path;
100 	size_t name_len = strlen(name);
101 	int ret = 0;
102 
103 	if (name_len + size > BTRFS_MAX_XATTR_SIZE(root->fs_info))
104 		return -ENOSPC;
105 
106 	path = btrfs_alloc_path();
107 	if (!path)
108 		return -ENOMEM;
109 	path->skip_release_on_error = 1;
110 
111 	if (!value) {
112 		di = btrfs_lookup_xattr(trans, root, path,
113 				btrfs_ino(BTRFS_I(inode)), name, name_len, -1);
114 		if (!di && (flags & XATTR_REPLACE))
115 			ret = -ENODATA;
116 		else if (IS_ERR(di))
117 			ret = PTR_ERR(di);
118 		else if (di)
119 			ret = btrfs_delete_one_dir_name(trans, root, path, di);
120 		goto out;
121 	}
122 
123 	/*
124 	 * For a replace we can't just do the insert blindly.
125 	 * Do a lookup first (read-only btrfs_search_slot), and return if xattr
126 	 * doesn't exist. If it exists, fall down below to the insert/replace
127 	 * path - we can't race with a concurrent xattr delete, because the VFS
128 	 * locks the inode's i_mutex before calling setxattr or removexattr.
129 	 */
130 	if (flags & XATTR_REPLACE) {
131 		ASSERT(inode_is_locked(inode));
132 		di = btrfs_lookup_xattr(NULL, root, path,
133 				btrfs_ino(BTRFS_I(inode)), name, name_len, 0);
134 		if (!di)
135 			ret = -ENODATA;
136 		else if (IS_ERR(di))
137 			ret = PTR_ERR(di);
138 		if (ret)
139 			goto out;
140 		btrfs_release_path(path);
141 		di = NULL;
142 	}
143 
144 	ret = btrfs_insert_xattr_item(trans, root, path, btrfs_ino(BTRFS_I(inode)),
145 				      name, name_len, value, size);
146 	if (ret == -EOVERFLOW) {
147 		/*
148 		 * We have an existing item in a leaf, split_leaf couldn't
149 		 * expand it. That item might have or not a dir_item that
150 		 * matches our target xattr, so lets check.
151 		 */
152 		ret = 0;
153 		btrfs_assert_tree_locked(path->nodes[0]);
154 		di = btrfs_match_dir_item_name(fs_info, path, name, name_len);
155 		if (!di && !(flags & XATTR_REPLACE)) {
156 			ret = -ENOSPC;
157 			goto out;
158 		}
159 	} else if (ret == -EEXIST) {
160 		ret = 0;
161 		di = btrfs_match_dir_item_name(fs_info, path, name, name_len);
162 		ASSERT(di); /* logic error */
163 	} else if (ret) {
164 		goto out;
165 	}
166 
167 	if (di && (flags & XATTR_CREATE)) {
168 		ret = -EEXIST;
169 		goto out;
170 	}
171 
172 	if (di) {
173 		/*
174 		 * We're doing a replace, and it must be atomic, that is, at
175 		 * any point in time we have either the old or the new xattr
176 		 * value in the tree. We don't want readers (getxattr and
177 		 * listxattrs) to miss a value, this is specially important
178 		 * for ACLs.
179 		 */
180 		const int slot = path->slots[0];
181 		struct extent_buffer *leaf = path->nodes[0];
182 		const u16 old_data_len = btrfs_dir_data_len(leaf, di);
183 		const u32 item_size = btrfs_item_size_nr(leaf, slot);
184 		const u32 data_size = sizeof(*di) + name_len + size;
185 		struct btrfs_item *item;
186 		unsigned long data_ptr;
187 		char *ptr;
188 
189 		if (size > old_data_len) {
190 			if (btrfs_leaf_free_space(fs_info, leaf) <
191 			    (size - old_data_len)) {
192 				ret = -ENOSPC;
193 				goto out;
194 			}
195 		}
196 
197 		if (old_data_len + name_len + sizeof(*di) == item_size) {
198 			/* No other xattrs packed in the same leaf item. */
199 			if (size > old_data_len)
200 				btrfs_extend_item(fs_info, path,
201 						  size - old_data_len);
202 			else if (size < old_data_len)
203 				btrfs_truncate_item(fs_info, path,
204 						    data_size, 1);
205 		} else {
206 			/* There are other xattrs packed in the same item. */
207 			ret = btrfs_delete_one_dir_name(trans, root, path, di);
208 			if (ret)
209 				goto out;
210 			btrfs_extend_item(fs_info, path, data_size);
211 		}
212 
213 		item = btrfs_item_nr(slot);
214 		ptr = btrfs_item_ptr(leaf, slot, char);
215 		ptr += btrfs_item_size(leaf, item) - data_size;
216 		di = (struct btrfs_dir_item *)ptr;
217 		btrfs_set_dir_data_len(leaf, di, size);
218 		data_ptr = ((unsigned long)(di + 1)) + name_len;
219 		write_extent_buffer(leaf, value, data_ptr, size);
220 		btrfs_mark_buffer_dirty(leaf);
221 	} else {
222 		/*
223 		 * Insert, and we had space for the xattr, so path->slots[0] is
224 		 * where our xattr dir_item is and btrfs_insert_xattr_item()
225 		 * filled it.
226 		 */
227 	}
228 out:
229 	btrfs_free_path(path);
230 	return ret;
231 }
232 
233 /*
234  * @value: "" makes the attribute to empty, NULL removes it
235  */
236 int __btrfs_setxattr(struct btrfs_trans_handle *trans,
237 		     struct inode *inode, const char *name,
238 		     const void *value, size_t size, int flags)
239 {
240 	struct btrfs_root *root = BTRFS_I(inode)->root;
241 	int ret;
242 
243 	if (btrfs_root_readonly(root))
244 		return -EROFS;
245 
246 	if (trans)
247 		return do_setxattr(trans, inode, name, value, size, flags);
248 
249 	trans = btrfs_start_transaction(root, 2);
250 	if (IS_ERR(trans))
251 		return PTR_ERR(trans);
252 
253 	ret = do_setxattr(trans, inode, name, value, size, flags);
254 	if (ret)
255 		goto out;
256 
257 	inode_inc_iversion(inode);
258 	inode->i_ctime = current_time(inode);
259 	set_bit(BTRFS_INODE_COPY_EVERYTHING, &BTRFS_I(inode)->runtime_flags);
260 	ret = btrfs_update_inode(trans, root, inode);
261 	BUG_ON(ret);
262 out:
263 	btrfs_end_transaction(trans);
264 	return ret;
265 }
266 
267 ssize_t btrfs_listxattr(struct dentry *dentry, char *buffer, size_t size)
268 {
269 	struct btrfs_key key;
270 	struct inode *inode = d_inode(dentry);
271 	struct btrfs_root *root = BTRFS_I(inode)->root;
272 	struct btrfs_path *path;
273 	int ret = 0;
274 	size_t total_size = 0, size_left = size;
275 
276 	/*
277 	 * ok we want all objects associated with this id.
278 	 * NOTE: we set key.offset = 0; because we want to start with the
279 	 * first xattr that we find and walk forward
280 	 */
281 	key.objectid = btrfs_ino(BTRFS_I(inode));
282 	key.type = BTRFS_XATTR_ITEM_KEY;
283 	key.offset = 0;
284 
285 	path = btrfs_alloc_path();
286 	if (!path)
287 		return -ENOMEM;
288 	path->reada = READA_FORWARD;
289 
290 	/* search for our xattrs */
291 	ret = btrfs_search_slot(NULL, root, &key, path, 0, 0);
292 	if (ret < 0)
293 		goto err;
294 
295 	while (1) {
296 		struct extent_buffer *leaf;
297 		int slot;
298 		struct btrfs_dir_item *di;
299 		struct btrfs_key found_key;
300 		u32 item_size;
301 		u32 cur;
302 
303 		leaf = path->nodes[0];
304 		slot = path->slots[0];
305 
306 		/* this is where we start walking through the path */
307 		if (slot >= btrfs_header_nritems(leaf)) {
308 			/*
309 			 * if we've reached the last slot in this leaf we need
310 			 * to go to the next leaf and reset everything
311 			 */
312 			ret = btrfs_next_leaf(root, path);
313 			if (ret < 0)
314 				goto err;
315 			else if (ret > 0)
316 				break;
317 			continue;
318 		}
319 
320 		btrfs_item_key_to_cpu(leaf, &found_key, slot);
321 
322 		/* check to make sure this item is what we want */
323 		if (found_key.objectid != key.objectid)
324 			break;
325 		if (found_key.type > BTRFS_XATTR_ITEM_KEY)
326 			break;
327 		if (found_key.type < BTRFS_XATTR_ITEM_KEY)
328 			goto next_item;
329 
330 		di = btrfs_item_ptr(leaf, slot, struct btrfs_dir_item);
331 		item_size = btrfs_item_size_nr(leaf, slot);
332 		cur = 0;
333 		while (cur < item_size) {
334 			u16 name_len = btrfs_dir_name_len(leaf, di);
335 			u16 data_len = btrfs_dir_data_len(leaf, di);
336 			u32 this_len = sizeof(*di) + name_len + data_len;
337 			unsigned long name_ptr = (unsigned long)(di + 1);
338 
339 			total_size += name_len + 1;
340 			/*
341 			 * We are just looking for how big our buffer needs to
342 			 * be.
343 			 */
344 			if (!size)
345 				goto next;
346 
347 			if (!buffer || (name_len + 1) > size_left) {
348 				ret = -ERANGE;
349 				goto err;
350 			}
351 
352 			read_extent_buffer(leaf, buffer, name_ptr, name_len);
353 			buffer[name_len] = '\0';
354 
355 			size_left -= name_len + 1;
356 			buffer += name_len + 1;
357 next:
358 			cur += this_len;
359 			di = (struct btrfs_dir_item *)((char *)di + this_len);
360 		}
361 next_item:
362 		path->slots[0]++;
363 	}
364 	ret = total_size;
365 
366 err:
367 	btrfs_free_path(path);
368 
369 	return ret;
370 }
371 
372 static int btrfs_xattr_handler_get(const struct xattr_handler *handler,
373 				   struct dentry *unused, struct inode *inode,
374 				   const char *name, void *buffer, size_t size)
375 {
376 	name = xattr_full_name(handler, name);
377 	return __btrfs_getxattr(inode, name, buffer, size);
378 }
379 
380 static int btrfs_xattr_handler_set(const struct xattr_handler *handler,
381 				   struct dentry *unused, struct inode *inode,
382 				   const char *name, const void *buffer,
383 				   size_t size, int flags)
384 {
385 	name = xattr_full_name(handler, name);
386 	return __btrfs_setxattr(NULL, inode, name, buffer, size, flags);
387 }
388 
389 static int btrfs_xattr_handler_set_prop(const struct xattr_handler *handler,
390 					struct dentry *unused, struct inode *inode,
391 					const char *name, const void *value,
392 					size_t size, int flags)
393 {
394 	name = xattr_full_name(handler, name);
395 	return btrfs_set_prop(inode, name, value, size, flags);
396 }
397 
398 static const struct xattr_handler btrfs_security_xattr_handler = {
399 	.prefix = XATTR_SECURITY_PREFIX,
400 	.get = btrfs_xattr_handler_get,
401 	.set = btrfs_xattr_handler_set,
402 };
403 
404 static const struct xattr_handler btrfs_trusted_xattr_handler = {
405 	.prefix = XATTR_TRUSTED_PREFIX,
406 	.get = btrfs_xattr_handler_get,
407 	.set = btrfs_xattr_handler_set,
408 };
409 
410 static const struct xattr_handler btrfs_user_xattr_handler = {
411 	.prefix = XATTR_USER_PREFIX,
412 	.get = btrfs_xattr_handler_get,
413 	.set = btrfs_xattr_handler_set,
414 };
415 
416 static const struct xattr_handler btrfs_btrfs_xattr_handler = {
417 	.prefix = XATTR_BTRFS_PREFIX,
418 	.get = btrfs_xattr_handler_get,
419 	.set = btrfs_xattr_handler_set_prop,
420 };
421 
422 const struct xattr_handler *btrfs_xattr_handlers[] = {
423 	&btrfs_security_xattr_handler,
424 #ifdef CONFIG_BTRFS_FS_POSIX_ACL
425 	&posix_acl_access_xattr_handler,
426 	&posix_acl_default_xattr_handler,
427 #endif
428 	&btrfs_trusted_xattr_handler,
429 	&btrfs_user_xattr_handler,
430 	&btrfs_btrfs_xattr_handler,
431 	NULL,
432 };
433 
434 static int btrfs_initxattrs(struct inode *inode,
435 			    const struct xattr *xattr_array, void *fs_info)
436 {
437 	const struct xattr *xattr;
438 	struct btrfs_trans_handle *trans = fs_info;
439 	char *name;
440 	int err = 0;
441 
442 	for (xattr = xattr_array; xattr->name != NULL; xattr++) {
443 		name = kmalloc(XATTR_SECURITY_PREFIX_LEN +
444 			       strlen(xattr->name) + 1, GFP_KERNEL);
445 		if (!name) {
446 			err = -ENOMEM;
447 			break;
448 		}
449 		strcpy(name, XATTR_SECURITY_PREFIX);
450 		strcpy(name + XATTR_SECURITY_PREFIX_LEN, xattr->name);
451 		err = __btrfs_setxattr(trans, inode, name,
452 				       xattr->value, xattr->value_len, 0);
453 		kfree(name);
454 		if (err < 0)
455 			break;
456 	}
457 	return err;
458 }
459 
460 int btrfs_xattr_security_init(struct btrfs_trans_handle *trans,
461 			      struct inode *inode, struct inode *dir,
462 			      const struct qstr *qstr)
463 {
464 	return security_inode_init_security(inode, dir, qstr,
465 					    &btrfs_initxattrs, trans);
466 }
467