diff options
author | G. Campana <gcampana+kvm@quarkslab.com> | 2016-11-10 16:21:11 +0100 |
---|---|---|
committer | Will Deacon <will.deacon@arm.com> | 2016-11-28 11:18:51 +0000 |
commit | b09224228296d9febf120f3aa956964cc01a14b5 (patch) | |
tree | db0207650a5f43b1c830f635606e9d0527d3b564 | |
parent | 716b2944e2eb92b4b43ec35c4347b5f9b853e6eb (diff) | |
download | kvmtool-b09224228296d9febf120f3aa956964cc01a14b5.tar.gz |
kvmtool: 9p: fix a buffer overflow in rel_to_abs
Make use of get_full_path_helper() instead of sprintf.
Signed-off-by: G. Campana <gcampana+kvm@quarkslab.com>
Signed-off-by: Will Deacon <will.deacon@arm.com>
-rw-r--r-- | virtio/9p.c | 29 |
1 files changed, 16 insertions, 13 deletions
diff --git a/virtio/9p.c b/virtio/9p.c index 7185bb73..6acbfdda 100644 --- a/virtio/9p.c +++ b/virtio/9p.c @@ -91,15 +91,6 @@ static struct p9_fid *get_fid(struct p9_dev *p9dev, int fid) return new; } -/* Warning: Immediately use value returned from this function */ -static const char *rel_to_abs(struct p9_dev *p9dev, - const char *path, char *abs_path) -{ - sprintf(abs_path, "%s/%s", p9dev->root_dir, path); - - return abs_path; -} - static void stat2qid(struct stat *st, struct p9_qid *qid) { *qid = (struct p9_qid) { @@ -269,6 +260,19 @@ static int get_full_path(char *full_path, size_t size, struct p9_fid *fid, return get_full_path_helper(full_path, size, fid->abs_path, name); } +static int stat_rel(struct p9_dev *p9dev, const char *path, struct stat *st) +{ + char full_path[PATH_MAX]; + + if (get_full_path_helper(full_path, sizeof(full_path), p9dev->root_dir, path) != 0) + return -1; + + if (lstat(full_path, st) != 0) + return -1; + + return 0; +} + static void virtio_p9_open(struct p9_dev *p9dev, struct p9_pdu *pdu, u32 *outlen) { @@ -443,7 +447,6 @@ static void virtio_p9_walk(struct p9_dev *p9dev, for (i = 0; i < nwname; i++) { struct stat st; char tmp[PATH_MAX] = {0}; - char full_path[PATH_MAX]; char *str; int ret; @@ -458,7 +461,7 @@ static void virtio_p9_walk(struct p9_dev *p9dev, free(str); - if (lstat(rel_to_abs(p9dev, tmp, full_path), &st) < 0) + if (stat_rel(p9dev, tmp, &st) != 0) goto err_out; stat2qid(&st, &wqid); @@ -612,7 +615,6 @@ static void virtio_p9_readdir(struct p9_dev *p9dev, struct stat st; struct p9_fid *fid; struct dirent *dent; - char full_path[PATH_MAX]; u64 offset, old_offset; rcount = 0; @@ -643,7 +645,8 @@ static void virtio_p9_readdir(struct p9_dev *p9dev, break; } old_offset = dent->d_off; - lstat(rel_to_abs(p9dev, dent->d_name, full_path), &st); + if (stat_rel(p9dev, dent->d_name, &st) != 0) + memset(&st, -1, sizeof(st)); stat2qid(&st, &qid); read = pdu->write_offset; virtio_p9_pdu_writef(pdu, "Qqbs", &qid, dent->d_off, |