Added IFUNC resolver for `memfd_secret()`.

Fortune for memfd_secret-shim's current commit: Curse − 凶
master
Avril 7 months ago
parent b8c2a2c3d6
commit f1c89d50e1
Signed by: flanchan
GPG Key ID: 284488987C31F630

@ -2,10 +2,24 @@
#define _IT_IFUNC_H
//! ifunc helpers
#if !IFUNC_PREFIX
#define IFUNC_PREFIX _ifun__
#endif
#define _IFUNC_STR_(X) #X
#define _IFUNC_STR(X) _IFUNC_STR_(X)
#define _IFUNC_PREFIX_S _IFUNC_STR(IFUNC_PREFIX)
#define _IFUNC_PASTE_(X,Y) X##Y
#define _IFUNC_PASTE(X,Y) _IFUNC_PASTE_(X,Y)
#define _IFUNC_PREFIX(X) _IFUNC_PASTE(IFUNC_PREFIX, X)
#define IFUNC_NAME(name, ver) _impl__ ## name ## __ ## ver
#define IFUNC_IMPL(name, ver) __attribute__((copy(name))) IFUNC_NAME(name, ver)
#define IFUNC_RESOLVER_A(attr, name) __attribute__((returns_nonnull)) (* __attribute__(attr) _ifun__ ## name (void)) // When the ifunc resolver wants to return a function pointer that has attributes on it, the attribute inner list (e.g. `(returns_nonnull, const, nonnull)') can be provided as the first argument
#define IFUNC_RESOLVER_A(attr, name) __attribute__((returns_nonnull)) (* __attribute__(attr) _IFUNC_PREFIX(name) /*_ifun__ ## name*/ (void)) // When the ifunc resolver wants to return a function pointer that has attributes on it, the attribute inner list (e.g. `(returns_nonnull, const, nonnull)') can be provided as the first argument
#define IFUNC_RESOLVER(name) IFUNC_RESOLVER_A((copy(name)), name)
#define IFUNC_DEF(name, params) name params __attribute__((__ifunc__("_ifun__" #name)))
#define IFUNC_DEF(name, params) name params __attribute__((__ifunc__(_IFUNC_PREFIX_S #name)))
#endif /* _IT_IFUNC_H */

@ -25,7 +25,8 @@ __attribute__((gnu_inline))
static inline
int _has_memfd_secret_raw()
{
int fd = _memfd_secret(FD_CLOEXEC);
// Attempt syscall
int fd = _memfd_secret_raw(FD_CLOEXEC);
// If failure to create new fd was caused by `ENOSYS`, it is not available.
if(fd < 0 && errno == ENOSYS)
@ -52,9 +53,12 @@ int _has_memfd_secret() {
return ok;
}
int IFUNC_DEF(memfd_secret, (unsigned int));
/// Set as IFUNC target for systems with `memfd_secret()` support enabled.
__attribute__((visibility("hidden"))) //XXX: `hidden` is the "can only be accessed outside .so from returned internal function pointer", right? and `internal` is "can *never* be accessed outside of .so"? (TODO: Check. Idk if this is the other way around.)
int memfd_secret_$enabled(unsigned int flags)
__attribute__((visibility("hidden")))
int IFUNC_IMPL(memfd_secret, $enabled) (unsigned int flags)
{
return _memfd_secret_raw(flags);
}
@ -63,7 +67,7 @@ int memfd_secret_$enabled(unsigned int flags)
///
/// The call is forwarded to `memfd_create()` instead.
__attribute__((visibility("hidden")))
int memfd_secret_$disabled(unsigned int flags)
int IFUNC_IMPL(memfd_secret, $disabled) (unsigned int flags)
{
if( FD_CLOEXEC != MEMFD_CLOEXEC ) { // NOTE: This is a constant expression, and this code will be removed if they are equal.
//TODO: Translate mask `flags`, from `FD_CLOEXEC` (if it is set) -> `MEMFD_CLOEXEC`.
@ -71,5 +75,12 @@ int memfd_secret_$disabled(unsigned int flags)
return memfd_create("memfd_secret@?", flags);
}
int IFUNC_RESOLVER(memfd_secret) (unsigned int flags)
{
return _has_memfd_secret()
? &IFUNC_NAME(memfd_secret, $enabled)
: &IFUNC_NAME(memfd_secret, $disabled);
}
//TODO: IFUNC resolver for `memfd_secret()` (Above two targets^^)
//TODO: Use `ifunc.h`'s macros for defining the ifunc instead of manually, it de-clutters shit and removed repetition.

Loading…
Cancel
Save