aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAndrew G. Morgan <morgan@kernel.org>2021-11-14 21:11:23 -0800
committerAndrew G. Morgan <morgan@kernel.org>2021-11-14 21:11:23 -0800
commit9fa2fe739c2eb4960f0417a1e5f8dcccbfd3d49b (patch)
tree40414693cea899f9ef5dba230c6425f619d5171f
parente9414f540a82b5348a12cfaddff229241564e1f3 (diff)
downloadlibcap-9fa2fe739c2eb4960f0417a1e5f8dcccbfd3d49b.tar.gz
Force libcap.so to initialize itself when run directly.
Not sure where this will go, but libcap.so uses _libcap_initialize() to set itself up at start up. So, run it when invoking libcap.so directly as a binary. Signed-off-by: Andrew G. Morgan <morgan@kernel.org>
-rw-r--r--libcap/Makefile4
-rw-r--r--libcap/cap_alloc.c10
-rw-r--r--libcap/execable.h8
-rw-r--r--libcap/libcap.h3
4 files changed, 22 insertions, 3 deletions
diff --git a/libcap/Makefile b/libcap/Makefile
index 7706063..967820e 100644
--- a/libcap/Makefile
+++ b/libcap/Makefile
@@ -107,8 +107,8 @@ ifeq ($(SHARED),yes)
loader.txt: empty
$(OBJCOPY) --dump-section .interp=$@ $< /dev/null
-cap_magic.o: execable.h execable.c loader.txt
- $(CC) $(CFLAGS) $(CPPFLAGS) -DLIBRARY_VERSION=\"$(LIBTITLE)-$(VERSION).$(MINOR)\" -DSHARED_LOADER=\"$(shell cat loader.txt)\" -c execable.c -o $@
+cap_magic.o: execable.h execable.c loader.txt libcap.h
+ $(CC) $(CFLAGS) $(CPPFLAGS) -DLIBRARY_VERSION=\"$(LIBTITLE)-$(VERSION).$(MINOR)\" -DSHARED_LOADER=\"$(shell cat loader.txt)\" -include ./libcap.h -c execable.c -o $@
$(CAPLIBNAME) $(MAJCAPLIBNAME) $(MINCAPLIBNAME): $(CAPOBJS) $(CAPMAGICOBJ)
$(LD) $(CFLAGS) $(LDFLAGS) -Wl,-soname,$(MAJCAPLIBNAME) -o $(MINCAPLIBNAME) $^ $(MAGIC)
diff --git a/libcap/cap_alloc.c b/libcap/cap_alloc.c
index 6a674f4..600b7cd 100644
--- a/libcap/cap_alloc.c
+++ b/libcap/cap_alloc.c
@@ -8,17 +8,25 @@
#include "libcap.h"
/*
+ * Make start up atomic.
+ */
+static __u8 __libcap_mutex;
+
+/*
* These get set via the pre-main() executed constructor function below it.
*/
static cap_value_t _cap_max_bits;
-__attribute__((constructor (300))) static void _initialize_libcap(void)
+__attribute__((constructor (300))) void _libcap_initialize()
{
+ _cap_mu_lock(&__libcap_mutex);
if (_cap_max_bits) {
+ _cap_mu_unlock(&__libcap_mutex);
return;
}
cap_set_syscall(NULL, NULL);
_binary_search(_cap_max_bits, cap_get_bound, 0, __CAP_MAXBITS, __CAP_BITS);
+ _cap_mu_unlock(&__libcap_mutex);
}
cap_value_t cap_max_bits(void)
diff --git a/libcap/execable.h b/libcap/execable.h
index 7cf9b34..fee17b4 100644
--- a/libcap/execable.h
+++ b/libcap/execable.h
@@ -81,6 +81,13 @@ static void __execable_parse_args(int *argc_p, char ***argv_p)
#endif /* def some x86 */
/*
+ * Permit the compiler to override this one.
+ */
+#ifndef EXECABLE_INITIALIZE
+#define EXECABLE_INITIALIZE do { } while(0)
+#endif /* ndef EXECABLE_INITIALIZE */
+
+/*
* Note, to avoid any runtime confusion, SO_MAIN is a void static
* function.
*/
@@ -93,6 +100,7 @@ void __so_start(void) \
int argc; \
char **argv; \
__execable_parse_args(&argc, &argv); \
+ EXECABLE_INITIALIZE; \
__execable_main(argc, argv); \
if (argc != 0) { \
free(argv[0]); \
diff --git a/libcap/libcap.h b/libcap/libcap.h
index a22f69a..f4a72fe 100644
--- a/libcap/libcap.h
+++ b/libcap/libcap.h
@@ -202,6 +202,9 @@ struct _cap_struct {
#endif /* DEBUG */
extern char *_libcap_strdup(const char *text);
+extern void _libcap_initialize(void);
+
+#define EXECABLE_INITIALIZE _libcap_initialize()
/*
* These are semi-public prototypes, they will only be defined in