From: Jincheng Miao <jmiao@xxxxxxxxxx> The vcpupin command allowed specifying a negative number for the --vcpu argument. This would the overflow when the underlying virDomainPinVcpu API was called. $ virsh vcpupin r7 -1 0 error: numerical overflow: input too large: 4294967295 Switch the vCPU variable to a unsigned int and parse it using the corresponding function. Also improve the vcpupin test to cover all the defects. Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=1101059 Signed-off-by: Jincheng Miao <jmiao@xxxxxxxxxx> Signed-off-by: Peter Krempa <pkrempa@xxxxxxxxxx> --- Notes: Version 3: - fix multiple problems, improve tests and refactor the error handling a bit better tests/vcpupin | 29 ++++++++++++++++++++++++++++- tools/virsh-domain.c | 35 ++++++++++++++++++----------------- 2 files changed, 46 insertions(+), 18 deletions(-) diff --git a/tests/vcpupin b/tests/vcpupin index f1fb038..9f34ec0 100755 --- a/tests/vcpupin +++ b/tests/vcpupin @@ -34,7 +34,7 @@ fail=0 $abs_top_builddir/tools/virsh --connect test:///default vcpupin test a 0,1 > out 2>&1 test $? = 1 || fail=1 cat <<\EOF > exp || fail=1 -error: vcpupin: Invalid or missing vCPU number. +error: vcpupin: Invalid vCPU number. EOF compare exp out || fail=1 @@ -43,9 +43,36 @@ compare exp out || fail=1 $abs_top_builddir/tools/virsh --connect test:///default vcpupin test 100 0,1 > out 2>&1 test $? = 1 || fail=1 cat <<\EOF > exp || fail=1 +error: vcpupin: vCPU index out of range. + +EOF +compare exp out || fail=1 + +# Negative number +$abs_top_builddir/tools/virsh --connect test:///default vcpupin test -100 0,1 > out 2>&1 +test $? = 1 || fail=1 +cat <<\EOF > exp || fail=1 error: vcpupin: Invalid vCPU number. EOF compare exp out || fail=1 +# missing argument +$abs_top_builddir/tools/virsh --connect test:///default vcpupin test --cpulist 0,1 > out 2>&1 +test $? = 1 || fail=1 +cat <<\EOF > exp || fail=1 +error: vcpupin: Missing vCPU number in pin mode. + +EOF +compare exp out || fail=1 + +# without arguments. This should succeed but the backend function in the +# test driver isn't implemented +$abs_top_builddir/tools/virsh --connect test:///default vcpupin test > out 2>&1 +test $? = 1 || fail=1 +cat <<\EOF > exp || fail=1 +error: this function is not supported by the connection driver: virDomainGetVcpuPinInfo + +EOF +compare exp out || fail=1 (exit $fail); exit $fail diff --git a/tools/virsh-domain.c b/tools/virsh-domain.c index 84a6706..e76418a 100644 --- a/tools/virsh-domain.c +++ b/tools/virsh-domain.c @@ -5797,7 +5797,7 @@ cmdVcpuPin(vshControl *ctl, const vshCmd *cmd) { virDomainInfo info; virDomainPtr dom; - int vcpu = -1; + unsigned int vcpu = 0; const char *cpulist = NULL; bool ret = false; unsigned char *cpumap = NULL; @@ -5809,6 +5809,7 @@ cmdVcpuPin(vshControl *ctl, const vshCmd *cmd) bool live = vshCommandOptBool(cmd, "live"); bool current = vshCommandOptBool(cmd, "current"); bool query = false; /* Query mode if no cpulist */ + int got_vcpu; unsigned int flags = VIR_DOMAIN_AFFECT_CURRENT; VSH_EXCLUSIVE_OPTIONS_VAR(current, live); @@ -5830,29 +5831,29 @@ cmdVcpuPin(vshControl *ctl, const vshCmd *cmd) query = !cpulist; - /* In query mode, "vcpu" is optional */ - if (vshCommandOptInt(cmd, "vcpu", &vcpu) < !query) { - vshError(ctl, "%s", - _("vcpupin: Invalid or missing vCPU number.")); - virDomainFree(dom); - return false; + if ((got_vcpu = vshCommandOptUInt(cmd, "vcpu", &vcpu)) < 0) { + vshError(ctl, "%s", _("vcpupin: Invalid vCPU number.")); + goto cleanup; } - if ((maxcpu = vshNodeGetCPUCount(ctl->conn)) < 0) { - virDomainFree(dom); - return false; + /* In pin mode, "vcpu" is necessary */ + if (!query && got_vcpu == 0) { + vshError(ctl, "%s", _("vcpupin: Missing vCPU number in pin mode.")); + goto cleanup; } if (virDomainGetInfo(dom, &info) != 0) { vshError(ctl, "%s", _("vcpupin: failed to get domain information.")); - virDomainFree(dom); - return false; + goto cleanup; } if (vcpu >= info.nrVirtCpu) { - vshError(ctl, "%s", _("vcpupin: Invalid vCPU number.")); - virDomainFree(dom); - return false; + vshError(ctl, "%s", _("vcpupin: vCPU index out of range.")); + goto cleanup; + } + + if ((maxcpu = vshNodeGetCPUCount(ctl->conn)) < 0) { + goto cleanup; } cpumaplen = VIR_CPU_MAPLEN(maxcpu); @@ -5871,7 +5872,7 @@ cmdVcpuPin(vshControl *ctl, const vshCmd *cmd) vshPrintExtra(ctl, "%s %s\n", _("VCPU:"), _("CPU Affinity")); vshPrintExtra(ctl, "----------------------------------\n"); for (i = 0; i < ncpus; i++) { - if (vcpu != -1 && i != vcpu) + if (got_vcpu && i != vcpu) continue; vshPrint(ctl, "%4zu: ", i); @@ -5880,8 +5881,8 @@ cmdVcpuPin(vshControl *ctl, const vshCmd *cmd) if (!ret) break; } - } + VIR_FREE(cpumaps); goto cleanup; } -- 1.9.3 -- libvir-list mailing list libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list