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 #define _IT_IFUNC_H
//! ifunc helpers //! 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_NAME(name, ver) _impl__ ## name ## __ ## ver
#define IFUNC_IMPL(name, ver) __attribute__((copy(name))) IFUNC_NAME(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_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 */ #endif /* _IT_IFUNC_H */

@ -25,7 +25,8 @@ __attribute__((gnu_inline))
static inline static inline
int _has_memfd_secret_raw() 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 failure to create new fd was caused by `ENOSYS`, it is not available.
if(fd < 0 && errno == ENOSYS) if(fd < 0 && errno == ENOSYS)
@ -52,9 +53,12 @@ int _has_memfd_secret() {
return ok; return ok;
} }
int IFUNC_DEF(memfd_secret, (unsigned int));
/// Set as IFUNC target for systems with `memfd_secret()` support enabled. /// 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.) __attribute__((visibility("hidden")))
int memfd_secret_$enabled(unsigned int flags) int IFUNC_IMPL(memfd_secret, $enabled) (unsigned int flags)
{ {
return _memfd_secret_raw(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. /// The call is forwarded to `memfd_create()` instead.
__attribute__((visibility("hidden"))) __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. 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`. //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); 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: 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. //TODO: Use `ifunc.h`'s macros for defining the ifunc instead of manually, it de-clutters shit and removed repetition.

Loading…
Cancel
Save