|
@@ -427,6 +427,7 @@ getxattr(struct dentry *d, const char __user *name, void __user *value,
|
|
|
{
|
|
|
ssize_t error;
|
|
|
void *kvalue = NULL;
|
|
|
+ void *vvalue = NULL;
|
|
|
char kname[XATTR_NAME_MAX + 1];
|
|
|
|
|
|
error = strncpy_from_user(kname, name, sizeof(kname));
|
|
@@ -438,9 +439,13 @@ getxattr(struct dentry *d, const char __user *name, void __user *value,
|
|
|
if (size) {
|
|
|
if (size > XATTR_SIZE_MAX)
|
|
|
size = XATTR_SIZE_MAX;
|
|
|
- kvalue = kzalloc(size, GFP_KERNEL);
|
|
|
- if (!kvalue)
|
|
|
- return -ENOMEM;
|
|
|
+ kvalue = kzalloc(size, GFP_KERNEL | __GFP_NOWARN);
|
|
|
+ if (!kvalue) {
|
|
|
+ vvalue = vmalloc(size);
|
|
|
+ if (!vvalue)
|
|
|
+ return -ENOMEM;
|
|
|
+ kvalue = vvalue;
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
error = vfs_getxattr(d, kname, kvalue, size);
|
|
@@ -452,7 +457,10 @@ getxattr(struct dentry *d, const char __user *name, void __user *value,
|
|
|
than XATTR_SIZE_MAX bytes. Not possible. */
|
|
|
error = -E2BIG;
|
|
|
}
|
|
|
- kfree(kvalue);
|
|
|
+ if (vvalue)
|
|
|
+ vfree(vvalue);
|
|
|
+ else
|
|
|
+ kfree(kvalue);
|
|
|
return error;
|
|
|
}
|
|
|
|