Prevent null pointer deref in DirectVolume

There's a possibility that if something were messed up a call to
NetlinkEvent::findParam could return a NULL. Passing NULL as the
argument into atoi() would cause a null pointer dereference.

Change-Id: Ib071afbbe2adc341108c245ffa596cc8730bd8fd
diff --git a/DirectVolume.cpp b/DirectVolume.cpp
index fd99f0c..6af4ccb 100644
--- a/DirectVolume.cpp
+++ b/DirectVolume.cpp
@@ -124,8 +124,11 @@
 }
 
 void DirectVolume::handleDiskAdded(const char *devpath, NetlinkEvent *evt) {
-    mDiskMajor = atoi(evt->findParam("MAJOR"));
-    mDiskMinor = atoi(evt->findParam("MINOR"));
+    int major, minor;
+    if (!getMajorMinorNum(evt, &major, &minor)) {
+        LOGE("Could not determine major:minor in handleDiskAdded");
+        return;
+    }
 
     const char *tmp = evt->findParam("NPARTS");
     if (tmp) {
@@ -164,8 +167,11 @@
 }
 
 void DirectVolume::handlePartitionAdded(const char *devpath, NetlinkEvent *evt) {
-    int major = atoi(evt->findParam("MAJOR"));
-    int minor = atoi(evt->findParam("MINOR"));
+    int major, minor;
+    if (!getMajorMinorNum(evt, &major, &minor)) {
+        LOGE("Could not determine major:minor in handlePartitionAdded");
+        return;
+    }
 
     int part_num;
 
@@ -207,8 +213,11 @@
 }
 
 void DirectVolume::handleDiskChanged(const char *devpath, NetlinkEvent *evt) {
-    int major = atoi(evt->findParam("MAJOR"));
-    int minor = atoi(evt->findParam("MINOR"));
+    int major, minor;
+    if (!getMajorMinorNum(evt, &major, &minor)) {
+        LOGE("Could not determine major:minor in handleDiskChanged");
+        return;
+    }
 
     if ((major != mDiskMajor) || (minor != mDiskMinor)) {
         return;
@@ -240,14 +249,22 @@
 }
 
 void DirectVolume::handlePartitionChanged(const char *devpath, NetlinkEvent *evt) {
-    int major = atoi(evt->findParam("MAJOR"));
-    int minor = atoi(evt->findParam("MINOR"));
+    int major, minor;
+    if (!getMajorMinorNum(evt, &major, &minor)) {
+        LOGE("Could not determine major:minor in handlePartitionChanged");
+        return;
+    }
+
     LOGD("Volume %s %s partition %d:%d changed\n", getLabel(), getMountpoint(), major, minor);
 }
 
 void DirectVolume::handleDiskRemoved(const char *devpath, NetlinkEvent *evt) {
-    int major = atoi(evt->findParam("MAJOR"));
-    int minor = atoi(evt->findParam("MINOR"));
+    int major, minor;
+    if (!getMajorMinorNum(evt, &major, &minor)) {
+        LOGE("Could not determine major:minor in handleDiskRemoved");
+        return;
+    }
+
     char msg[255];
 
     LOGD("Volume %s %s disk %d:%d removed\n", getLabel(), getMountpoint(), major, minor);
@@ -259,8 +276,12 @@
 }
 
 void DirectVolume::handlePartitionRemoved(const char *devpath, NetlinkEvent *evt) {
-    int major = atoi(evt->findParam("MAJOR"));
-    int minor = atoi(evt->findParam("MINOR"));
+    int major, minor;
+    if (!getMajorMinorNum(evt, &major, &minor)) {
+        LOGE("Could not determine major:minor in handlePartitionRemoved");
+        return;
+    }
+
     char msg[255];
 
     LOGD("Volume %s %s partition %d:%d removed\n", getLabel(), getMountpoint(), major, minor);
diff --git a/DirectVolume.h b/DirectVolume.h
index 2a78236..3c95b4b 100644
--- a/DirectVolume.h
+++ b/DirectVolume.h
@@ -18,6 +18,7 @@
 #define _DEVICEVOLUME_H
 
 #include <utils/List.h>
+#include <sysutils/NetlinkEvent.h>
 
 #include "Volume.h"
 
@@ -25,6 +26,20 @@
 
 typedef android::List<char *> PathCollection;
 
+inline bool getMajorMinorNum(NetlinkEvent *evt, int *major, int *minor) {
+    const char *major_str = evt->findParam("MAJOR");
+    const char *minor_str = evt->findParam("MINOR");
+
+    if (major_str == NULL || minor_str == NULL) {
+        return false;
+    }
+
+    *major = atoi(major_str);
+    *minor = atoi(minor_str);
+
+    return true;
+}
+
 class DirectVolume : public Volume {
 public:
     static const int MAX_PARTITIONS = 4;