Recognize that NULL is an invalid cap_t and cap_iab_t.

This was a regresssion introduced in libcap-2.55. Fixed in libcap-2.59.
Added a cap_launch NULL test too. Comparing against NULL would cause a
SIGSEGV against these library revisions.

Signed-off-by: Andrew G. Morgan <morgan@kernel.org>
diff --git a/doc/cap_clear.3 b/doc/cap_clear.3
index 6d06049..eb8f4ec 100644
--- a/doc/cap_clear.3
+++ b/doc/cap_clear.3
@@ -88,16 +88,18 @@
 compares two full capability sets and, in the spirit of
 .BR memcmp (),
 returns zero if the two capability sets are identical. A positive
-return value,
-.BR status ,
-indicates there is a difference between them. The
-returned value carries further information about which of three sets,
-.I cap_flag_t
-.BR flag ,
-differ. Specifically, the macro
+return
+.I value
+indicates there is a difference between them. The returned
+.I value
+carries further information about the
+.BI "cap_flag_t " flag
+differences. Specifically, the macro
 .B CAP_DIFFERS
-.RI ( status ", " flag )
-evaluates to non-zero if the returned status differs in its
+.RI ( value ", " flag )
+evaluates to non-zero if the returned
+.I value
+differs in its
 .I flag
 components.
 .SH "RETURN VALUE"
diff --git a/libcap/cap_proc.c b/libcap/cap_proc.c
index eac86cb..8633824 100644
--- a/libcap/cap_proc.c
+++ b/libcap/cap_proc.c
@@ -998,6 +998,11 @@
     int ps[2];
     pid_t child;
 
+    if (!good_cap_launch_t(attr)) {
+	errno = EINVAL;
+	return -1;
+    }
+
     /* The launch must have a purpose */
     if (attr->custom_setup_fn == NULL &&
 	(attr->arg0 == NULL || attr->argv == NULL)) {
diff --git a/libcap/cap_test.c b/libcap/cap_test.c
index 729efed..2c068aa 100644
--- a/libcap/cap_test.c
+++ b/libcap/cap_test.c
@@ -49,6 +49,14 @@
 	printf("test_flags failed to allocate a set\n");
 	return -1;
     }
+    if (cap_compare(c, NULL) != -1) {
+	printf("compare to NULL should give invalid\n");
+	return -1;
+    }
+    if (cap_compare(NULL, c) != -1) {
+	printf("compare with NULL should give invalid\n");
+	return -1;
+    }
 
     for (v = 0; v < __CAP_MAXBITS; v += 3) {
 	if (cap_set_flag(c, CAP_INHERITABLE, 1, &v, CAP_SET)) {
diff --git a/libcap/libcap.h b/libcap/libcap.h
index ffc8c8a..bd80342 100644
--- a/libcap/libcap.h
+++ b/libcap/libcap.h
@@ -133,9 +133,10 @@
 /* launcher magic for cap_free */
 #define CAP_LAUNCH_MAGIC 0xCA91A
 
-#define magic_of(x)        (*(-2 + (const __u32 *) x))
-#define good_cap_t(x)      (CAP_T_MAGIC   == magic_of(x))
-#define good_cap_iab_t(x)  (CAP_IAB_MAGIC == magic_of(x))
+#define magic_of(x)           ((x) ? *(-2 + (const __u32 *) x) : 0)
+#define good_cap_t(x)         (CAP_T_MAGIC   == magic_of(x))
+#define good_cap_iab_t(x)     (CAP_IAB_MAGIC == magic_of(x))
+#define good_cap_launch_t(x)  (CAP_LAUNCH_MAGIC == magic_of(x))
 
 /*
  * kernel API cap set abstraction
diff --git a/tests/libcap_launch_test.c b/tests/libcap_launch_test.c
index 343e389..12d123c 100644
--- a/tests/libcap_launch_test.c
+++ b/tests/libcap_launch_test.c
@@ -127,8 +127,12 @@
 
     int success = 1, i;
     for (i=0; vs[i].pass_on != NO_MORE; i++) {
-	cap_launch_t attr;
+	cap_launch_t attr = NULL;
 	const struct test_case_s *v = &vs[i];
+	if (cap_launch(attr, NULL) != -1) {
+	    perror("NULL launch didn't fail");
+	    exit(1);
+	}
 	printf("[%d] test should %s\n", i,
 	       v->result || v->launch_abort ? "generate error" : "work");
 	if (v->args[0] != NULL) {