grub-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [PATCH] fix SigSegV and hang with grub-emu-usb


From: Vladimir 'phcoder' Serbinenko
Subject: Re: [PATCH] fix SigSegV and hang with grub-emu-usb
Date: Fri, 19 Jun 2009 17:54:50 +0200



On Fri, Jun 19, 2009 at 5:20 PM, Pavel Roskin <address@hidden> wrote:
On Fri, 2009-06-19 at 16:58 +0200, Vladimir 'phcoder' Serbinenko wrote:
> Hello when testing grub-emu with USB support I stumbled across  several problems
> 1) compile time warning of undefined grub_usb_libinit
> 2) When launched under normal user it crashed
> 3) When launched as superuser it hanged on ls
> Here is the fix. Formatting omitted for readability

It's not clear which changes are responsible for fixing which problems.
Please post separate patches if you want a meaningful review.
I thought it was clear. Here is an explanation hunk by hunk:
diff --git a/disk/scsi.c b/disk/scsi.c
index 046dcb8..312d58a 100644
--- a/disk/scsi.c
+++ b/disk/scsi.c
@@ -246,8 +246,9 @@ grub_scsi_open (const char *name, grub_disk_t disk)
 
   for (p = grub_scsi_dev_list; p; p = p->next)
     {
-      if (! p->open (name, scsi))
-    {
+      if (p->open (name, scsi))
+    continue;
+
       disk->id = (unsigned long) "scsi"; /* XXX */
       disk->data = "">       scsi->dev = p;

This is purely stilistic to avoid unnecessarily long if

@@ -266,7 +267,7 @@ grub_scsi_open (const char *name, grub_disk_t disk)
         {
           grub_free (scsi);
           grub_dprintf ("scsi", "inquiry failed\n");
-          return grub_errno;
+      return err;
         }
 
       grub_dprintf ("scsi", "inquiry: devtype=0x%02x removable=%d\n",
Error wasn't propagated which caused double closing which resulted in sigsegv. With another hunk (adding grub-error) this hunk wouldn't be necessary but I consider construction
err = ....;
if (err)
  return err;
more logical than
err = ....;
if (err)
  return grub_errno;

@@ -306,7 +307,6 @@ grub_scsi_open (const char *name, grub_disk_t disk)
 
       return GRUB_ERR_NONE;
     }
-    }
 
   grub_free (scsi);
 Counterpart of first hunk
diff --git a/disk/usbms.c b/disk/usbms.c
index 3c7ebaf..f67f918 100644
--- a/disk/usbms.c
+++ b/disk/usbms.c
@@ -226,7 +226,7 @@ grub_usbms_transfer (struct grub_scsi *scsi, grub_size_t cmdsize, char *cmd,
 
  retry:
   if (retrycnt == 0)
-    return err;
+    return grub_error (GRUB_ERR_IO, "USB Mass Storage stalled");
 
   /* Setup the request.  */
   grub_memset (&cbw, 0, sizeof (cbw));

when retry numbers failed returned error was ERR_NONE even if nothing was read
@@ -246,6 +246,7 @@ grub_usbms_transfer (struct grub_scsi *scsi, grub_size_t cmdsize, char *cmd,
       if (err == GRUB_USB_ERR_STALL)
     {
       grub_usb_clear_halt (dev->dev, dev->out->endp_addr);
+      retrycnt--;
       goto retry;
     }
       return grub_error (GRUB_ERR_IO, "USB Mass Storage request failed");;
retrycnt wasn't decreased which caused grub2 to retry infinitely hence a hang.
diff --git a/include/grub/usb.h b/include/grub/usb.h
index 8dd3b6e..d6d9a3e 100644
--- a/include/grub/usb.h
+++ b/include/grub/usb.h
@@ -204,4 +204,9 @@ grub_usb_get_config_interface (struct grub_usb_desc_config *config)
   return interf;
 }
 
+#ifdef GRUB_UTIL
+grub_err_t grub_libusb_init (void);
+grub_err_t grub_libusb_fini (void);
+#endif
+
 #endif /* GRUB_USB_H */
diff --git a/util/grub-emu.c b/util/grub-emu.c
index c133dbe..2621d18 100644
--- a/util/grub-emu.c
+++ b/util/grub-emu.c
@@ -39,6 +39,10 @@
 
 #include <grub_emu_init.h>
 
+#if HAVE_USB_H
+#include <grub/usb.h>
+#endif
+
 /* Used for going back to the main function.  */
 jmp_buf main_env;
 
@@ -223,6 +227,10 @@ main (int argc, char *argv[])
   if (setjmp (main_env) == 0)
     grub_main ();
 
+#if HAVE_USB_H
+  grub_libusb_fini ();
+#endif
+
   grub_fini_all ();
 
   grub_machine_fini ();
Previous hunks just fixed warnings
diff --git a/util/usb.c b/util/usb.c
index e1d8c71..4ca1c10 100644
--- a/util/usb.c
+++ b/util/usb.c
@@ -51,6 +51,7 @@ grub_libusb_devices (void)
       for (usbdev = bus->devices; usbdev; usbdev = usbdev->next)
     {
       struct usb_device_descriptor *desc = &usbdev->descriptor;
+      grub_err_t err;
 
       if (! desc->bcdUSB)
         continue;
@@ -62,7 +63,9 @@ grub_libusb_devices (void)
       dev->data = ""> 
       /* Fill in all descriptors.  */
-      grub_usb_device_initialize (dev);
+      err = grub_usb_device_initialize (dev);
+      if (err)
+        continue;
 
       /* Register the device.  */
       grub_usb_devs[last++] = dev;
When device couldn'r be initialized (e.g. because of privilege problem) it was still added to list. Subsequent access created sigsegv

Regarding the compile warning fix, I would try to make
grub_libusb_init() and grub_libusb_fini() appear in grub_emu_init.h
rather than declare them elsewhere.
I was inspired by previous example of disk subsystems:
#ifdef GRUB_UTIL
void grub_raid_init (void);
void grub_raid_fini (void);
void grub_lvm_init (void);
void grub_lvm_fini (void);
#endif
file: include/grub/disk.h

--
Regards,
Pavel Roskin


_______________________________________________
Grub-devel mailing list
address@hidden
http://lists.gnu.org/mailman/listinfo/grub-devel



--
Regards
Vladimir 'phcoder' Serbinenko

reply via email to

[Prev in Thread] Current Thread [Next in Thread]