diff options
author | Andrew G. Morgan <morgan@kernel.org> | 2021-11-14 21:11:23 -0800 |
---|---|---|
committer | Andrew G. Morgan <morgan@kernel.org> | 2021-11-14 21:11:23 -0800 |
commit | 9fa2fe739c2eb4960f0417a1e5f8dcccbfd3d49b (patch) | |
tree | 40414693cea899f9ef5dba230c6425f619d5171f | |
parent | e9414f540a82b5348a12cfaddff229241564e1f3 (diff) | |
download | libcap-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/Makefile | 4 | ||||
-rw-r--r-- | libcap/cap_alloc.c | 10 | ||||
-rw-r--r-- | libcap/execable.h | 8 | ||||
-rw-r--r-- | libcap/libcap.h | 3 |
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 |