213 lines
6.5 KiB
Diff
213 lines
6.5 KiB
Diff
From 9beb50cd2c05f69f1231eb1f4579d6770ef48359 Mon Sep 17 00:00:00 2001
|
|
From: Theodore Ts'o <tytso@mit.edu>
|
|
Date: Sun, 7 Feb 2021 23:21:58 -0500
|
|
Subject: [PATCH 18/46] libext2fs: fix segault when setting an xattr with an
|
|
unknown prefix
|
|
Content-Type: text/plain
|
|
|
|
Also avoid unnecessary calls to find_ea_index() by caching the short
|
|
name and name index in the ext2_attr structure.
|
|
|
|
Signed-off-by: Theodore Ts'o <tytso@mit.edu>
|
|
Signed-off-by: Lukas Czerner <lczerner@redhat.com>
|
|
---
|
|
lib/ext2fs/ext_attr.c | 64 +++++++++++++++++++++----------------------
|
|
1 file changed, 32 insertions(+), 32 deletions(-)
|
|
|
|
diff --git a/lib/ext2fs/ext_attr.c b/lib/ext2fs/ext_attr.c
|
|
index 871319a5..8a7a17cf 100644
|
|
--- a/lib/ext2fs/ext_attr.c
|
|
+++ b/lib/ext2fs/ext_attr.c
|
|
@@ -293,7 +293,9 @@ errcode_t ext2fs_adjust_ea_refcount(ext2_filsys fs, blk_t blk,
|
|
|
|
/* Manipulate the contents of extended attribute regions */
|
|
struct ext2_xattr {
|
|
+ int name_index;
|
|
char *name;
|
|
+ char *short_name;
|
|
void *value;
|
|
unsigned int value_len;
|
|
ext2_ino_t ea_ino;
|
|
@@ -643,29 +645,23 @@ write_xattrs_to_buffer(ext2_filsys fs, struct ext2_xattr *attrs, int count,
|
|
struct ext2_xattr *x;
|
|
struct ext2_ext_attr_entry *e = entries_start;
|
|
char *end = (char *) entries_start + storage_size;
|
|
- const char *shortname;
|
|
unsigned int value_size;
|
|
- int idx, ret;
|
|
errcode_t err;
|
|
|
|
memset(entries_start, 0, storage_size);
|
|
for (x = attrs; x < attrs + count; x++) {
|
|
- /* Calculate index and shortname position */
|
|
- shortname = x->name;
|
|
- ret = find_ea_index(x->name, &shortname, &idx);
|
|
-
|
|
value_size = ((x->value_len + EXT2_EXT_ATTR_PAD - 1) /
|
|
EXT2_EXT_ATTR_PAD) * EXT2_EXT_ATTR_PAD;
|
|
|
|
/* Fill out e appropriately */
|
|
- e->e_name_len = strlen(shortname);
|
|
- e->e_name_index = (ret ? idx : 0);
|
|
+ e->e_name_len = strlen(x->short_name);
|
|
+ e->e_name_index = x->name_index;
|
|
|
|
e->e_value_size = x->value_len;
|
|
e->e_value_inum = x->ea_ino;
|
|
|
|
/* Store name */
|
|
- memcpy((char *)e + sizeof(*e), shortname, e->e_name_len);
|
|
+ memcpy((char *)e + sizeof(*e), x->short_name, e->e_name_len);
|
|
if (x->ea_ino) {
|
|
e->e_value_offs = 0;
|
|
} else {
|
|
@@ -875,6 +871,8 @@ static errcode_t read_xattrs_from_buffer(struct ext2_xattr_handle *handle,
|
|
memcpy(x->name + prefix_len,
|
|
(char *)entry + sizeof(*entry),
|
|
entry->e_name_len);
|
|
+ x->short_name = x->name + prefix_len;
|
|
+ x->name_index = entry->e_name_index;
|
|
|
|
/* Check & copy value */
|
|
if (!ext2fs_has_feature_ea_inode(handle->fs->super) &&
|
|
@@ -1302,7 +1300,8 @@ out:
|
|
}
|
|
|
|
static errcode_t xattr_update_entry(ext2_filsys fs, struct ext2_xattr *x,
|
|
- const char *name, const void *value,
|
|
+ const char *name, const char *short_name,
|
|
+ int index, const void *value,
|
|
size_t value_len, int in_inode)
|
|
{
|
|
ext2_ino_t ea_ino = 0;
|
|
@@ -1336,8 +1335,11 @@ static errcode_t xattr_update_entry(ext2_filsys fs, struct ext2_xattr *x,
|
|
goto fail;
|
|
}
|
|
|
|
- if (!x->name)
|
|
+ if (!x->name) {
|
|
x->name = new_name;
|
|
+ x->short_name = new_name + (short_name - name);
|
|
+ }
|
|
+ x->name_index = index;
|
|
|
|
if (x->value)
|
|
ext2fs_free_mem(&x->value);
|
|
@@ -1356,31 +1358,27 @@ fail:
|
|
}
|
|
|
|
static int xattr_find_position(struct ext2_xattr *attrs, int count,
|
|
- const char *name)
|
|
+ const char *shortname, int name_idx)
|
|
{
|
|
struct ext2_xattr *x;
|
|
int i;
|
|
- const char *shortname, *x_shortname;
|
|
- int name_idx, x_name_idx;
|
|
int shortname_len, x_shortname_len;
|
|
|
|
- find_ea_index(name, &shortname, &name_idx);
|
|
shortname_len = strlen(shortname);
|
|
|
|
for (i = 0, x = attrs; i < count; i++, x++) {
|
|
- find_ea_index(x->name, &x_shortname, &x_name_idx);
|
|
- if (name_idx < x_name_idx)
|
|
+ if (name_idx < x->name_index)
|
|
break;
|
|
- if (name_idx > x_name_idx)
|
|
+ if (name_idx > x->name_index)
|
|
continue;
|
|
|
|
- x_shortname_len = strlen(x_shortname);
|
|
+ x_shortname_len = strlen(x->short_name);
|
|
if (shortname_len < x_shortname_len)
|
|
break;
|
|
if (shortname_len > x_shortname_len)
|
|
continue;
|
|
|
|
- if (memcmp(shortname, x_shortname, shortname_len) <= 0)
|
|
+ if (memcmp(shortname, x->short_name, shortname_len) <= 0)
|
|
break;
|
|
}
|
|
return i;
|
|
@@ -1395,8 +1393,8 @@ static errcode_t xattr_array_update(struct ext2_xattr_handle *h,
|
|
struct ext2_xattr tmp;
|
|
int add_to_ibody;
|
|
int needed;
|
|
- int name_len, name_idx;
|
|
- const char *shortname;
|
|
+ int name_len, name_idx = 0;
|
|
+ const char *shortname = name;
|
|
int new_idx;
|
|
int ret;
|
|
|
|
@@ -1423,7 +1421,8 @@ static errcode_t xattr_array_update(struct ext2_xattr_handle *h,
|
|
|
|
/* Update the existing entry. */
|
|
ret = xattr_update_entry(h->fs, &h->attrs[old_idx], name,
|
|
- value, value_len, in_inode);
|
|
+ shortname, name_idx, value,
|
|
+ value_len, in_inode);
|
|
if (ret)
|
|
return ret;
|
|
if (h->ibody_count <= old_idx) {
|
|
@@ -1451,7 +1450,8 @@ static errcode_t xattr_array_update(struct ext2_xattr_handle *h,
|
|
if (old_idx >= 0) {
|
|
/* Update the existing entry. */
|
|
ret = xattr_update_entry(h->fs, &h->attrs[old_idx], name,
|
|
- value, value_len, in_inode);
|
|
+ shortname, name_idx, value,
|
|
+ value_len, in_inode);
|
|
if (ret)
|
|
return ret;
|
|
if (old_idx < h->ibody_count) {
|
|
@@ -1460,7 +1460,8 @@ static errcode_t xattr_array_update(struct ext2_xattr_handle *h,
|
|
* entries in the block are sorted.
|
|
*/
|
|
new_idx = xattr_find_position(h->attrs + h->ibody_count,
|
|
- h->count - h->ibody_count, name);
|
|
+ h->count - h->ibody_count,
|
|
+ shortname, name_idx);
|
|
new_idx += h->ibody_count - 1;
|
|
tmp = h->attrs[old_idx];
|
|
memmove(h->attrs + old_idx, h->attrs + old_idx + 1,
|
|
@@ -1472,7 +1473,8 @@ static errcode_t xattr_array_update(struct ext2_xattr_handle *h,
|
|
}
|
|
|
|
new_idx = xattr_find_position(h->attrs + h->ibody_count,
|
|
- h->count - h->ibody_count, name);
|
|
+ h->count - h->ibody_count,
|
|
+ shortname, name_idx);
|
|
new_idx += h->ibody_count;
|
|
add_to_ibody = 0;
|
|
|
|
@@ -1483,8 +1485,8 @@ add_new:
|
|
return ret;
|
|
}
|
|
|
|
- ret = xattr_update_entry(h->fs, &h->attrs[h->count], name, value,
|
|
- value_len, in_inode);
|
|
+ ret = xattr_update_entry(h->fs, &h->attrs[h->count], name, shortname,
|
|
+ name_idx, value, value_len, in_inode);
|
|
if (ret)
|
|
return ret;
|
|
|
|
@@ -1502,12 +1504,10 @@ static int space_used(struct ext2_xattr *attrs, int count)
|
|
{
|
|
int total = 0;
|
|
struct ext2_xattr *x;
|
|
- const char *shortname;
|
|
- int i, len, name_idx;
|
|
+ int i, len;
|
|
|
|
for (i = 0, x = attrs; i < count; i++, x++) {
|
|
- find_ea_index(x->name, &shortname, &name_idx);
|
|
- len = strlen(shortname);
|
|
+ len = strlen(x->short_name);
|
|
total += EXT2_EXT_ATTR_LEN(len);
|
|
if (!x->ea_ino)
|
|
total += EXT2_EXT_ATTR_SIZE(x->value_len);
|
|
--
|
|
2.35.1
|
|
|