1 /* 2 File: fs/xattr.c 3 4 Extended attribute handling. 5 6 Copyright (C) 2001 by Andreas Gruenbacher <a.gruenbacher@computer.org> 7 Copyright (C) 2001 SGI - Silicon Graphics, Inc <linux-xfs@oss.sgi.com> 8 Copyright (c) 2004 Red Hat, Inc., James Morris <jmorris@redhat.com> 9 */ 10 #include <linux/fs.h> 11 #include <linux/slab.h> 12 #include <linux/smp_lock.h> 13 #include <linux/file.h> 14 #include <linux/xattr.h> 15 #include <linux/namei.h> 16 #include <linux/security.h> 17 #include <linux/syscalls.h> 18 #include <linux/module.h> 19 #include <linux/fsnotify.h> 20 #include <asm/uaccess.h> 21 22 /* 23 * Extended attribute SET operations 24 */ 25 static long 26 setxattr(struct dentry *d, char __user *name, void __user *value, 27 size_t size, int flags) 28 { 29 int error; 30 void *kvalue = NULL; 31 char kname[XATTR_NAME_MAX + 1]; 32 33 if (flags & ~(XATTR_CREATE|XATTR_REPLACE)) 34 return -EINVAL; 35 36 error = strncpy_from_user(kname, name, sizeof(kname)); 37 if (error == 0 || error == sizeof(kname)) 38 error = -ERANGE; 39 if (error < 0) 40 return error; 41 42 if (size) { 43 if (size > XATTR_SIZE_MAX) 44 return -E2BIG; 45 kvalue = kmalloc(size, GFP_KERNEL); 46 if (!kvalue) 47 return -ENOMEM; 48 if (copy_from_user(kvalue, value, size)) { 49 kfree(kvalue); 50 return -EFAULT; 51 } 52 } 53 54 down(&d->d_inode->i_sem); 55 error = security_inode_setxattr(d, kname, kvalue, size, flags); 56 if (error) 57 goto out; 58 error = -EOPNOTSUPP; 59 if (d->d_inode->i_op && d->d_inode->i_op->setxattr) { 60 error = d->d_inode->i_op->setxattr(d, kname, kvalue, 61 size, flags); 62 if (!error) { 63 fsnotify_xattr(d); 64 security_inode_post_setxattr(d, kname, kvalue, 65 size, flags); 66 } 67 } else if (!strncmp(kname, XATTR_SECURITY_PREFIX, 68 sizeof XATTR_SECURITY_PREFIX - 1)) { 69 const char *suffix = kname + sizeof XATTR_SECURITY_PREFIX - 1; 70 error = security_inode_setsecurity(d->d_inode, suffix, kvalue, 71 size, flags); 72 if (!error) 73 fsnotify_xattr(d); 74 } 75 out: 76 up(&d->d_inode->i_sem); 77 if (kvalue) 78 kfree(kvalue); 79 return error; 80 } 81 82 asmlinkage long 83 sys_setxattr(char __user *path, char __user *name, void __user *value, 84 size_t size, int flags) 85 { 86 struct nameidata nd; 87 int error; 88 89 error = user_path_walk(path, &nd); 90 if (error) 91 return error; 92 error = setxattr(nd.dentry, name, value, size, flags); 93 path_release(&nd); 94 return error; 95 } 96 97 asmlinkage long 98 sys_lsetxattr(char __user *path, char __user *name, void __user *value, 99 size_t size, int flags) 100 { 101 struct nameidata nd; 102 int error; 103 104 error = user_path_walk_link(path, &nd); 105 if (error) 106 return error; 107 error = setxattr(nd.dentry, name, value, size, flags); 108 path_release(&nd); 109 return error; 110 } 111 112 asmlinkage long 113 sys_fsetxattr(int fd, char __user *name, void __user *value, 114 size_t size, int flags) 115 { 116 struct file *f; 117 int error = -EBADF; 118 119 f = fget(fd); 120 if (!f) 121 return error; 122 error = setxattr(f->f_dentry, name, value, size, flags); 123 fput(f); 124 return error; 125 } 126 127 /* 128 * Extended attribute GET operations 129 */ 130 static ssize_t 131 getxattr(struct dentry *d, char __user *name, void __user *value, size_t size) 132 { 133 ssize_t error; 134 void *kvalue = NULL; 135 char kname[XATTR_NAME_MAX + 1]; 136 137 error = strncpy_from_user(kname, name, sizeof(kname)); 138 if (error == 0 || error == sizeof(kname)) 139 error = -ERANGE; 140 if (error < 0) 141 return error; 142 143 if (size) { 144 if (size > XATTR_SIZE_MAX) 145 size = XATTR_SIZE_MAX; 146 kvalue = kmalloc(size, GFP_KERNEL); 147 if (!kvalue) 148 return -ENOMEM; 149 } 150 151 error = security_inode_getxattr(d, kname); 152 if (error) 153 goto out; 154 error = -EOPNOTSUPP; 155 if (d->d_inode->i_op && d->d_inode->i_op->getxattr) 156 error = d->d_inode->i_op->getxattr(d, kname, kvalue, size); 157 else if (!strncmp(kname, XATTR_SECURITY_PREFIX, 158 sizeof XATTR_SECURITY_PREFIX - 1)) { 159 const char *suffix = kname + sizeof XATTR_SECURITY_PREFIX - 1; 160 error = security_inode_getsecurity(d->d_inode, suffix, kvalue, 161 size); 162 } 163 if (error > 0) { 164 if (size && copy_to_user(value, kvalue, error)) 165 error = -EFAULT; 166 } else if (error == -ERANGE && size >= XATTR_SIZE_MAX) { 167 /* The file system tried to returned a value bigger 168 than XATTR_SIZE_MAX bytes. Not possible. */ 169 error = -E2BIG; 170 } 171 out: 172 if (kvalue) 173 kfree(kvalue); 174 return error; 175 } 176 177 asmlinkage ssize_t 178 sys_getxattr(char __user *path, char __user *name, void __user *value, 179 size_t size) 180 { 181 struct nameidata nd; 182 ssize_t error; 183 184 error = user_path_walk(path, &nd); 185 if (error) 186 return error; 187 error = getxattr(nd.dentry, name, value, size); 188 path_release(&nd); 189 return error; 190 } 191 192 asmlinkage ssize_t 193 sys_lgetxattr(char __user *path, char __user *name, void __user *value, 194 size_t size) 195 { 196 struct nameidata nd; 197 ssize_t error; 198 199 error = user_path_walk_link(path, &nd); 200 if (error) 201 return error; 202 error = getxattr(nd.dentry, name, value, size); 203 path_release(&nd); 204 return error; 205 } 206 207 asmlinkage ssize_t 208 sys_fgetxattr(int fd, char __user *name, void __user *value, size_t size) 209 { 210 struct file *f; 211 ssize_t error = -EBADF; 212 213 f = fget(fd); 214 if (!f) 215 return error; 216 error = getxattr(f->f_dentry, name, value, size); 217 fput(f); 218 return error; 219 } 220 221 /* 222 * Extended attribute LIST operations 223 */ 224 static ssize_t 225 listxattr(struct dentry *d, char __user *list, size_t size) 226 { 227 ssize_t error; 228 char *klist = NULL; 229 230 if (size) { 231 if (size > XATTR_LIST_MAX) 232 size = XATTR_LIST_MAX; 233 klist = kmalloc(size, GFP_KERNEL); 234 if (!klist) 235 return -ENOMEM; 236 } 237 238 error = security_inode_listxattr(d); 239 if (error) 240 goto out; 241 error = -EOPNOTSUPP; 242 if (d->d_inode->i_op && d->d_inode->i_op->listxattr) { 243 error = d->d_inode->i_op->listxattr(d, klist, size); 244 } else { 245 error = security_inode_listsecurity(d->d_inode, klist, size); 246 if (size && error >= size) 247 error = -ERANGE; 248 } 249 if (error > 0) { 250 if (size && copy_to_user(list, klist, error)) 251 error = -EFAULT; 252 } else if (error == -ERANGE && size >= XATTR_LIST_MAX) { 253 /* The file system tried to returned a list bigger 254 than XATTR_LIST_MAX bytes. Not possible. */ 255 error = -E2BIG; 256 } 257 out: 258 if (klist) 259 kfree(klist); 260 return error; 261 } 262 263 asmlinkage ssize_t 264 sys_listxattr(char __user *path, char __user *list, size_t size) 265 { 266 struct nameidata nd; 267 ssize_t error; 268 269 error = user_path_walk(path, &nd); 270 if (error) 271 return error; 272 error = listxattr(nd.dentry, list, size); 273 path_release(&nd); 274 return error; 275 } 276 277 asmlinkage ssize_t 278 sys_llistxattr(char __user *path, char __user *list, size_t size) 279 { 280 struct nameidata nd; 281 ssize_t error; 282 283 error = user_path_walk_link(path, &nd); 284 if (error) 285 return error; 286 error = listxattr(nd.dentry, list, size); 287 path_release(&nd); 288 return error; 289 } 290 291 asmlinkage ssize_t 292 sys_flistxattr(int fd, char __user *list, size_t size) 293 { 294 struct file *f; 295 ssize_t error = -EBADF; 296 297 f = fget(fd); 298 if (!f) 299 return error; 300 error = listxattr(f->f_dentry, list, size); 301 fput(f); 302 return error; 303 } 304 305 /* 306 * Extended attribute REMOVE operations 307 */ 308 static long 309 removexattr(struct dentry *d, char __user *name) 310 { 311 int error; 312 char kname[XATTR_NAME_MAX + 1]; 313 314 error = strncpy_from_user(kname, name, sizeof(kname)); 315 if (error == 0 || error == sizeof(kname)) 316 error = -ERANGE; 317 if (error < 0) 318 return error; 319 320 error = -EOPNOTSUPP; 321 if (d->d_inode->i_op && d->d_inode->i_op->removexattr) { 322 error = security_inode_removexattr(d, kname); 323 if (error) 324 goto out; 325 down(&d->d_inode->i_sem); 326 error = d->d_inode->i_op->removexattr(d, kname); 327 up(&d->d_inode->i_sem); 328 if (!error) 329 fsnotify_xattr(d); 330 } 331 out: 332 return error; 333 } 334 335 asmlinkage long 336 sys_removexattr(char __user *path, char __user *name) 337 { 338 struct nameidata nd; 339 int error; 340 341 error = user_path_walk(path, &nd); 342 if (error) 343 return error; 344 error = removexattr(nd.dentry, name); 345 path_release(&nd); 346 return error; 347 } 348 349 asmlinkage long 350 sys_lremovexattr(char __user *path, char __user *name) 351 { 352 struct nameidata nd; 353 int error; 354 355 error = user_path_walk_link(path, &nd); 356 if (error) 357 return error; 358 error = removexattr(nd.dentry, name); 359 path_release(&nd); 360 return error; 361 } 362 363 asmlinkage long 364 sys_fremovexattr(int fd, char __user *name) 365 { 366 struct file *f; 367 int error = -EBADF; 368 369 f = fget(fd); 370 if (!f) 371 return error; 372 error = removexattr(f->f_dentry, name); 373 fput(f); 374 return error; 375 } 376 377 378 static const char * 379 strcmp_prefix(const char *a, const char *a_prefix) 380 { 381 while (*a_prefix && *a == *a_prefix) { 382 a++; 383 a_prefix++; 384 } 385 return *a_prefix ? NULL : a; 386 } 387 388 /* 389 * In order to implement different sets of xattr operations for each xattr 390 * prefix with the generic xattr API, a filesystem should create a 391 * null-terminated array of struct xattr_handler (one for each prefix) and 392 * hang a pointer to it off of the s_xattr field of the superblock. 393 * 394 * The generic_fooxattr() functions will use this list to dispatch xattr 395 * operations to the correct xattr_handler. 396 */ 397 #define for_each_xattr_handler(handlers, handler) \ 398 for ((handler) = *(handlers)++; \ 399 (handler) != NULL; \ 400 (handler) = *(handlers)++) 401 402 /* 403 * Find the xattr_handler with the matching prefix. 404 */ 405 static struct xattr_handler * 406 xattr_resolve_name(struct xattr_handler **handlers, const char **name) 407 { 408 struct xattr_handler *handler; 409 410 if (!*name) 411 return NULL; 412 413 for_each_xattr_handler(handlers, handler) { 414 const char *n = strcmp_prefix(*name, handler->prefix); 415 if (n) { 416 *name = n; 417 break; 418 } 419 } 420 return handler; 421 } 422 423 /* 424 * Find the handler for the prefix and dispatch its get() operation. 425 */ 426 ssize_t 427 generic_getxattr(struct dentry *dentry, const char *name, void *buffer, size_t size) 428 { 429 struct xattr_handler *handler; 430 struct inode *inode = dentry->d_inode; 431 432 handler = xattr_resolve_name(inode->i_sb->s_xattr, &name); 433 if (!handler) 434 return -EOPNOTSUPP; 435 return handler->get(inode, name, buffer, size); 436 } 437 438 /* 439 * Combine the results of the list() operation from every xattr_handler in the 440 * list. 441 */ 442 ssize_t 443 generic_listxattr(struct dentry *dentry, char *buffer, size_t buffer_size) 444 { 445 struct inode *inode = dentry->d_inode; 446 struct xattr_handler *handler, **handlers = inode->i_sb->s_xattr; 447 unsigned int size = 0; 448 449 if (!buffer) { 450 for_each_xattr_handler(handlers, handler) 451 size += handler->list(inode, NULL, 0, NULL, 0); 452 } else { 453 char *buf = buffer; 454 455 for_each_xattr_handler(handlers, handler) { 456 size = handler->list(inode, buf, buffer_size, NULL, 0); 457 if (size > buffer_size) 458 return -ERANGE; 459 buf += size; 460 buffer_size -= size; 461 } 462 size = buf - buffer; 463 } 464 return size; 465 } 466 467 /* 468 * Find the handler for the prefix and dispatch its set() operation. 469 */ 470 int 471 generic_setxattr(struct dentry *dentry, const char *name, const void *value, size_t size, int flags) 472 { 473 struct xattr_handler *handler; 474 struct inode *inode = dentry->d_inode; 475 476 if (size == 0) 477 value = ""; /* empty EA, do not remove */ 478 handler = xattr_resolve_name(inode->i_sb->s_xattr, &name); 479 if (!handler) 480 return -EOPNOTSUPP; 481 return handler->set(inode, name, value, size, flags); 482 } 483 484 /* 485 * Find the handler for the prefix and dispatch its set() operation to remove 486 * any associated extended attribute. 487 */ 488 int 489 generic_removexattr(struct dentry *dentry, const char *name) 490 { 491 struct xattr_handler *handler; 492 struct inode *inode = dentry->d_inode; 493 494 handler = xattr_resolve_name(inode->i_sb->s_xattr, &name); 495 if (!handler) 496 return -EOPNOTSUPP; 497 return handler->set(inode, name, NULL, 0, XATTR_REPLACE); 498 } 499 500 EXPORT_SYMBOL(generic_getxattr); 501 EXPORT_SYMBOL(generic_listxattr); 502 EXPORT_SYMBOL(generic_setxattr); 503 EXPORT_SYMBOL(generic_removexattr); 504