diff options
author | Peter Maydell <peter.maydell@linaro.org> | 2022-02-19 12:59:38 +0000 |
---|---|---|
committer | Peter Maydell <peter.maydell@linaro.org> | 2022-02-19 12:59:38 +0000 |
commit | 439346ce8fa32095433a9abb2aa3564d11283372 (patch) | |
tree | 6f349f7536e1b2e9ee569f7363b9802e82fb8e20 /hw | |
parent | c13b8e9973635f34f3ce4356af27a311c993729c (diff) | |
parent | e64e27d5cb103b7764f1a05b6eda7e7fedd517c5 (diff) | |
download | qemu-439346ce8fa32095433a9abb2aa3564d11283372.zip qemu-439346ce8fa32095433a9abb2aa3564d11283372.tar.gz qemu-439346ce8fa32095433a9abb2aa3564d11283372.tar.bz2 |
Merge remote-tracking branch 'remotes/cschoenebeck/tags/pull-9p-20220217' into staging
9pfs: fixes and cleanup
* Fifth patch fixes a 9pfs server crash that happened on some systems due
to incorrect (system dependant) handling of struct dirent size.
* Tests: Second patch fixes a test error that happened on some systems due
mkdir() being called twice for creating the test directory for the 9p
'local' tests.
* Tests: Third patch fixes a memory leak.
* Tests: The remaining two patches are code cleanup.
# gpg: Signature made Thu 17 Feb 2022 16:19:25 GMT
# gpg: using RSA key 96D8D110CF7AF8084F88590134C2B58765A47395
# gpg: issuer "qemu_oss@crudebyte.com"
# gpg: Good signature from "Christian Schoenebeck <qemu_oss@crudebyte.com>" [unknown]
# gpg: WARNING: This key is not certified with a trusted signature!
# gpg: There is no indication that the signature belongs to the owner.
# Primary key fingerprint: ECAB 1A45 4014 1413 BA38 4926 30DB 47C3 A012 D5F4
# Subkey fingerprint: 96D8 D110 CF7A F808 4F88 5901 34C2 B587 65A4 7395
* remotes/cschoenebeck/tags/pull-9p-20220217:
9pfs: Fix segfault in do_readdir_many caused by struct dirent overread
tests/9pfs: Use g_autofree and g_autoptr where possible
tests/9pfs: Fix leak of local_test_path
tests/9pfs: fix mkdir() being called twice
tests/9pfs: use g_autofree where possible
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Diffstat (limited to 'hw')
-rw-r--r-- | hw/9pfs/9p-synth.c | 18 | ||||
-rw-r--r-- | hw/9pfs/9p-synth.h | 5 | ||||
-rw-r--r-- | hw/9pfs/codir.c | 3 |
3 files changed, 21 insertions, 5 deletions
diff --git a/hw/9pfs/9p-synth.c b/hw/9pfs/9p-synth.c index b38088e..7a7cd5c 100644 --- a/hw/9pfs/9p-synth.c +++ b/hw/9pfs/9p-synth.c @@ -182,7 +182,12 @@ static int synth_opendir(FsContext *ctx, V9fsSynthOpenState *synth_open; V9fsSynthNode *node = *(V9fsSynthNode **)fs_path->data; - synth_open = g_malloc(sizeof(*synth_open)); + /* + * V9fsSynthOpenState contains 'struct dirent' which have OS-specific + * properties, thus it's zero cleared on allocation here and below + * in synth_open. + */ + synth_open = g_new0(V9fsSynthOpenState, 1); synth_open->node = node; node->open_count++; fs->private = synth_open; @@ -220,7 +225,14 @@ static void synth_rewinddir(FsContext *ctx, V9fsFidOpenState *fs) static void synth_direntry(V9fsSynthNode *node, struct dirent *entry, off_t off) { - strcpy(entry->d_name, node->name); + size_t sz = strlen(node->name) + 1; + /* + * 'entry' is always inside of V9fsSynthOpenState which have NAME_MAX + * back padding. Ensure we do not overflow it. + */ + g_assert(sizeof(struct dirent) + NAME_MAX >= + offsetof(struct dirent, d_name) + sz); + memcpy(entry->d_name, node->name, sz); entry->d_ino = node->attr->inode; entry->d_off = off + 1; } @@ -266,7 +278,7 @@ static int synth_open(FsContext *ctx, V9fsPath *fs_path, V9fsSynthOpenState *synth_open; V9fsSynthNode *node = *(V9fsSynthNode **)fs_path->data; - synth_open = g_malloc(sizeof(*synth_open)); + synth_open = g_new0(V9fsSynthOpenState, 1); synth_open->node = node; node->open_count++; fs->private = synth_open; diff --git a/hw/9pfs/9p-synth.h b/hw/9pfs/9p-synth.h index 036d7e4..eeb246f 100644 --- a/hw/9pfs/9p-synth.h +++ b/hw/9pfs/9p-synth.h @@ -41,6 +41,11 @@ typedef struct V9fsSynthOpenState { off_t offset; V9fsSynthNode *node; struct dirent dent; + /* + * Ensure there is enough space for 'dent' above, some systems have a + * d_name size of just 1, which would cause a buffer overrun. + */ + char dent_trailing_space[NAME_MAX]; } V9fsSynthOpenState; int qemu_v9fs_synth_mkdir(V9fsSynthNode *parent, int mode, diff --git a/hw/9pfs/codir.c b/hw/9pfs/codir.c index 032cce0..c0873bd 100644 --- a/hw/9pfs/codir.c +++ b/hw/9pfs/codir.c @@ -143,8 +143,7 @@ static int do_readdir_many(V9fsPDU *pdu, V9fsFidState *fidp, } else { e = e->next = g_malloc0(sizeof(V9fsDirEnt)); } - e->dent = g_malloc0(sizeof(struct dirent)); - memcpy(e->dent, dent, sizeof(struct dirent)); + e->dent = qemu_dirent_dup(dent); /* perform a full stat() for directory entry if requested by caller */ if (dostat) { |