]> xenbits.xensource.com Git - people/liuw/libxenctrl-split/libvirt.git/commitdiff
command: shell-quote when logging commands
authorEric Blake <eblake@redhat.com>
Tue, 28 Aug 2012 18:11:45 +0000 (11:11 -0700)
committerEric Blake <eblake@redhat.com>
Fri, 31 Aug 2012 15:10:58 +0000 (08:10 -0700)
Without this patch, logged command executions can be ambiguous if
the command contained any shell metacharacters.  This has caused
more than one person to attempt to patch clients to add unnecessary
quoting, without realizing that the command itself was run with
correct args, and only the logged output was ambiguous.

* src/util/command.c (virCommandToString): Add shell escapes.
* tests/commandtest.c (test16): Test new behavior.
* tests/commanddata/test16.log: Update expected output.
* tests/qemuxml2argvdata/qemuxml2argv-*.args: Likewise.
* tests/networkxml2argvdata/*.argv: Likewise.

src/util/command.c
tests/commanddata/test16.log
tests/commandtest.c
tests/networkxml2argvdata/nat-network-dns-txt-record.argv
tests/qemuxml2argvdata/qemuxml2argv-disk-drive-network-rbd-auth.args
tests/qemuxml2argvdata/qemuxml2argv-disk-drive-network-rbd.args
tests/qemuxml2argvdata/qemuxml2argv-graphics-vnc.args
tests/qemuxml2argvdata/qemuxml2argv-qemu-ns.args
tests/qemuxml2argvdata/qemuxml2argv-smbios.args

index 49ec1787c118911169df0005095a9c728ab06f91..418b198b920395424341d520109c5894628afbe6 100644 (file)
@@ -1614,9 +1614,10 @@ virCommandWriteArgLog(virCommandPtr cmd, int logfd)
  * virCommandToString:
  * @cmd: the command to convert
  *
- * Call after adding all arguments and environment settings, but before
- * Run/RunAsync, to return a string representation of the environment and
- * arguments of cmd.  If virCommandRun cannot succeed (because of an
+ * Call after adding all arguments and environment settings, but
+ * before Run/RunAsync, to return a string representation of the
+ * environment and arguments of cmd, suitably quoted for pasting into
+ * a shell.  If virCommandRun cannot succeed (because of an
  * out-of-memory condition while building cmd), NULL will be returned.
  * Caller is responsible for freeing the resulting string.
  */
@@ -1639,13 +1640,25 @@ virCommandToString(virCommandPtr cmd)
     }
 
     for (i = 0; i < cmd->nenv; i++) {
-        virBufferAdd(&buf, cmd->env[i], strlen(cmd->env[i]));
+        /* In shell, a='b c' has a different meaning than 'a=b c', so
+         * we must determine where the '=' lives.  */
+        char *eq = strchr(cmd->env[i], '=');
+
+        if (!eq) {
+            virBufferFreeAndReset(&buf);
+            virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
+                           _("invalid use of command API"));
+            return NULL;
+        }
+        eq++;
+        virBufferAdd(&buf, cmd->env[i], eq - cmd->env[i]);
+        virBufferEscapeShell(&buf, eq);
         virBufferAddChar(&buf, ' ');
     }
