Branch data Line data Source code
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 "ctree.h"
27 : : #include "btrfs_inode.h"
28 : : #include "transaction.h"
29 : : #include "xattr.h"
30 : : #include "disk-io.h"
31 : : #include "props.h"
32 : :
33 : :
34 : 0 : ssize_t __btrfs_getxattr(struct inode *inode, const char *name,
35 : : void *buffer, size_t size)
36 : : {
37 : : struct btrfs_dir_item *di;
38 : 0 : struct btrfs_root *root = BTRFS_I(inode)->root;
39 : : struct btrfs_path *path;
40 : : struct extent_buffer *leaf;
41 : : int ret = 0;
42 : : unsigned long data_ptr;
43 : :
44 : 0 : path = btrfs_alloc_path();
45 [ # # ]: 0 : if (!path)
46 : : return -ENOMEM;
47 : :
48 : : /* lookup the xattr by name */
49 : 0 : di = btrfs_lookup_xattr(NULL, root, path, btrfs_ino(inode), name,
50 : 0 : strlen(name), 0);
51 [ # # ]: 0 : if (!di) {
52 : : ret = -ENODATA;
53 : : goto out;
54 [ # # ]: 0 : } else if (IS_ERR(di)) {
55 : : ret = PTR_ERR(di);
56 : 0 : goto out;
57 : : }
58 : :
59 : 0 : leaf = path->nodes[0];
60 : : /* if size is 0, that means we want the size of the attr */
61 [ # # ]: 0 : if (!size) {
62 : 0 : ret = btrfs_dir_data_len(leaf, di);
63 : 0 : goto out;
64 : : }
65 : :
66 : : /* now get the data out of our dir_item */
67 [ # # ]: 0 : if (btrfs_dir_data_len(leaf, di) > size) {
68 : : ret = -ERANGE;
69 : : goto out;
70 : : }
71 : :
72 : : /*
73 : : * The way things are packed into the leaf is like this
74 : : * |struct btrfs_dir_item|name|data|
75 : : * where name is the xattr name, so security.foo, and data is the
76 : : * content of the xattr. data_ptr points to the location in memory
77 : : * where the data starts in the in memory leaf
78 : : */
79 : 0 : data_ptr = (unsigned long)((char *)(di + 1) +
80 : : btrfs_dir_name_len(leaf, di));
81 : 0 : read_extent_buffer(leaf, buffer, data_ptr,
82 : : btrfs_dir_data_len(leaf, di));
83 : 0 : ret = btrfs_dir_data_len(leaf, di);
84 : :
85 : : out:
86 : 0 : btrfs_free_path(path);
87 : 0 : return ret;
88 : : }
89 : :
90 : 0 : static int do_setxattr(struct btrfs_trans_handle *trans,
91 : : struct inode *inode, const char *name,
92 : : const void *value, size_t size, int flags)
93 : : {
94 : : struct btrfs_dir_item *di;
95 : 0 : struct btrfs_root *root = BTRFS_I(inode)->root;
96 : : struct btrfs_path *path;
97 : 0 : size_t name_len = strlen(name);
98 : : int ret = 0;
99 : :
100 [ # # ]: 0 : if (name_len + size > BTRFS_MAX_XATTR_SIZE(root))
101 : : return -ENOSPC;
102 : :
103 : 0 : path = btrfs_alloc_path();
104 [ # # ]: 0 : if (!path)
105 : : return -ENOMEM;
106 : :
107 [ # # ]: 0 : if (flags & XATTR_REPLACE) {
108 : 0 : di = btrfs_lookup_xattr(trans, root, path, btrfs_ino(inode), name,
109 : : name_len, -1);
110 [ # # ]: 0 : if (IS_ERR(di)) {
111 : : ret = PTR_ERR(di);
112 : 0 : goto out;
113 [ # # ]: 0 : } else if (!di) {
114 : : ret = -ENODATA;
115 : : goto out;
116 : : }
117 : 0 : ret = btrfs_delete_one_dir_name(trans, root, path, di);
118 [ # # ]: 0 : if (ret)
119 : : goto out;
120 : 0 : btrfs_release_path(path);
121 : :
122 : : /*
123 : : * remove the attribute
124 : : */
125 [ # # ]: 0 : if (!value)
126 : : goto out;
127 : : } else {
128 : 0 : di = btrfs_lookup_xattr(NULL, root, path, btrfs_ino(inode),
129 : : name, name_len, 0);
130 [ # # ]: 0 : if (IS_ERR(di)) {
131 : : ret = PTR_ERR(di);
132 : 0 : goto out;
133 : : }
134 [ # # ]: 0 : if (!di && !value)
135 : : goto out;
136 : 0 : btrfs_release_path(path);
137 : : }
138 : :
139 : : again:
140 : 0 : ret = btrfs_insert_xattr_item(trans, root, path, btrfs_ino(inode),
141 : : name, name_len, value, size);
142 : : /*
143 : : * If we're setting an xattr to a new value but the new value is say
144 : : * exactly BTRFS_MAX_XATTR_SIZE, we could end up with EOVERFLOW getting
145 : : * back from split_leaf. This is because it thinks we'll be extending
146 : : * the existing item size, but we're asking for enough space to add the
147 : : * item itself. So if we get EOVERFLOW just set ret to EEXIST and let
148 : : * the rest of the function figure it out.
149 : : */
150 [ # # ]: 0 : if (ret == -EOVERFLOW)
151 : : ret = -EEXIST;
152 : :
153 [ # # ]: 0 : if (ret == -EEXIST) {
154 [ # # ]: 0 : if (flags & XATTR_CREATE)
155 : : goto out;
156 : : /*
157 : : * We can't use the path we already have since we won't have the
158 : : * proper locking for a delete, so release the path and
159 : : * re-lookup to delete the thing.
160 : : */
161 : 0 : btrfs_release_path(path);
162 : 0 : di = btrfs_lookup_xattr(trans, root, path, btrfs_ino(inode),
163 : : name, name_len, -1);
164 [ # # ]: 0 : if (IS_ERR(di)) {
165 : : ret = PTR_ERR(di);
166 : 0 : goto out;
167 [ # # ]: 0 : } else if (!di) {
168 : : /* Shouldn't happen but just in case... */
169 : 0 : btrfs_release_path(path);
170 : 0 : goto again;
171 : : }
172 : :
173 : 0 : ret = btrfs_delete_one_dir_name(trans, root, path, di);
174 [ # # ]: 0 : if (ret)
175 : : goto out;
176 : :
177 : : /*
178 : : * We have a value to set, so go back and try to insert it now.
179 : : */
180 [ # # ]: 0 : if (value) {
181 : 0 : btrfs_release_path(path);
182 : 0 : goto again;
183 : : }
184 : : }
185 : : out:
186 : 0 : btrfs_free_path(path);
187 : 0 : return ret;
188 : : }
189 : :
190 : : /*
191 : : * @value: "" makes the attribute to empty, NULL removes it
192 : : */
193 : 0 : int __btrfs_setxattr(struct btrfs_trans_handle *trans,
194 : : struct inode *inode, const char *name,
195 : : const void *value, size_t size, int flags)
196 : : {
197 : 0 : struct btrfs_root *root = BTRFS_I(inode)->root;
198 : : int ret;
199 : :
200 [ # # ]: 0 : if (trans)
201 : 0 : return do_setxattr(trans, inode, name, value, size, flags);
202 : :
203 : 0 : trans = btrfs_start_transaction(root, 2);
204 [ # # ]: 0 : if (IS_ERR(trans))
205 : 0 : return PTR_ERR(trans);
206 : :
207 : 0 : ret = do_setxattr(trans, inode, name, value, size, flags);
208 [ # # ]: 0 : if (ret)
209 : : goto out;
210 : :
211 : : inode_inc_iversion(inode);
212 : 0 : inode->i_ctime = CURRENT_TIME;
213 : 0 : set_bit(BTRFS_INODE_COPY_EVERYTHING, &BTRFS_I(inode)->runtime_flags);
214 : 0 : ret = btrfs_update_inode(trans, root, inode);
215 [ # # ]: 0 : BUG_ON(ret);
216 : : out:
217 : 0 : btrfs_end_transaction(trans, root);
218 : 0 : return ret;
219 : : }
220 : :
221 : 0 : ssize_t btrfs_listxattr(struct dentry *dentry, char *buffer, size_t size)
222 : : {
223 : : struct btrfs_key key, found_key;
224 : 0 : struct inode *inode = dentry->d_inode;
225 : 0 : struct btrfs_root *root = BTRFS_I(inode)->root;
226 : : struct btrfs_path *path;
227 : 0 : struct extent_buffer *leaf;
228 : : struct btrfs_dir_item *di;
229 : : int ret = 0, slot;
230 : : size_t total_size = 0, size_left = size;
231 : : unsigned long name_ptr;
232 : : size_t name_len;
233 : :
234 : : /*
235 : : * ok we want all objects associated with this id.
236 : : * NOTE: we set key.offset = 0; because we want to start with the
237 : : * first xattr that we find and walk forward
238 : : */
239 : 0 : key.objectid = btrfs_ino(inode);
240 : : btrfs_set_key_type(&key, BTRFS_XATTR_ITEM_KEY);
241 : 0 : key.offset = 0;
242 : :
243 : 0 : path = btrfs_alloc_path();
244 [ # # ]: 0 : if (!path)
245 : : return -ENOMEM;
246 : 0 : path->reada = 2;
247 : :
248 : : /* search for our xattrs */
249 : 0 : ret = btrfs_search_slot(NULL, root, &key, path, 0, 0);
250 [ # # ]: 0 : if (ret < 0)
251 : : goto err;
252 : :
253 : : while (1) {
254 : 0 : leaf = path->nodes[0];
255 : 0 : slot = path->slots[0];
256 : :
257 : : /* this is where we start walking through the path */
258 [ # # ]: 0 : if (slot >= btrfs_header_nritems(leaf)) {
259 : : /*
260 : : * if we've reached the last slot in this leaf we need
261 : : * to go to the next leaf and reset everything
262 : : */
263 : 0 : ret = btrfs_next_leaf(root, path);
264 [ # # ]: 0 : if (ret < 0)
265 : : goto err;
266 [ # # ]: 0 : else if (ret > 0)
267 : : break;
268 : 0 : continue;
269 : : }
270 : :
271 : : btrfs_item_key_to_cpu(leaf, &found_key, slot);
272 : :
273 : : /* check to make sure this item is what we want */
274 [ # # ]: 0 : if (found_key.objectid != key.objectid)
275 : : break;
276 [ # # ]: 0 : if (btrfs_key_type(&found_key) != BTRFS_XATTR_ITEM_KEY)
277 : : break;
278 : :
279 : 0 : di = btrfs_item_ptr(leaf, slot, struct btrfs_dir_item);
280 [ # # ]: 0 : if (verify_dir_item(root, leaf, di))
281 : : goto next;
282 : :
283 : 0 : name_len = btrfs_dir_name_len(leaf, di);
284 : 0 : total_size += name_len + 1;
285 : :
286 : : /* we are just looking for how big our buffer needs to be */
287 [ # # ]: 0 : if (!size)
288 : : goto next;
289 : :
290 [ # # ][ # # ]: 0 : if (!buffer || (name_len + 1) > size_left) {
291 : : ret = -ERANGE;
292 : : goto err;
293 : : }
294 : :
295 : 0 : name_ptr = (unsigned long)(di + 1);
296 : 0 : read_extent_buffer(leaf, buffer, name_ptr, name_len);
297 : 0 : buffer[name_len] = '\0';
298 : :
299 : 0 : size_left -= name_len + 1;
300 : 0 : buffer += name_len + 1;
301 : : next:
302 : 0 : path->slots[0]++;
303 : : }
304 : 0 : ret = total_size;
305 : :
306 : : err:
307 : 0 : btrfs_free_path(path);
308 : :
309 : 0 : return ret;
310 : : }
311 : :
312 : : /*
313 : : * List of handlers for synthetic system.* attributes. All real ondisk
314 : : * attributes are handled directly.
315 : : */
316 : : const struct xattr_handler *btrfs_xattr_handlers[] = {
317 : : #ifdef CONFIG_BTRFS_FS_POSIX_ACL
318 : : &posix_acl_access_xattr_handler,
319 : : &posix_acl_default_xattr_handler,
320 : : #endif
321 : : NULL,
322 : : };
323 : :
324 : : /*
325 : : * Check if the attribute is in a supported namespace.
326 : : *
327 : : * This applied after the check for the synthetic attributes in the system
328 : : * namespace.
329 : : */
330 : 0 : static bool btrfs_is_valid_xattr(const char *name)
331 : : {
332 : 0 : return !strncmp(name, XATTR_SECURITY_PREFIX,
333 [ # # ]: 0 : XATTR_SECURITY_PREFIX_LEN) ||
334 [ # # ]: 0 : !strncmp(name, XATTR_SYSTEM_PREFIX, XATTR_SYSTEM_PREFIX_LEN) ||
335 [ # # ]: 0 : !strncmp(name, XATTR_TRUSTED_PREFIX, XATTR_TRUSTED_PREFIX_LEN) ||
336 [ # # ][ # # ]: 0 : !strncmp(name, XATTR_USER_PREFIX, XATTR_USER_PREFIX_LEN) ||
337 : 0 : !strncmp(name, XATTR_BTRFS_PREFIX, XATTR_BTRFS_PREFIX_LEN);
338 : : }
339 : :
340 : 0 : ssize_t btrfs_getxattr(struct dentry *dentry, const char *name,
341 : : void *buffer, size_t size)
342 : : {
343 : : /*
344 : : * If this is a request for a synthetic attribute in the system.*
345 : : * namespace use the generic infrastructure to resolve a handler
346 : : * for it via sb->s_xattr.
347 : : */
348 [ # # ]: 0 : if (!strncmp(name, XATTR_SYSTEM_PREFIX, XATTR_SYSTEM_PREFIX_LEN))
349 : 0 : return generic_getxattr(dentry, name, buffer, size);
350 : :
351 [ # # ]: 0 : if (!btrfs_is_valid_xattr(name))
352 : : return -EOPNOTSUPP;
353 : 0 : return __btrfs_getxattr(dentry->d_inode, name, buffer, size);
354 : : }
355 : :
356 : 0 : int btrfs_setxattr(struct dentry *dentry, const char *name, const void *value,
357 : : size_t size, int flags)
358 : : {
359 : 0 : struct btrfs_root *root = BTRFS_I(dentry->d_inode)->root;
360 : :
361 : : /*
362 : : * The permission on security.* and system.* is not checked
363 : : * in permission().
364 : : */
365 [ # # ]: 0 : if (btrfs_root_readonly(root))
366 : : return -EROFS;
367 : :
368 : : /*
369 : : * If this is a request for a synthetic attribute in the system.*
370 : : * namespace use the generic infrastructure to resolve a handler
371 : : * for it via sb->s_xattr.
372 : : */
373 [ # # ]: 0 : if (!strncmp(name, XATTR_SYSTEM_PREFIX, XATTR_SYSTEM_PREFIX_LEN))
374 : 0 : return generic_setxattr(dentry, name, value, size, flags);
375 : :
376 [ # # ]: 0 : if (!btrfs_is_valid_xattr(name))
377 : : return -EOPNOTSUPP;
378 : :
379 [ # # ]: 0 : if (!strncmp(name, XATTR_BTRFS_PREFIX, XATTR_BTRFS_PREFIX_LEN))
380 : 0 : return btrfs_set_prop(dentry->d_inode, name,
381 : : value, size, flags);
382 : :
383 [ # # ]: 0 : if (size == 0)
384 : : value = ""; /* empty EA, do not remove */
385 : :
386 : 0 : return __btrfs_setxattr(NULL, dentry->d_inode, name, value, size,
387 : : flags);
388 : : }
389 : :
390 : 0 : int btrfs_removexattr(struct dentry *dentry, const char *name)
391 : : {
392 : 0 : struct btrfs_root *root = BTRFS_I(dentry->d_inode)->root;
393 : :
394 : : /*
395 : : * The permission on security.* and system.* is not checked
396 : : * in permission().
397 : : */
398 [ # # ]: 0 : if (btrfs_root_readonly(root))
399 : : return -EROFS;
400 : :
401 : : /*
402 : : * If this is a request for a synthetic attribute in the system.*
403 : : * namespace use the generic infrastructure to resolve a handler
404 : : * for it via sb->s_xattr.
405 : : */
406 [ # # ]: 0 : if (!strncmp(name, XATTR_SYSTEM_PREFIX, XATTR_SYSTEM_PREFIX_LEN))
407 : 0 : return generic_removexattr(dentry, name);
408 : :
409 [ # # ]: 0 : if (!btrfs_is_valid_xattr(name))
410 : : return -EOPNOTSUPP;
411 : :
412 [ # # ]: 0 : if (!strncmp(name, XATTR_BTRFS_PREFIX, XATTR_BTRFS_PREFIX_LEN))
413 : 0 : return btrfs_set_prop(dentry->d_inode, name,
414 : : NULL, 0, XATTR_REPLACE);
415 : :
416 : 0 : return __btrfs_setxattr(NULL, dentry->d_inode, name, NULL, 0,
417 : : XATTR_REPLACE);
418 : : }
419 : :
420 : 0 : static int btrfs_initxattrs(struct inode *inode,
421 : : const struct xattr *xattr_array, void *fs_info)
422 : : {
423 : : const struct xattr *xattr;
424 : : struct btrfs_trans_handle *trans = fs_info;
425 : : char *name;
426 : : int err = 0;
427 : :
428 [ # # ]: 0 : for (xattr = xattr_array; xattr->name != NULL; xattr++) {
429 : 0 : name = kmalloc(XATTR_SECURITY_PREFIX_LEN +
430 : 0 : strlen(xattr->name) + 1, GFP_NOFS);
431 [ # # ]: 0 : if (!name) {
432 : : err = -ENOMEM;
433 : : break;
434 : : }
435 : 0 : strcpy(name, XATTR_SECURITY_PREFIX);
436 : 0 : strcpy(name + XATTR_SECURITY_PREFIX_LEN, xattr->name);
437 : 0 : err = __btrfs_setxattr(trans, inode, name,
438 : 0 : xattr->value, xattr->value_len, 0);
439 : 0 : kfree(name);
440 [ # # ]: 0 : if (err < 0)
441 : : break;
442 : : }
443 : 0 : return err;
444 : : }
445 : :
446 : 0 : int btrfs_xattr_security_init(struct btrfs_trans_handle *trans,
447 : : struct inode *inode, struct inode *dir,
448 : : const struct qstr *qstr)
449 : : {
450 : 0 : return security_inode_init_security(inode, dir, qstr,
451 : : &btrfs_initxattrs, trans);
452 : : }
|