dma-debug: Fix check_unmap null pointer dereference
Kyle McMartin [Thu, 20 Aug 2009 01:17:08 +0000 (21:17 -0400)]
While it's debatable whether or not a NULL device argument to
the DMA API functions is valid... since it certainly isn't
valid on devices with an IOMMU... dma-debug really shouldn't be
dereferencing null pointers either.

Guard against that in err_printk and the driver_filter
functions. A Fedora rawhide user was seeing this in one of the
dvb drivers resulting in an oops on boot.

[ A patch has been sent for testing to the driver, but I feel
  the dma debugging support should be fixed as well. (There's
  still a pile of legacy garbage in the kernel passing null
  pointers to dma_{alloc,free}_*. :( ]

Signed-off-by: Kyle McMartin <kyle@redhat.com>
Cc: mchehab@infradead.org
Cc: Joerg Roedel <joerg.roedel@amd.com>
LKML-Reference: <20090820011708.GP25206@bombadil.infradead.org>
Signed-off-by: Ingo Molnar <mingo@elte.hu>

lib/dma-debug.c

index 65b0d99..58a9f9f 100644 (file)
@@ -156,9 +156,13 @@ static bool driver_filter(struct device *dev)
                return true;
 
        /* driver filter on and initialized */
-       if (current_driver && dev->driver == current_driver)
+       if (current_driver && dev && dev->driver == current_driver)
                return true;
 
+       /* driver filter on, but we can't filter on a NULL device... */
+       if (!dev)
+               return false;
+
        if (current_driver || !current_driver_name[0])
                return false;
 
@@ -183,17 +187,17 @@ static bool driver_filter(struct device *dev)
        return ret;
 }
 
-#define err_printk(dev, entry, format, arg...) do {            \
-               error_count += 1;                               \
-               if (driver_filter(dev) &&                       \
-                   (show_all_errors || show_num_errors > 0)) { \
-                       WARN(1, "%s %s: " format,               \
-                            dev_driver_string(dev),            \
-                            dev_name(dev) , ## arg);           \
-                       dump_entry_trace(entry);                \
-               }                                               \
-               if (!show_all_errors && show_num_errors > 0)    \
-                       show_num_errors -= 1;                   \
+#define err_printk(dev, entry, format, arg...) do {                    \
+               error_count += 1;                                       \
+               if (driver_filter(dev) &&                               \
+                   (show_all_errors || show_num_errors > 0)) {         \
+                       WARN(1, "%s %s: " format,                       \
+                            dev ? dev_driver_string(dev) : "NULL",     \
+                            dev ? dev_name(dev) : "NULL", ## arg);     \
+                       dump_entry_trace(entry);                        \
+               }                                                       \
+               if (!show_all_errors && show_num_errors > 0)            \
+                       show_num_errors -= 1;                           \
        } while (0);
 
 /*