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