Re: [libvirt] [PATCH] util: Prevent libvirtd crash from virPCIDeviceAddressIsEqual()

2013-05-02 Thread Alex Jia

On 04/29/2013 02:48 AM, Laine Stump wrote:

On 04/28/2013 06:12 AM, Alex Jia wrote:

GDB backtrace:

Breakpoint 1, virPCIGetVirtualFunctionIndex (pf_sysfs_device_link=0x7fc04400f470 
/sys/bus/pci/devices/:03:00.1, vf_sysfs_device_link=optimized out, 
vf_index=vf_index@entry=0x7fc06897b8f4)
 at util/virpci.c:2107
2107if (virPCIDeviceAddressIsEqual(vf_bdf, virt_fns[i])) {
(gdb) p *vf_bdf
$1 = {domain = 0, bus = 3, slot = 16, function = 1}
(gdb) l
2102 virtual_functions), pf_sysfs_device_link);
2103goto out;
2104}
2105
2106for (i = 0; i  num_virt_fns; i++) {
2107if (virPCIDeviceAddressIsEqual(vf_bdf, virt_fns[i])) {
2108*vf_index = i;
2109ret = 0;
2110break;
2111}
(gdb) p num_virt_fns
$46 = 2
(gdb) p virt_fns[0]
$48 = (virPCIDeviceAddressPtr) 0x0
(gdb) s
virPCIDeviceAddressIsEqual (bdf2=0x0, bdf1=0x7fc04400f330) at util/virpci.c:1844
1844(bdf1-slot == bdf2-slot)
(gdb) s

Program received signal SIGSEGV, Segmentation fault.

RHBZ: https://bugzilla.redhat.com/show_bug.cgi?id=957416

Signed-off-by: Alex Jiaa...@redhat.com
---
  src/util/virpci.c |3 ++-
  1 files changed, 2 insertions(+), 1 deletions(-)

diff --git a/src/util/virpci.c b/src/util/virpci.c
index 97bba74..dda044c 100644
--- a/src/util/virpci.c
+++ b/src/util/virpci.c
@@ -1897,7 +1897,8 @@ static bool
  virPCIDeviceAddressIsEqual(virPCIDeviceAddressPtr bdf1,
 virPCIDeviceAddressPtr bdf2)
  {
-return ((bdf1-domain == bdf2-domain)
+return (bdf1  bdf2
+(bdf1-domain == bdf2-domain)
  (bdf1-bus == bdf2-bus)
  (bdf1-slot == bdf2-slot)
  (bdf1-function == bdf2-function));

NACK.

This patch only fixes the symptom (not the root cause), and only in the
case of starting a domain with aninterface type='hostdev'. It doesn't
fix the second crash described in the BZ when running virsh
nodedev-dumpxml - the code path of that doesn't ever get to


Yes, I just noticed this, it should be different code path.


virPCIDeviceAddressIsEqual() (but *does* call the function that actually
has the bug).


Yes, another bug.


The root cause of these crashes was a typo introduced just before the
release of 1.0.4. I found that problem and pushed the correct patch on
April 9:

http://libvirt.org/git/?p=libvirt.git;a=commit;h=9579b6bc209b46a0f079b21455b598c817925b48


It should be okay if the patch is backported into rhel.

(Beyond that, I don't like the idea of ignoring a NULL pointer -
virPCIDeviceAddressIsEqual should always be passed non-NULL pointers,
and its only current caller does guarantee that (except for when it has
a bug). If we want virPCIDeviceAddressIsEqual to do something with NULL
pointers, it should be logging an error and failing, but that would
complicate the interface to the function beyond just returning a
true/false (it would have to be tri-state, and the caller would need to


Yes, the function interface will be more complex and return value should
be tri-state not simple true/false.


check all three possibilities). I think in this case it's better for the
caller to make sure the pointers it sends are valid.)


Yes, a simple way is the caller makes sure pointers is Non-NULL, maybe,
we need also to add comment The caller should make sure the pointers
it sends are valid into the virPCIDeviceAddressIsEqual(). However,
in order to avoid the caller missing argument judgement, I think we
should also fix virPCIDeviceAddressIsEqual().

Thanks for your comments,
Alex

--
libvir-list mailing list
libvir-list@redhat.com
https://www.redhat.com/mailman/listinfo/libvir-list


--
libvir-list mailing list
libvir-list@redhat.com
https://www.redhat.com/mailman/listinfo/libvir-list


Re: [libvirt] [PATCH] util: Prevent libvirtd crash from virPCIDeviceAddressIsEqual()

2013-05-02 Thread Laine Stump
On 05/02/2013 02:06 AM, Alex Jia wrote:
 On 04/29/2013 02:48 AM, Laine Stump wrote:
 On 04/28/2013 06:12 AM, Alex Jia wrote:
 GDB backtrace:

 Breakpoint 1, virPCIGetVirtualFunctionIndex
 (pf_sysfs_device_link=0x7fc04400f470
 /sys/bus/pci/devices/:03:00.1, vf_sysfs_device_link=optimized
 out, vf_index=vf_index@entry=0x7fc06897b8f4)
  at util/virpci.c:2107
 2107if (virPCIDeviceAddressIsEqual(vf_bdf, virt_fns[i])) {
 (gdb) p *vf_bdf
 $1 = {domain = 0, bus = 3, slot = 16, function = 1}
 (gdb) l
 2102 virtual_functions),
 pf_sysfs_device_link);
 2103goto out;
 2104}
 2105
 2106for (i = 0; i  num_virt_fns; i++) {
 2107if (virPCIDeviceAddressIsEqual(vf_bdf, virt_fns[i])) {
 2108*vf_index = i;
 2109ret = 0;
 2110break;
 2111}
 (gdb) p num_virt_fns
 $46 = 2
 (gdb) p virt_fns[0]
 $48 = (virPCIDeviceAddressPtr) 0x0
 (gdb) s
 virPCIDeviceAddressIsEqual (bdf2=0x0, bdf1=0x7fc04400f330) at
 util/virpci.c:1844
 1844(bdf1-slot == bdf2-slot)
 (gdb) s

 Program received signal SIGSEGV, Segmentation fault.

 RHBZ: https://bugzilla.redhat.com/show_bug.cgi?id=957416

 Signed-off-by: Alex Jiaa...@redhat.com
 ---
   src/util/virpci.c |3 ++-
   1 files changed, 2 insertions(+), 1 deletions(-)

 diff --git a/src/util/virpci.c b/src/util/virpci.c
 index 97bba74..dda044c 100644
 --- a/src/util/virpci.c
 +++ b/src/util/virpci.c
 @@ -1897,7 +1897,8 @@ static bool
   virPCIDeviceAddressIsEqual(virPCIDeviceAddressPtr bdf1,
  virPCIDeviceAddressPtr bdf2)
   {
 -return ((bdf1-domain == bdf2-domain)
 +return (bdf1  bdf2
 +(bdf1-domain == bdf2-domain)
   (bdf1-bus == bdf2-bus)
   (bdf1-slot == bdf2-slot)
   (bdf1-function == bdf2-function));
 NACK.

 This patch only fixes the symptom (not the root cause), and only in the
 case of starting a domain with aninterface type='hostdev'. It doesn't
 fix the second crash described in the BZ when running virsh
 nodedev-dumpxml - the code path of that doesn't ever get to

 Yes, I just noticed this, it should be different code path.

 virPCIDeviceAddressIsEqual() (but *does* call the function that actually
 has the bug).

 Yes, another bug.


IMO, the only bug here.



 The root cause of these crashes was a typo introduced just before the
 release of 1.0.4. I found that problem and pushed the correct patch on
 April 9:

 http://libvirt.org/git/?p=libvirt.git;a=commit;h=9579b6bc209b46a0f079b21455b598c817925b48


 It should be okay if the patch is backported into rhel.


No backport is needed. This bug was only in one release of libvirt, and
that release is not (and almost surely will not be) in any public RHEL
or Fedora release.


 (Beyond that, I don't like the idea of ignoring a NULL pointer -
 virPCIDeviceAddressIsEqual should always be passed non-NULL pointers,
 and its only current caller does guarantee that (except for when it has
 a bug). If we want virPCIDeviceAddressIsEqual to do something with NULL
 pointers, it should be logging an error and failing, but that would
 complicate the interface to the function beyond just returning a
 true/false (it would have to be tri-state, and the caller would need to

 Yes, the function interface will be more complex and return value should
 be tri-state not simple true/false.


Which will make the code in the caller unnecessarily more complex, since
we've already checked for a valid pointer and handled it earlier in that
same function (or to be more exact, a function called by that one -
virPCIGetVirtualFunctions(), which does guarantee that only non-NULL
pointers are placed into the array (when written correctly, as it is now
after the bugfix patch above).



 check all three possibilities). I think in this case it's better for the
 caller to make sure the pointers it sends are valid.)

 Yes, a simple way is the caller makes sure pointers is Non-NULL, maybe,
 we need also to add comment The caller should make sure the pointers
 it sends are valid into the virPCIDeviceAddressIsEqual().


That's kind of a given for *any* function :-)


 However,
 in order to avoid the caller missing argument judgement, I think we
 should also fix().

There are many private functions in libvirt that assume the caller has
sent in sane arguments. If every function checked every argument for
non-NULL, the code would be full of that. I think that's only necessary
for API-level functions, but this function is only a static, used just
within the same file (and only once).

I think that the proper course of action here is to leave it as it is;
note that if it had been fixed at the time the bug was introduced to
virPCIGetVirtualFunctions(), it would have been *much* more difficult to
detect, identify, and fix that bug.

--
libvir-list mailing list
libvir-list@redhat.com
https://www.redhat.com/mailman/listinfo/libvir-list


Re: [libvirt] [PATCH] util: Prevent libvirtd crash from virPCIDeviceAddressIsEqual()

2013-05-02 Thread Alex Jia

On 05/02/2013 11:30 PM, Laine Stump wrote:

On 05/02/2013 02:06 AM, Alex Jia wrote:

On 04/29/2013 02:48 AM, Laine Stump wrote:

On 04/28/2013 06:12 AM, Alex Jia wrote:

GDB backtrace:

Breakpoint 1, virPCIGetVirtualFunctionIndex
(pf_sysfs_device_link=0x7fc04400f470
/sys/bus/pci/devices/:03:00.1, vf_sysfs_device_link=optimized
out, vf_index=vf_index@entry=0x7fc06897b8f4)
  at util/virpci.c:2107
2107if (virPCIDeviceAddressIsEqual(vf_bdf, virt_fns[i])) {
(gdb) p *vf_bdf
$1 = {domain = 0, bus = 3, slot = 16, function = 1}
(gdb) l
2102 virtual_functions),
pf_sysfs_device_link);
2103goto out;
2104}
2105
2106for (i = 0; i   num_virt_fns; i++) {
2107if (virPCIDeviceAddressIsEqual(vf_bdf, virt_fns[i])) {
2108*vf_index = i;
2109ret = 0;
2110break;
2111}
(gdb) p num_virt_fns
$46 = 2
(gdb) p virt_fns[0]
$48 = (virPCIDeviceAddressPtr) 0x0
(gdb) s
virPCIDeviceAddressIsEqual (bdf2=0x0, bdf1=0x7fc04400f330) at
util/virpci.c:1844
1844(bdf1-slot == bdf2-slot)
(gdb) s

Program received signal SIGSEGV, Segmentation fault.

RHBZ: https://bugzilla.redhat.com/show_bug.cgi?id=957416

Signed-off-by: Alex Jiaa...@redhat.com
---
   src/util/virpci.c |3 ++-
   1 files changed, 2 insertions(+), 1 deletions(-)

diff --git a/src/util/virpci.c b/src/util/virpci.c
index 97bba74..dda044c 100644
--- a/src/util/virpci.c
+++ b/src/util/virpci.c
@@ -1897,7 +1897,8 @@ static bool
   virPCIDeviceAddressIsEqual(virPCIDeviceAddressPtr bdf1,
  virPCIDeviceAddressPtr bdf2)
   {
-return ((bdf1-domain == bdf2-domain)
+return (bdf1   bdf2
+(bdf1-domain == bdf2-domain)
   (bdf1-bus == bdf2-bus)
   (bdf1-slot == bdf2-slot)
   (bdf1-function == bdf2-function));

NACK.

This patch only fixes the symptom (not the root cause), and only in the
case of starting a domain with aninterface type='hostdev'. It doesn't
fix the second crash described in the BZ when running virsh
nodedev-dumpxml - the code path of that doesn't ever get to

Yes, I just noticed this, it should be different code path.


virPCIDeviceAddressIsEqual() (but *does* call the function that actually
has the bug).

Yes, another bug.


IMO, the only bug here.



The root cause of these crashes was a typo introduced just before the
release of 1.0.4. I found that problem and pushed the correct patch on
April 9:

http://libvirt.org/git/?p=libvirt.git;a=commit;h=9579b6bc209b46a0f079b21455b598c817925b48


It should be okay if the patch is backported into rhel.


No backport is needed. This bug was only in one release of libvirt, and
that release is not (and almost surely will not be) in any public RHEL
or Fedora release.



(Beyond that, I don't like the idea of ignoring a NULL pointer -
virPCIDeviceAddressIsEqual should always be passed non-NULL pointers,
and its only current caller does guarantee that (except for when it has
a bug). If we want virPCIDeviceAddressIsEqual to do something with NULL
pointers, it should be logging an error and failing, but that would
complicate the interface to the function beyond just returning a
true/false (it would have to be tri-state, and the caller would need to

Yes, the function interface will be more complex and return value should
be tri-state not simple true/false.


Which will make the code in the caller unnecessarily more complex, since
we've already checked for a valid pointer and handled it earlier in that
same function (or to be more exact, a function called by that one -
virPCIGetVirtualFunctions(), which does guarantee that only non-NULL
pointers are placed into the array (when written correctly, as it is now
after the bugfix patch above).



check all three possibilities). I think in this case it's better for the
caller to make sure the pointers it sends are valid.)

Yes, a simple way is the caller makes sure pointers is Non-NULL, maybe,
we need also to add comment The caller should make sure the pointers
it sends are valid into the virPCIDeviceAddressIsEqual().


That's kind of a given for *any* function :-)



However,
in order to avoid the caller missing argument judgement, I think we
should also fix().

There are many private functions in libvirt that assume the caller has
sent in sane arguments. If every function checked every argument for
non-NULL, the code would be full of that. I think that's only necessary
for API-level functions, but this function is only a static, used just
within the same file (and only once).

I think that the proper course of action here is to leave it as it is;
note that if it had been fixed at the time the bug was introduced to
virPCIGetVirtualFunctions(), it would have been *much* more difficult to
detect, identify, and fix that bug.


Laine, got it and thanks for your nice comments :)

Alex


--
libvir-list mailing list
libvir-list@redhat.com

Re: [libvirt] [PATCH] util: Prevent libvirtd crash from virPCIDeviceAddressIsEqual()

2013-04-28 Thread Laine Stump
On 04/28/2013 06:12 AM, Alex Jia wrote:
 GDB backtrace:

 Breakpoint 1, virPCIGetVirtualFunctionIndex 
 (pf_sysfs_device_link=0x7fc04400f470 /sys/bus/pci/devices/:03:00.1, 
 vf_sysfs_device_link=optimized out, vf_index=vf_index@entry=0x7fc06897b8f4)
 at util/virpci.c:2107
 2107if (virPCIDeviceAddressIsEqual(vf_bdf, virt_fns[i])) {
 (gdb) p *vf_bdf
 $1 = {domain = 0, bus = 3, slot = 16, function = 1}
 (gdb) l
 2102 virtual_functions), pf_sysfs_device_link);
 2103goto out;
 2104}
 2105
 2106for (i = 0; i  num_virt_fns; i++) {
 2107if (virPCIDeviceAddressIsEqual(vf_bdf, virt_fns[i])) {
 2108*vf_index = i;
 2109ret = 0;
 2110break;
 2111}
 (gdb) p num_virt_fns
 $46 = 2
 (gdb) p virt_fns[0]
 $48 = (virPCIDeviceAddressPtr) 0x0
 (gdb) s
 virPCIDeviceAddressIsEqual (bdf2=0x0, bdf1=0x7fc04400f330) at 
 util/virpci.c:1844
 1844(bdf1-slot == bdf2-slot) 
 (gdb) s

 Program received signal SIGSEGV, Segmentation fault.

 RHBZ: https://bugzilla.redhat.com/show_bug.cgi?id=957416

 Signed-off-by: Alex Jia a...@redhat.com
 ---
  src/util/virpci.c |3 ++-
  1 files changed, 2 insertions(+), 1 deletions(-)

 diff --git a/src/util/virpci.c b/src/util/virpci.c
 index 97bba74..dda044c 100644
 --- a/src/util/virpci.c
 +++ b/src/util/virpci.c
 @@ -1897,7 +1897,8 @@ static bool
  virPCIDeviceAddressIsEqual(virPCIDeviceAddressPtr bdf1,
 virPCIDeviceAddressPtr bdf2)
  {
 -return ((bdf1-domain == bdf2-domain) 
 +return (bdf1  bdf2 
 +(bdf1-domain == bdf2-domain) 
  (bdf1-bus == bdf2-bus) 
  (bdf1-slot == bdf2-slot) 
  (bdf1-function == bdf2-function));
NACK.

This patch only fixes the symptom (not the root cause), and only in the
case of starting a domain with an interface type='hostdev'. It doesn't
fix the second crash described in the BZ when running virsh
nodedev-dumpxml - the code path of that doesn't ever get to
virPCIDeviceAddressIsEqual() (but *does* call the function that actually
has the bug).

The root cause of these crashes was a typo introduced just before the
release of 1.0.4. I found that problem and pushed the correct patch on
April 9:

http://libvirt.org/git/?p=libvirt.git;a=commit;h=9579b6bc209b46a0f079b21455b598c817925b48

(Beyond that, I don't like the idea of ignoring a NULL pointer -
virPCIDeviceAddressIsEqual should always be passed non-NULL pointers,
and its only current caller does guarantee that (except for when it has
a bug). If we want virPCIDeviceAddressIsEqual to do something with NULL
pointers, it should be logging an error and failing, but that would
complicate the interface to the function beyond just returning a
true/false (it would have to be tri-state, and the caller would need to
check all three possibilities). I think in this case it's better for the
caller to make sure the pointers it sends are valid.)

--
libvir-list mailing list
libvir-list@redhat.com
https://www.redhat.com/mailman/listinfo/libvir-list