]> git.proxmox.com Git - pve-qemu-kvm.git/blob - debian/patches/extra/0003-9pfs-handle-walk-of-.-in-the-root-directory.patch
various CVE fixes
[pve-qemu-kvm.git] / debian / patches / extra / 0003-9pfs-handle-walk-of-.-in-the-root-directory.patch
1 From 348503ea115b336343166b87271208ffc0bdeb0a Mon Sep 17 00:00:00 2001
2 From: Greg Kurz <groug@kaod.org>
3 Date: Tue, 30 Aug 2016 17:02:27 +0200
4 Subject: [PATCH 3/6] 9pfs: handle walk of ".." in the root directory
5
6 The 9P spec at http://man.cat-v.org/plan_9/5/intro says:
7
8 All directories must support walks to the directory .. (dot-dot) meaning
9 parent directory, although by convention directories contain no explicit
10 entry for .. or . (dot). The parent of the root directory of a server's
11 tree is itself.
12
13 This means that a client cannot walk further than the root directory
14 exported by the server. In other words, if the client wants to walk
15 "/.." or "/foo/../..", the server should answer like the request was
16 to walk "/".
17
18 This patch just does that:
19 - we cache the QID of the root directory at attach time
20 - during the walk we compare the QID of each path component with the root
21 QID to detect if we're in a "/.." situation
22 - if so, we skip the current component and go to the next one
23
24 Signed-off-by: Greg Kurz <groug@kaod.org>
25 Reviewed-by: Eric Blake <eblake@redhat.com>
26 Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
27 ---
28 hw/9pfs/9p.c | 40 +++++++++++++++++++++++++++++++---------
29 hw/9pfs/9p.h | 1 +
30 2 files changed, 32 insertions(+), 9 deletions(-)
31
32 diff --git a/hw/9pfs/9p.c b/hw/9pfs/9p.c
33 index 1e96427..1ac05b2 100644
34 --- a/hw/9pfs/9p.c
35 +++ b/hw/9pfs/9p.c
36 @@ -1008,6 +1008,7 @@ static void v9fs_attach(void *opaque)
37 goto out;
38 }
39 err += offset;
40 + memcpy(&s->root_qid, &qid, sizeof(qid));
41 trace_v9fs_attach_return(pdu->tag, pdu->id,
42 qid.type, qid.version, qid.path);
43 /*
44 @@ -1259,6 +1260,14 @@ static bool name_is_illegal(const char *name)
45 return !*name || strchr(name, '/') != NULL;
46 }
47
48 +static bool not_same_qid(const V9fsQID *qid1, const V9fsQID *qid2)
49 +{
50 + return
51 + qid1->type != qid2->type ||
52 + qid1->version != qid2->version ||
53 + qid1->path != qid2->path;
54 +}
55 +
56 static void v9fs_walk(void *opaque)
57 {
58 int name_idx;
59 @@ -1274,6 +1283,7 @@ static void v9fs_walk(void *opaque)
60 V9fsFidState *newfidp = NULL;
61 V9fsPDU *pdu = opaque;
62 V9fsState *s = pdu->s;
63 + V9fsQID qid;
64
65 err = pdu_unmarshal(pdu, offset, "ddw", &fid, &newfid, &nwnames);
66 if (err < 0) {
67 @@ -1307,6 +1317,12 @@ static void v9fs_walk(void *opaque)
68 err = -ENOENT;
69 goto out_nofid;
70 }
71 +
72 + err = fid_to_qid(pdu, fidp, &qid);
73 + if (err < 0) {
74 + goto out;
75 + }
76 +
77 v9fs_path_init(&dpath);
78 v9fs_path_init(&path);
79 /*
80 @@ -1316,16 +1332,22 @@ static void v9fs_walk(void *opaque)
81 v9fs_path_copy(&dpath, &fidp->path);
82 v9fs_path_copy(&path, &fidp->path);
83 for (name_idx = 0; name_idx < nwnames; name_idx++) {
84 - err = v9fs_co_name_to_path(pdu, &dpath, wnames[name_idx].data, &path);
85 - if (err < 0) {
86 - goto out;
87 - }
88 - err = v9fs_co_lstat(pdu, &path, &stbuf);
89 - if (err < 0) {
90 - goto out;
91 + if (not_same_qid(&pdu->s->root_qid, &qid) ||
92 + strcmp("..", wnames[name_idx].data)) {
93 + err = v9fs_co_name_to_path(pdu, &dpath, wnames[name_idx].data,
94 + &path);
95 + if (err < 0) {
96 + goto out;
97 + }
98 +
99 + err = v9fs_co_lstat(pdu, &path, &stbuf);
100 + if (err < 0) {
101 + goto out;
102 + }
103 + stat_to_qid(&stbuf, &qid);
104 + v9fs_path_copy(&dpath, &path);
105 }
106 - stat_to_qid(&stbuf, &qids[name_idx]);
107 - v9fs_path_copy(&dpath, &path);
108 + memcpy(&qids[name_idx], &qid, sizeof(qid));
109 }
110 if (fid == newfid) {
111 BUG_ON(fidp->fid_type != P9_FID_NONE);
112 diff --git a/hw/9pfs/9p.h b/hw/9pfs/9p.h
113 index 1a19418..589b3a5 100644
114 --- a/hw/9pfs/9p.h
115 +++ b/hw/9pfs/9p.h
116 @@ -219,6 +219,7 @@ typedef struct V9fsState
117 int32_t root_fid;
118 Error *migration_blocker;
119 V9fsConf fsconf;
120 + V9fsQID root_qid;
121 } V9fsState;
122
123 /* 9p2000.L open flags */
124 --
125 2.1.4
126