aboutsummaryrefslogtreecommitdiffstats
path: root/main/xen/xsa48-4.2.patch
blob: 998dbcb1d516422e2ba9570ec39eccc936d0d5f1 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
Add -f FMT  / --format FMT arg to qemu-nbd

From: "Daniel P. Berrange" <berrange@redhat.com>

Currently the qemu-nbd program will auto-detect the format of
any disk it is given. This behaviour is known to be insecure.
For example, if qemu-nbd initially exposes a 'raw' file to an
unprivileged app, and that app runs

   'qemu-img create -f qcow2 -o backing_file=/etc/shadow /dev/nbd0'

then the next time the app is started, the qemu-nbd will now
detect it as a 'qcow2' file and expose /etc/shadow to the
unprivileged app.

The only way to avoid this is to explicitly tell qemu-nbd what
disk format to use on the command line, completely disabling
auto-detection. This patch adds a '-f' / '--format' arg for
this purpose, mirroring what is already available via qemu-img
and qemu commands.

  qemu-nbd --format raw -p 9000 evil.img

will now always use raw, regardless of what format 'evil.img'
looks like it contains

Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
[Use errx, not err. - Paolo]
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
Signed-off-by: Stefano Stabellini <stefano.stabellini@eu.citrix.com>

[ This is a security issue, CVE-2013-1922 / XSA-48. ]

diff --git a/qemu-nbd.c b/qemu-nbd.c
index 291cba2..8fbe2cf 100644
--- a/tools/qemu-xen/qemu-nbd.c
+++ b/tools/qemu-xen/qemu-nbd.c
@@ -247,6 +247,7 @@ out:
 int main(int argc, char **argv)
 {
     BlockDriverState *bs;
+    BlockDriver *drv;
     off_t dev_offset = 0;
     off_t offset = 0;
     uint32_t nbdflags = 0;
@@ -256,7 +257,7 @@ int main(int argc, char **argv)
     struct sockaddr_in addr;
     socklen_t addr_len = sizeof(addr);
     off_t fd_size;
-    const char *sopt = "hVb:o:p:rsnP:c:dvk:e:t";
+    const char *sopt = "hVb:o:p:rsnP:c:dvk:e:f:t";
     struct option lopt[] = {
         { "help", 0, NULL, 'h' },
         { "version", 0, NULL, 'V' },
@@ -271,6 +272,7 @@ int main(int argc, char **argv)
         { "snapshot", 0, NULL, 's' },
         { "nocache", 0, NULL, 'n' },
         { "shared", 1, NULL, 'e' },
+        { "format", 1, NULL, 'f' },
         { "persistent", 0, NULL, 't' },
         { "verbose", 0, NULL, 'v' },
         { NULL, 0, NULL, 0 }
@@ -292,6 +294,7 @@ int main(int argc, char **argv)
     int max_fd;
     int persistent = 0;
     pthread_t client_thread;
+    const char *fmt = NULL;
 
     /* The client thread uses SIGTERM to interrupt the server.  A signal
      * handler ensures that "qemu-nbd -v -c" exits with a nice status code.
@@ -368,6 +371,9 @@ int main(int argc, char **argv)
                 errx(EXIT_FAILURE, "Shared device number must be greater than 0\n");
             }
             break;
+        case 'f':
+            fmt = optarg;
+            break;
 	case 't':
 	    persistent = 1;
 	    break;
@@ -478,9 +484,19 @@ int main(int argc, char **argv)
     bdrv_init();
     atexit(bdrv_close_all);
 
+    if (fmt) {
+        drv = bdrv_find_format(fmt);
+        if (!drv) {
+            errx(EXIT_FAILURE, "Unknown file format '%s'", fmt);
+        }
+    } else {
+        drv = NULL;
+    }
+
     bs = bdrv_new("hda");
     srcpath = argv[optind];
-    if ((ret = bdrv_open(bs, srcpath, flags, NULL)) < 0) {
+    ret = bdrv_open(bs, srcpath, flags, drv);
+    if (ret < 0) {
         errno = -ret;
         err(EXIT_FAILURE, "Failed to bdrv_open '%s'", argv[optind]);
     }
diff --git a/qemu-nbd.texi b/qemu-nbd.texi
index 44996cc..f56c68e 100644
--- a/tools/qemu-xen/qemu-nbd.texi
+++ b/tools/qemu-xen/qemu-nbd.texi
@@ -36,6 +36,8 @@ Export Qemu disk image using NBD protocol.
   disconnect the specified device
 @item -e, --shared=@var{num}
   device can be shared by @var{num} clients (default @samp{1})
+@item -f, --format=@var{fmt}
+  force block driver for format @var{fmt} instead of auto-detecting
 @item -t, --persistent
   don't exit on the last connection
 @item -v, --verbose