Message ID | 20230814132025.45364-9-cgzones@googlemail.com (mailing list archive) |
---|---|
State | Accepted |
Commit | cb8289c2b237 |
Delegated to: | Petr Lautrbach |
Headers | show |
Series | libselinux: rework selabel_file(5) database | expand |
On Mon, Aug 14, 2023 at 9:41 AM Christian Göttsche <cgzones@googlemail.com> wrote: > > 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@googlemail.com> > --- > 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 20d79312..ac656257 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 9a9bafb0..a1c5b0cc 100644 > --- a/libselinux/src/matchpathcon.c > +++ b/libselinux/src/matchpathcon.c > @@ -95,8 +95,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..9f1aff40 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 > -1 / size) { Should be "(size_t)-1" > + errno = ENOMEM; > + return 0; Should be "return NULL;" Thanks, Jim > + } > + > + 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.40.1 >
diff --git a/libselinux/src/Makefile b/libselinux/src/Makefile index 20d79312..ac656257 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 9a9bafb0..a1c5b0cc 100644 --- a/libselinux/src/matchpathcon.c +++ b/libselinux/src/matchpathcon.c @@ -95,8 +95,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..9f1aff40 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 > -1 / size) { + errno = ENOMEM; + return 0; + } + + 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;
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@googlemail.com> --- 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(-)