Skip to content

Commit 3c0a63d

Browse files
Vito Caputosashalevin
authored andcommitted
ovl: use a minimal buffer in ovl_copy_xattr
[ Upstream commit e4ad29f ] Rather than always allocating the high-order XATTR_SIZE_MAX buffer which is costly and prone to failure, only allocate what is needed and realloc if necessary. Fixes coreos/bugs#489 Signed-off-by: Miklos Szeredi <[email protected]> Cc: <[email protected]> Signed-off-by: Sasha Levin <[email protected]>
1 parent c000201 commit 3c0a63d

File tree

1 file changed

+25
-14
lines changed

1 file changed

+25
-14
lines changed

fs/overlayfs/copy_up.c

Lines changed: 25 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -22,9 +22,9 @@
2222

2323
int ovl_copy_xattr(struct dentry *old, struct dentry *new)
2424
{
25-
ssize_t list_size, size;
26-
char *buf, *name, *value;
27-
int error;
25+
ssize_t list_size, size, value_size = 0;
26+
char *buf, *name, *value = NULL;
27+
int uninitialized_var(error);
2828

2929
if (!old->d_inode->i_op->getxattr ||
3030
!new->d_inode->i_op->getxattr)
@@ -41,29 +41,40 @@ int ovl_copy_xattr(struct dentry *old, struct dentry *new)
4141
if (!buf)
4242
return -ENOMEM;
4343

44-
error = -ENOMEM;
45-
value = kmalloc(XATTR_SIZE_MAX, GFP_KERNEL);
46-
if (!value)
47-
goto out;
48-
4944
list_size = vfs_listxattr(old, buf, list_size);
5045
if (list_size <= 0) {
5146
error = list_size;
52-
goto out_free_value;
47+
goto out;
5348
}
5449

5550
for (name = buf; name < (buf + list_size); name += strlen(name) + 1) {
56-
size = vfs_getxattr(old, name, value, XATTR_SIZE_MAX);
51+
retry:
52+
size = vfs_getxattr(old, name, value, value_size);
53+
if (size == -ERANGE)
54+
size = vfs_getxattr(old, name, NULL, 0);
55+
5756
if (size < 0) {
5857
error = size;
59-
goto out_free_value;
58+
break;
59+
}
60+
61+
if (size > value_size) {
62+
void *new;
63+
64+
new = krealloc(value, size, GFP_KERNEL);
65+
if (!new) {
66+
error = -ENOMEM;
67+
break;
68+
}
69+
value = new;
70+
value_size = size;
71+
goto retry;
6072
}
73+
6174
error = vfs_setxattr(new, name, value, size, 0);
6275
if (error)
63-
goto out_free_value;
76+
break;
6477
}
65-
66-
out_free_value:
6778
kfree(value);
6879
out:
6980
kfree(buf);

0 commit comments

Comments
 (0)