summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndrew G. Morgan <morgan@kernel.org>2021-08-28 09:43:51 -0700
committerAndrew G. Morgan <morgan@kernel.org>2021-08-28 09:43:51 -0700
commit6c38eb78d96a60a9503dc5c89ade67b65778fed9 (patch)
treeb8965a83cc5ddfff0ba32e1175cf5eb78596e382
parent43365cf01c64b530e7a3d62214247e1aa042414d (diff)
downloadlibcap2-6c38eb78d96a60a9503dc5c89ade67b65778fed9.tar.gz
Avoid the build server failure.
I figured out that the key ingredient to reproducing this issue was: make COPTS="-D_FORTIFY_SOURCE=2 -O1 -g" clean test Signed-off-by: Andrew G. Morgan <morgan@kernel.org>
-rw-r--r--Makefile1
-rw-r--r--libcap/cap_alloc.c27
2 files changed, 19 insertions, 9 deletions
diff --git a/Makefile b/Makefile
index d26af01..1c195dd 100644
--- a/Makefile
+++ b/Makefile
@@ -67,6 +67,7 @@ endif
distcheck:
./distcheck.sh
+ $(MAKE) DYNAMIC=no COPTS="-D_FORTIFY_SOURCE=2 -O1 -g" clean test
$(MAKE) DYNAMIC=yes clean all test sudotest
$(MAKE) DYNAMIC=no COPTS="-O2 -std=c89" clean all test sudotest
$(MAKE) PAM_CAP=no CC=/usr/local/musl/bin/musl-gcc clean all test sudotest
diff --git a/libcap/cap_alloc.c b/libcap/cap_alloc.c
index ba2dd11..4dabe27 100644
--- a/libcap/cap_alloc.c
+++ b/libcap/cap_alloc.c
@@ -34,7 +34,6 @@ struct _cap_alloc_s {
__u32 magic;
__u32 size;
union {
- char string_start; /* enough memory is allocated for string */
struct _cap_struct set;
struct cap_iab_s iab;
struct cap_launch_s launcher;
@@ -90,7 +89,8 @@ cap_t cap_init(void)
*/
char *_libcap_strdup(const char *old)
{
- struct _cap_alloc_s *raw_data;
+ struct _cap_alloc_s *header;
+ char *raw_data;
size_t len;
if (old == NULL) {
@@ -106,16 +106,19 @@ char *_libcap_strdup(const char *old)
errno = EINVAL;
return NULL;
}
+
raw_data = calloc(1, len);
if (raw_data == NULL) {
errno = ENOMEM;
return NULL;
}
- raw_data->magic = CAP_S_MAGIC;
- raw_data->size = (__u32) len;
- strcpy(&raw_data->u.string_start, old);
+ header = (void *) raw_data;
+ header->magic = CAP_S_MAGIC;
+ header->size = (__u32) len;
- return &raw_data->u.string_start;
+ raw_data += 2*sizeof(__u32);
+ strcpy(raw_data, old);
+ return raw_data;
}
/*
@@ -221,7 +224,8 @@ int cap_free(void *data_p)
return -1;
}
- struct _cap_alloc_s *data = (void *) (-2 + (__u32 *) data_p);
+ void *base = (void *) (-2 + (__u32 *) data_p);
+ struct _cap_alloc_s *data = base;
switch (data->magic) {
case CAP_T_MAGIC:
case CAP_IAB_MAGIC:
@@ -243,9 +247,14 @@ int cap_free(void *data_p)
return -1;
}
- memset(data, 0, data->size);
- free(data);
+ /*
+ * operate here with respect to base, to avoid tangling with the
+ * automated buffer overflow detection.
+ */
+ memset(base, 0, data->size);
+ free(base);
data_p = NULL;
data = NULL;
+ base = NULL;
return 0;
}