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 } 329 out: 330 return error; 331 } 332 333 asmlinkage long 334 sys_removexattr(char __user *path, char __user *name) 335 { 336 struct nameidata nd; 337 int error; 338 339 error = user_path_walk(path, &nd); 340 if (error) 341 return error; 342 error = removexattr(nd.dentry, name); 343 path_release(&nd); 344 return error; 345 } 346 347 asmlinkage long 348 sys_lremovexattr(char __user *path, char __user *name) 349 { 350 struct nameidata nd; 351 int error; 352 353 error = user_path_walk_link(path, &nd); 354 if (error) 355 return error; 356 error = removexattr(nd.dentry, name); 357 path_release(&nd); 358 return error; 359 } 360 361 asmlinkage long 362 sys_fremovexattr(int fd, char __user *name) 363 { 364 struct file *f; 365 int error = -EBADF; 366 367 f = fget(fd); 368 if (!f) 369 return error; 370 error = removexattr(f->f_dentry, name); 371 fput(f); 372 return error; 373 } 374 375 376 static const char * 377 strcmp_prefix(const char *a, const char *a_prefix) 378 { 379 while (*a_prefix && *a == *a_prefix) { 380 a++; 381 a_prefix++; 382 } 383 return *a_prefix ? NULL : a; 384 } 385 386 /* 387 * In order to implement different sets of xattr operations for each xattr 388 * prefix with the generic xattr API, a filesystem should create a 389 * null-terminated array of struct xattr_handler (one for each prefix) and 390 * hang a pointer to it off of the s_xattr field of the superblock. 391 * 392 * The generic_fooxattr() functions will use this list to dispatch xattr 393 * operations to the correct xattr_handler. 394 */ 395 #define for_each_xattr_handler(handlers, handler) \ 396 for ((handler) = *(handlers)++; \ 397 (handler) != NULL; \ 398 (handler) = *(handlers)++) 399 400 /* 401 * Find the xattr_handler with the matching prefix. 402 */ 403 static struct xattr_handler * 404 xattr_resolve_name(struct xattr_handler **handlers, const char **name) 405 { 406 struct xattr_handler *handler; 407 408 if (!*name) 409 return NULL; 410 411 for_each_xattr_handler(handlers, handler) { 412 const char *n = strcmp_prefix(*name, handler->prefix); 413 if (n) { 414 *name = n; 415 break; 416 } 417 } 418 return handler; 419 } 420 421 /* 422 * Find the handler for the prefix and dispatch its get() operation. 423 */ 424 ssize_t 425 generic_getxattr(struct dentry *dentry, const char *name, void *buffer, size_t size) 426 { 427 struct xattr_handler *handler; 428 struct inode *inode = dentry->d_inode; 429 430 handler = xattr_resolve_name(inode->i_sb->s_xattr, &name); 431 if (!handler) 432 return -EOPNOTSUPP; 433 return handler->get(inode, name, buffer, size); 434 } 435 436 /* 437 * Combine the results of the list() operation from every xattr_handler in the 438 * list. 439 */ 440 ssize_t 441 generic_listxattr(struct dentry *dentry, char *buffer, size_t buffer_size) 442 { 443 struct inode *inode = dentry->d_inode; 444 struct xattr_handler *handler, **handlers = inode->i_sb->s_xattr; 445 unsigned int size = 0; 446 447 if (!buffer) { 448 for_each_xattr_handler(handlers, handler) 449 size += handler->list(inode, NULL, 0, NULL, 0); 450 } else { 451 char *buf = buffer; 452 453 for_each_xattr_handler(handlers, handler) { 454 size = handler->list(inode, buf, buffer_size, NULL, 0); 455 if (size > buffer_size) 456 return -ERANGE; 457 buf += size; 458 buffer_size -= size; 459 } 460 size = buf - buffer; 461 } 462 return size; 463 } 464 465 /* 466 * Find the handler for the prefix and dispatch its set() operation. 467 */ 468 int 469 generic_setxattr(struct dentry *dentry, const char *name, const void *value, size_t size, int flags) 470 { 471 struct xattr_handler *handler; 472 struct inode *inode = dentry->d_inode; 473 474 if (size == 0) 475 value = ""; /* empty EA, do not remove */ 476 handler = xattr_resolve_name(inode->i_sb->s_xattr, &name); 477 if (!handler) 478 return -EOPNOTSUPP; 479 return handler->set(inode, name, value, size, flags); 480 } 481 482 /* 483 * Find the handler for the prefix and dispatch its set() operation to remove 484 * any associated extended attribute. 485 */ 486 int 487 generic_removexattr(struct dentry *dentry, const char *name) 488 { 489 struct xattr_handler *handler; 490 struct inode *inode = dentry->d_inode; 491 492 handler = xattr_resolve_name(inode->i_sb->s_xattr, &name); 493 if (!handler) 494 return -EOPNOTSUPP; 495 return handler->set(inode, name, NULL, 0, XATTR_REPLACE); 496 } 497 498 EXPORT_SYMBOL(generic_getxattr); 499 EXPORT_SYMBOL(generic_listxattr); 500 EXPORT_SYMBOL(generic_setxattr); 501 EXPORT_SYMBOL(generic_removexattr); 502