aboutsummaryrefslogtreecommitdiffstats
path: root/fs/xattr.c
diff options
context:
space:
mode:
authorSasha Levin <levinsasha928@gmail.com>2012-07-30 17:39:13 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2012-07-30 20:25:11 -0400
commit779302e67835fe9a6b74327e54969ba59cb3478a (patch)
tree1e808fa81616ddf170879652f86e3d755694af81 /fs/xattr.c
parent32b4560b04af6e4fee241ea6de6db780eaf354f2 (diff)
fs/xattr.c:getxattr(): improve handling of allocation failures
This allocation can be as large as 64k. - Add __GFP_NOWARN so the falied kmalloc() is silent - Fall back to vmalloc() if the kmalloc() failed Signed-off-by: Sasha Levin <levinsasha928@gmail.com> Cc: Al Viro <viro@zeniv.linux.org.uk> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'fs/xattr.c')
-rw-r--r--fs/xattr.c16
1 files changed, 12 insertions, 4 deletions
diff --git a/fs/xattr.c b/fs/xattr.c
index 1d7ac3790458..4d45b7189e7e 100644
--- a/fs/xattr.c
+++ b/fs/xattr.c
@@ -427,6 +427,7 @@ getxattr(struct dentry *d, const char __user *name, void __user *value,
427{ 427{
428 ssize_t error; 428 ssize_t error;
429 void *kvalue = NULL; 429 void *kvalue = NULL;
430 void *vvalue = NULL;
430 char kname[XATTR_NAME_MAX + 1]; 431 char kname[XATTR_NAME_MAX + 1];
431 432
432 error = strncpy_from_user(kname, name, sizeof(kname)); 433 error = strncpy_from_user(kname, name, sizeof(kname));
@@ -438,9 +439,13 @@ getxattr(struct dentry *d, const char __user *name, void __user *value,
438 if (size) { 439 if (size) {
439 if (size > XATTR_SIZE_MAX) 440 if (size > XATTR_SIZE_MAX)
440 size = XATTR_SIZE_MAX; 441 size = XATTR_SIZE_MAX;
441 kvalue = kzalloc(size, GFP_KERNEL); 442 kvalue = kzalloc(size, GFP_KERNEL | __GFP_NOWARN);
442 if (!kvalue) 443 if (!kvalue) {
443 return -ENOMEM; 444 vvalue = vmalloc(size);
445 if (!vvalue)
446 return -ENOMEM;
447 kvalue = vvalue;
448 }
444 } 449 }
445 450
446 error = vfs_getxattr(d, kname, kvalue, size); 451 error = vfs_getxattr(d, kname, kvalue, size);
@@ -452,7 +457,10 @@ getxattr(struct dentry *d, const char __user *name, void __user *value,
452 than XATTR_SIZE_MAX bytes. Not possible. */ 457 than XATTR_SIZE_MAX bytes. Not possible. */
453 error = -E2BIG; 458 error = -E2BIG;
454 } 459 }
455 kfree(kvalue); 460 if (vvalue)
461 vfree(vvalue);
462 else
463 kfree(kvalue);
456 return error; 464 return error;
457} 465}
458 466