1 From 86a37b0a0ed8f32db819782ca4a367712ece1453 Mon Sep 17 00:00:00 2001
2 From: Li Qiang <liqiang6-s@360.cn>
3 Date: Tue, 1 Nov 2016 12:00:40 +0100
4 Subject: [PATCH 8/8] 9pfs: fix integer overflow issue in xattr read/write
6 Content-Type: text/plain; charset=UTF-8
7 Content-Transfer-Encoding: 8bit
9 The v9fs_xattr_read() and v9fs_xattr_write() are passed a guest
10 originated offset: they must ensure this offset does not go beyond
11 the size of the extended attribute that was set in v9fs_xattrcreate().
12 Unfortunately, the current code implement these checks with unsafe
13 calculations on 32 and 64 bit values, which may allow a malicious
14 guest to cause OOB access anyway.
16 Fix this by comparing the offset and the xattr size, which are
17 both uint64_t, before trying to compute the effective number of bytes
20 Suggested-by: Greg Kurz <groug@kaod.org>
21 Signed-off-by: Li Qiang <liqiang6-s@360.cn>
22 Reviewed-by: Greg Kurz <groug@kaod.org>
23 Reviewed-By: Guido Günther <agx@sigxcpu.org>
24 Signed-off-by: Greg Kurz <groug@kaod.org>
26 hw/9pfs/9p.c | 32 ++++++++++++--------------------
27 1 file changed, 12 insertions(+), 20 deletions(-)
29 diff --git a/hw/9pfs/9p.c b/hw/9pfs/9p.c
30 index af07846..fc4f2cd 100644
33 @@ -1628,20 +1628,17 @@ static int v9fs_xattr_read(V9fsState *s, V9fsPDU *pdu, V9fsFidState *fidp,
39 + uint64_t read_count;
40 V9fsVirtioState *v = container_of(s, V9fsVirtioState, state);
41 VirtQueueElement *elem = v->elems[pdu->idx];
43 - xattr_len = fidp->fs.xattr.len;
44 - read_count = xattr_len - off;
45 + if (fidp->fs.xattr.len < off) {
48 + read_count = fidp->fs.xattr.len - off;
50 if (read_count > max_count) {
51 read_count = max_count;
52 - } else if (read_count < 0) {
54 - * read beyond XATTR value
58 err = pdu_marshal(pdu, offset, "d", read_count);
60 @@ -1969,23 +1966,18 @@ static int v9fs_xattr_write(V9fsState *s, V9fsPDU *pdu, V9fsFidState *fidp,
66 + uint64_t write_count;
70 - xattr_len = fidp->fs.xattr.len;
71 - write_count = xattr_len - off;
72 - if (write_count > count) {
73 - write_count = count;
74 - } else if (write_count < 0) {
76 - * write beyond XATTR value len specified in
79 + if (fidp->fs.xattr.len < off) {
83 + write_count = fidp->fs.xattr.len - off;
84 + if (write_count > count) {
85 + write_count = count;
87 err = pdu_marshal(pdu, offset, "d", write_count);