-    virBufferAdd(&buf, cmd->args[0], strlen(cmd->args[0]));
+    virBufferEscapeShell(&buf, cmd->args[0]);
     for (i = 1; i < cmd->nargs; i++) {
         virBufferAddChar(&buf, ' ');
-        virBufferAdd(&buf, cmd->args[i], strlen(cmd->args[i]));
+        virBufferEscapeShell(&buf, cmd->args[i]);
     }
 
     if (virBufferError(&buf)) {
index 70881650a61d8433c0f88808dcaddb929c798d4c..119dd29e92b14a092c3944d6e01cbbca0ae06d40 100644 (file)
@@ -1 +1 @@
-A=B true C
+A=B C=D  E true F G  H
index b1c752373b149991065e060581789a72e889841c..c00515373aa6628bce1879e3a4a184fccfe9499f 100644 (file)
@@ -607,12 +607,14 @@ static int test16(const void *unused ATTRIBUTE_UNUSED)
 {
     virCommandPtr cmd = virCommandNew("true");
     char *outactual = NULL;
-    const char *outexpect = "A=B true C";
+    const char *outexpect = "A=B C='D  E' true F 'G  H'";
     int ret = -1;
     int fd = -1;
 
     virCommandAddEnvPair(cmd, "A", "B");
-    virCommandAddArg(cmd, "C");
+    virCommandAddEnvPair(cmd, "C", "D  E");
+    virCommandAddArg(cmd, "F");
+    virCommandAddArg(cmd, "G  H");
 
     if ((outactual = virCommandToString(cmd)) == NULL) {
         virErrorPtr err = virGetLastError();
index 1b318716e5ba305bf95a325f6947c4550de044c5..2a6c799e3e374ef330293c531a99dac373879a83 100644 (file)
@@ -1,6 +1,6 @@
 @DNSMASQ@ --strict-order --bind-interfaces \
 --local=// --domain-needed --filterwin2k --conf-file= \
---except-interface lo --txt-record=example,example value \
+--except-interface lo '--txt-record=example,example value' \
 --listen-address 192.168.122.1 --listen-address 192.168.123.1 \
 --listen-address 2001:db8:ac10:fe01::1 \
 --listen-address 2001:db8:ac10:fd01::1 --listen-address 10.24.10.1 \
index b323e913839c5601e7f2db24602c580880285abd..02a98692dadd932be05a03b73cf80fd6c7f70d2c 100644 (file)
@@ -2,9 +2,10 @@ LC_ALL=C PATH=/bin HOME=/home/test USER=test LOGNAME=test \
 /usr/bin/qemu -S -M pc -m 214 -smp 1 -nographic -monitor \
 unix:/tmp/test-monitor,server,nowait -no-acpi -boot c -drive \
 file=/dev/HostVG/QEMUGuest1,if=ide,bus=0,unit=0 -drive \
-file=rbd:pool/image:\
+'file=rbd:pool/image:\
 id=myname:\
 key=QVFDVm41aE82SHpGQWhBQXEwTkN2OGp0SmNJY0UrSE9CbE1RMUE=:\
 auth_supported=cephx\;none:\
-mon_host=mon1.example.org\:6321\;mon2.example.org\:6322\;mon3.example.org\:6322,\
-if=virtio,format=raw -net none -serial none -parallel none -usb
+mon_host=mon1.example.org\:6321\;mon2.example.org\:6322\;\
+mon3.example.org\:6322,\
+if=virtio,format=raw' -net none -serial none -parallel none -usb
index 69cf7c72191603c3122057df068935779c118b5a..61c8f7dd170281d6989160b4642a19338bf56644 100644 (file)
@@ -2,6 +2,7 @@ LC_ALL=C PATH=/bin HOME=/home/test USER=test LOGNAME=test \
 /usr/bin/qemu -S -M pc -m 214 -smp 1 -nographic -monitor \
 unix:/tmp/test-monitor,server,nowait -no-acpi -boot c -drive \
 file=/dev/HostVG/QEMUGuest1,if=ide,bus=0,unit=0 -drive \
-file=rbd:pool/image:auth_supported=none:\
-mon_host=mon1.example.org\:6321\;mon2.example.org\:6322\;mon3.example.org\:6322,\
-if=virtio,format=raw -net none -serial none -parallel none -usb
+'file=rbd:pool/image:auth_supported=none:\
+mon_host=mon1.example.org\:6321\;mon2.example.org\:6322\;\
+mon3.example.org\:6322,\
+if=virtio,format=raw' -net none -serial none -parallel none -usb
index 2af154065c15afc2172c795c0d03960f9fe65590..af99225b00c5214caeee1687006f5fadf6761de4 100644 (file)
@@ -1,4 +1,4 @@
 LC_ALL=C PATH=/bin HOME=/home/test USER=test LOGNAME=test QEMU_AUDIO_DRV=none \
 /usr/bin/qemu -S -M pc -m 214 -smp 1 -monitor unix:/tmp/test-monitor,server,\
 nowait -no-acpi -boot c -hda /dev/HostVG/QEMUGuest1 -net none -serial none \
--parallel none -usb -vnc [2001:1:2:3:4:5:1234:1234]:3
+-parallel none -usb -vnc '[2001:1:2:3:4:5:1234:1234]:3'
index 19450a117b523fce4792bc1fad4a9fe33c621e86..88bdd13f3d50420a6e7d9b46fd773a1a539a2bdd 100644 (file)
@@ -1,4 +1,4 @@
-LC_ALL=C PATH=/bin HOME=/home/test USER=test LOGNAME=test NS=ns BAR= \
+LC_ALL=C PATH=/bin HOME=/home/test USER=test LOGNAME=test NS=ns BAR='' \
 /usr/bin/qemu -S -M pc -m 214 -smp 1 -nographic -monitor \
 unix:/tmp/test-monitor,server,nowait -no-acpi -boot c -hda \
 /dev/HostVG/QEMUGuest1 -net none -serial none -parallel none -usb -unknown \
index 3f6cb818e176570d069dc5ed10f9bdb4b07bef16..ac28badebaa8817b46b712536a969f4b08dfac47 100644 (file)
@@ -1,7 +1,7 @@
 LC_ALL=C PATH=/bin HOME=/home/test USER=test LOGNAME=test /usr/bin/qemu -S -M \
-pc -m 214 -smp 1 -smbios type=0,vendor=LENOVO,version=6FET82WW (3.12 ) -smbios \
-type=1,manufacturer=Fedora,product=Virt-Manager,version=0.8.2-3.fc14,\
+pc -m 214 -smp 1 -smbios 'type=0,vendor=LENOVO,version=6FET82WW (3.12 )' \
+-smbios 'type=1,manufacturer=Fedora,product=Virt-Manager,version=0.8.2-3.fc14,\
 serial=32dfcb37-5af1-552b-357c-be8c3aa38310,\
-uuid=c7a5fdbd-edaf-9455-926a-d65c16db1809,sku=1234567890,family=Red Hat \
+uuid=c7a5fdbd-edaf-9455-926a-d65c16db1809,sku=1234567890,family=Red Hat' \
 -nographic -monitor unix:/tmp/test-monitor,server,nowait -no-acpi -boot c -hda \
 /dev/HostVG/QEMUGuest1 -net none -serial none -parallel none -usb