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 = kzalloc(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 158 if (!strncmp(kname, XATTR_SECURITY_PREFIX, 159 sizeof XATTR_SECURITY_PREFIX - 1)) { 160 const char *suffix = kname + sizeof XATTR_SECURITY_PREFIX - 1; 161 int rv = security_inode_getsecurity(d->d_inode, suffix, kvalue, 162 size, error); 163 /* Security module active: overwrite error value */ 164 if (rv != -EOPNOTSUPP) 165 error = rv; 166 } 167 if (error > 0) { 168 if (size && copy_to_user(value, kvalue, error)) 169 error = -EFAULT; 170 } else if (error == -ERANGE && size >= XATTR_SIZE_MAX) { 171 /* The file system tried to returned a value bigger 172 than XATTR_SIZE_MAX bytes. Not possible. */ 173 error = -E2BIG; 174 } 175 out: 176 if (kvalue) 177 kfree(kvalue); 178 return error; 179 } 180 181 asmlinkage ssize_t 182 sys_getxattr(char __user *path, char __user *name, void __user *value, 183 size_t size) 184 { 185 struct nameidata nd; 186 ssize_t error; 187 188 error = user_path_walk(path, &nd); 189 if (error) 190 return error; 191 error = getxattr(nd.dentry, name, value, size); 192 path_release(&nd); 193 return error; 194 } 195 196 asmlinkage ssize_t 197 sys_lgetxattr(char __user *path, char __user *name, void __user *value, 198 size_t size) 199 { 200 struct nameidata nd; 201 ssize_t error; 202 203 error = user_path_walk_link(path, &nd); 204 if (error) 205 return error; 206 error = getxattr(nd.dentry, name, value, size); 207 path_release(&nd); 208 return error; 209 } 210 211 asmlinkage ssize_t 212 sys_fgetxattr(int fd, char __user *name, void __user *value, size_t size) 213 { 214 struct file *f; 215 ssize_t error = -EBADF; 216 217 f = fget(fd); 218 if (!f) 219 return error; 220 error = getxattr(f->f_dentry, name, value, size); 221 fput(f); 222 return error; 223 } 224 225 /* 226 * Extended attribute LIST operations 227 */ 228 static ssize_t 229 listxattr(struct dentry *d, char __user *list, size_t size) 230 { 231 ssize_t error; 232 char *klist = NULL; 233 234 if (size) { 235 if (size > XATTR_LIST_MAX) 236 size = XATTR_LIST_MAX; 237 klist = kmalloc(size, GFP_KERNEL); 238 if (!klist) 239 return -ENOMEM; 240 } 241 242 error = security_inode_listxattr(d); 243 if (error) 244 goto out; 245 error = -EOPNOTSUPP; 246 if (d->d_inode->i_op && d->d_inode->i_op->listxattr) { 247 error = d->d_inode->i_op->listxattr(d, klist, size); 248 } else { 249 error = security_inode_listsecurity(d->d_inode, klist, size); 250 if (size && error >= size) 251 error = -ERANGE; 252 } 253 if (error > 0) { 254 if (size && copy_to_user(list, klist, error)) 255 error = -EFAULT; 256 } else if (error == -ERANGE && size >= XATTR_LIST_MAX) { 257 /* The file system tried to returned a list bigger 258 than XATTR_LIST_MAX bytes. Not possible. */ 259 error = -E2BIG; 260 } 261 out: 262 if (klist) 263 kfree(klist); 264 return error; 265 } 266 267 asmlinkage ssize_t 268 sys_listxattr(char __user *path, char __user *list, size_t size) 269 { 270 struct nameidata nd; 271 ssize_t error; 272 273 error = user_path_walk(path, &nd); 274 if (error) 275 return error; 276 error = listxattr(nd.dentry, list, size); 277 path_release(&nd); 278 return error; 279 } 280 281 asmlinkage ssize_t 282 sys_llistxattr(char __user *path, char __user *list, size_t size) 283 { 284 struct nameidata nd; 285 ssize_t error; 286 287 error = user_path_walk_link(path, &nd); 288 if (error) 289 return error; 290 error = listxattr(nd.dentry, list, size); 291 path_release(&nd); 292 return error; 293 } 294 295 asmlinkage ssize_t 296 sys_flistxattr(int fd, char __user *list, size_t size) 297 { 298 struct file *f; 299 ssize_t error = -EBADF; 300 301 f = fget(fd); 302 if (!f) 303 return error; 304 error = listxattr(f->f_dentry, list, size); 305 fput(f); 306 return error; 307 } 308 309 /* 310 * Extended attribute REMOVE operations 311 */ 312 static long 313 removexattr(struct dentry *d, char __user *name) 314 { 315 int error; 316 char kname[XATTR_NAME_MAX + 1]; 317 318 error = strncpy_from_user(kname, name, sizeof(kname)); 319 if (error == 0 || error == sizeof(kname)) 320 error = -ERANGE; 321 if (error < 0) 322 return error; 323 324 error = -EOPNOTSUPP; 325 if (d->d_inode->i_op && d->d_inode->i_op->removexattr) { 326 error = security_inode_removexattr(d, kname); 327 if (error) 328 goto out; 329 down(&d->d_inode->i_sem); 330 error = d->d_inode->i_op->removexattr(d, kname); 331 up(&d->d_inode->i_sem); 332 if (!error) 333 fsnotify_xattr(d); 334 } 335 out: 336 return error; 337 } 338 339 asmlinkage long 340 sys_removexattr(char __user *path, char __user *name) 341 { 342 struct nameidata nd; 343 int error; 344 345 error = user_path_walk(path, &nd); 346 if (error) 347 return error; 348 error = removexattr(nd.dentry, name); 349 path_release(&nd); 350 return error; 351 } 352 353 asmlinkage long 354 sys_lremovexattr(char __user *path, char __user *name) 355 { 356 struct nameidata nd; 357 int error; 358 359 error = user_path_walk_link(path, &nd); 360 if (error) 361 return error; 362 error = removexattr(nd.dentry, name); 363 path_release(&nd); 364 return error; 365 } 366 367 asmlinkage long 368 sys_fremovexattr(int fd, char __user *name) 369 { 370 struct file *f; 371 int error = -EBADF; 372 373 f = fget(fd); 374 if (!f) 375 return error; 376 error = removexattr(f->f_dentry, name); 377 fput(f); 378 return error; 379 } 380 381 382 static const char * 383 strcmp_prefix(const char *a, const char *a_prefix) 384 { 385 while (*a_prefix && *a == *a_prefix) { 386 a++; 387 a_prefix++; 388 } 389 return *a_prefix ? NULL : a; 390 } 391 392 /* 393 * In order to implement different sets of xattr operations for each xattr 394 * prefix with the generic xattr API, a filesystem should create a 395 * null-terminated array of struct xattr_handler (one for each prefix) and 396 * hang a pointer to it off of the s_xattr field of the superblock. 397 * 398 * The generic_fooxattr() functions will use this list to dispatch xattr 399 * operations to the correct xattr_handler. 400 */ 401 #define for_each_xattr_handler(handlers, handler) \ 402 for ((handler) = *(handlers)++; \ 403 (handler) != NULL; \ 404 (handler) = *(handlers)++) 405 406 /* 407 * Find the xattr_handler with the matching prefix. 408 */ 409 static struct xattr_handler * 410 xattr_resolve_name(struct xattr_handler **handlers, const char **name) 411 { 412 struct xattr_handler *handler; 413 414 if (!*name) 415 return NULL; 416 417 for_each_xattr_handler(handlers, handler) { 418 const char *n = strcmp_prefix(*name, handler->prefix); 419 if (n) { 420 *name = n; 421 break; 422 } 423 } 424 return handler; 425 } 426 427 /* 428 * Find the handler for the prefix and dispatch its get() operation. 429 */ 430 ssize_t 431 generic_getxattr(struct dentry *dentry, const char *name, void *buffer, size_t size) 432 { 433 struct xattr_handler *handler; 434 struct inode *inode = dentry->d_inode; 435 436 handler = xattr_resolve_name(inode->i_sb->s_xattr, &name); 437 if (!handler) 438 return -EOPNOTSUPP; 439 return handler->get(inode, name, buffer, size); 440 } 441 442 /* 443 * Combine the results of the list() operation from every xattr_handler in the 444 * list. 445 */ 446 ssize_t 447 generic_listxattr(struct dentry *dentry, char *buffer, size_t buffer_size) 448 { 449 struct inode *inode = dentry->d_inode; 450 struct xattr_handler *handler, **handlers = inode->i_sb->s_xattr; 451 unsigned int size = 0; 452 453 if (!buffer) { 454 for_each_xattr_handler(handlers, handler) 455 size += handler->list(inode, NULL, 0, NULL, 0); 456 } else { 457 char *buf = buffer; 458 459 for_each_xattr_handler(handlers, handler) { 460 size = handler->list(inode, buf, buffer_size, NULL, 0); 461 if (size > buffer_size) 462 return -ERANGE; 463 buf += size; 464 buffer_size -= size; 465 } 466 size = buf - buffer; 467 } 468 return size; 469 } 470 471 /* 472 * Find the handler for the prefix and dispatch its set() operation. 473 */ 474 int 475 generic_setxattr(struct dentry *dentry, const char *name, const void *value, size_t size, int flags) 476 { 477 struct xattr_handler *handler; 478 struct inode *inode = dentry->d_inode; 479 480 if (size == 0) 481 value = ""; /* empty EA, do not remove */ 482 handler = xattr_resolve_name(inode->i_sb->s_xattr, &name); 483 if (!handler) 484 return -EOPNOTSUPP; 485 return handler->set(inode, name, value, size, flags); 486 } 487 488 /* 489 * Find the handler for the prefix and dispatch its set() operation to remove 490 * any associated extended attribute. 491 */ 492 int 493 generic_removexattr(struct dentry *dentry, const char *name) 494 { 495 struct xattr_handler *handler; 496 struct inode *inode = dentry->d_inode; 497 498 handler = xattr_resolve_name(inode->i_sb->s_xattr, &name); 499 if (!handler) 500 return -EOPNOTSUPP; 501 return handler->set(inode, name, NULL, 0, XATTR_REPLACE); 502 } 503 504 EXPORT_SYMBOL(generic_getxattr); 505 EXPORT_SYMBOL(generic_listxattr); 506 EXPORT_SYMBOL(generic_setxattr); 507 EXPORT_SYMBOL(generic_removexattr); 508