[PATCH v3 2/2] libselinux: introduce reallocarray(3)

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

 



Introduce reallocarray(3), a realloc(3) wrapper incorporating a
multiplication overflow check.

Add private implementation in case the function is not provided by the
standard C library.

Use in appropriate locations.

Signed-off-by: Christian Göttsche <cgzones@xxxxxxxxxxxxxx>
---
v3:
  - use SIZE_MAX and NULL instead of -1 and 0
  - fix indentation
  - drop RFC and split from original patch set
---
 libselinux/src/Makefile             |  6 ++++++
 libselinux/src/get_context_list.c   |  2 +-
 libselinux/src/matchpathcon.c       |  4 ++--
 libselinux/src/selinux_internal.c   | 16 ++++++++++++++++
 libselinux/src/selinux_internal.h   |  4 ++++
 libselinux/src/selinux_restorecon.c |  3 +--
 6 files changed, 30 insertions(+), 5 deletions(-)

diff --git a/libselinux/src/Makefile b/libselinux/src/Makefile
index cf830046..7aadb822 100644
--- a/libselinux/src/Makefile
+++ b/libselinux/src/Makefile
@@ -108,6 +108,12 @@ ifeq (yes,$(shell printf '${H}include <string.h>\nint main(void){char*d,*s;strlc
 override CFLAGS += -DHAVE_STRLCPY
 endif
 
+# check for reallocarray(3) availability
+H := \#
+ifeq (yes,$(shell printf '${H}include <stdlib.h>\nint main(void){reallocarray(NULL, 0, 0);return 0;}' | $(CC) -x c -o /dev/null - >/dev/null 2>&1 && echo yes))
+override CFLAGS += -DHAVE_REALLOCARRAY
+endif
+
 SWIG_CFLAGS += -Wno-error -Wno-unused-variable -Wno-unused-but-set-variable -Wno-unused-parameter \
 		-Wno-shadow -Wno-uninitialized -Wno-missing-prototypes -Wno-missing-declarations \
 		-Wno-deprecated-declarations
diff --git a/libselinux/src/get_context_list.c b/libselinux/src/get_context_list.c
index 0342823c..9dafa519 100644
--- a/libselinux/src/get_context_list.c
+++ b/libselinux/src/get_context_list.c
@@ -272,7 +272,7 @@ static int get_context_user(FILE * fp,
 			continue;
 		}
 		if (security_check_context(usercon_str2) == 0) {
-			new_reachable = realloc(*reachable, (*nreachable + 2) * sizeof(char *));
+			new_reachable = reallocarray(*reachable, *nreachable + 2, sizeof(char *));
 			if (!new_reachable) {
 				context_free(usercon);
 				rc = -1;
diff --git a/libselinux/src/matchpathcon.c b/libselinux/src/matchpathcon.c
index b98849d9..e44734c3 100644
--- a/libselinux/src/matchpathcon.c
+++ b/libselinux/src/matchpathcon.c
@@ -96,8 +96,8 @@ static int add_array_elt(char *con)
 	if (con_array_size) {
 		while (con_array_used >= con_array_size) {
 			con_array_size *= 2;
-			tmp = (char **)realloc(con_array, sizeof(char*) *
-						     con_array_size);
+			tmp = (char **)reallocarray(con_array, con_array_size,
+						    sizeof(char*));
 			if (!tmp) {
 				free_array_elts();
 				return -1;
diff --git a/libselinux/src/selinux_internal.c b/libselinux/src/selinux_internal.c
index c2be7c0a..678bd99c 100644
--- a/libselinux/src/selinux_internal.c
+++ b/libselinux/src/selinux_internal.c
@@ -1,5 +1,7 @@
 #include "selinux_internal.h"
 
+#include <errno.h>
+#include <stdlib.h>
 #include <string.h>
 
 
@@ -16,3 +18,17 @@ size_t strlcpy(char *dest, const char *src, size_t size)
 	return ret;
 }
 #endif /* HAVE_STRLCPY */
+
+#ifndef HAVE_REALLOCARRAY
+void *reallocarray(void *ptr, size_t nmemb, size_t size)
+{
+	
+	if (size && nmemb > SIZE_MAX / size) {
+		errno = ENOMEM;
+		return NULL;
+	}
+
+	return realloc(ptr, nmemb * size);
+
+}
+#endif /* HAVE_REALLOCARRAY */
diff --git a/libselinux/src/selinux_internal.h b/libselinux/src/selinux_internal.h
index 06f2c038..af69ff04 100644
--- a/libselinux/src/selinux_internal.h
+++ b/libselinux/src/selinux_internal.h
@@ -98,4 +98,8 @@ extern int has_selinux_config ;
 size_t strlcpy(char *dest, const char *src, size_t size);
 #endif
 
+#ifndef HAVE_REALLOCARRAY
+void *reallocarray(void *ptr, size_t nmemb, size_t size);
+#endif
+
 #endif /* SELINUX_INTERNAL_H_ */
diff --git a/libselinux/src/selinux_restorecon.c b/libselinux/src/selinux_restorecon.c
index 7ef2d45d..38f10f1c 100644
--- a/libselinux/src/selinux_restorecon.c
+++ b/libselinux/src/selinux_restorecon.c
@@ -175,8 +175,7 @@ static int add_exclude(const char *directory, bool who)
 		return -1;
 	}
 
-	tmp_list = realloc(exclude_lst,
-			   sizeof(struct edir) * (exclude_count + 1));
+	tmp_list = reallocarray(exclude_lst, exclude_count + 1, sizeof(struct edir));
 	if (!tmp_list)
 		goto oom;
 
-- 
2.42.0




[Index of Archives]     [Selinux Refpolicy]     [Linux SGX]     [Fedora Users]     [Fedora Desktop]     [Yosemite Photos]     [Yosemite Camping]     [Yosemite Campsites]     [KDE Users]     [Gnome Users]

  Powered by Linux