From 308230d4fcb90822b81578624504d74ad2fbeab9 Mon Sep 17 00:00:00 2001 From: Robin Hack Date: Fri, 23 Jan 2015 15:28:37 +0100 Subject: [PATCH] uwrap: Rewrite uwrap_libc_fns struct to pass strict aliasing rules. Also rename struct uwrap_libc_fns fns to uwrap_libc_symbols and uwrap_load_lib_function to uwrap_bind_symbol (same for _uwrap_load_... variant. Signed-off-by: Robin Hack Reviewed-by: Andreas Schneider Reviewed-by: Stefan Metzmacher --- lib/uid_wrapper/uid_wrapper.c | 175 ++++++++++++++++++++++++++++-------------- 1 file changed, 116 insertions(+), 59 deletions(-) diff --git a/lib/uid_wrapper/uid_wrapper.c b/lib/uid_wrapper/uid_wrapper.c index 42c3083a115..50dfaa4b165 100644 --- a/lib/uid_wrapper/uid_wrapper.c +++ b/lib/uid_wrapper/uid_wrapper.c @@ -177,43 +177,99 @@ static void uwrap_log(enum uwrap_dbglvl_e dbglvl, const char *format, ...) #define LIBC_NAME "libc.so" -struct uwrap_libc_fns { - int (*_libc_setuid)(uid_t uid); - uid_t (*_libc_getuid)(void); +typedef int (*__libc_setuid)(uid_t uid); + +typedef uid_t (*__libc_getuid)(void); #ifdef HAVE_SETEUID - int (*_libc_seteuid)(uid_t euid); +typedef int (*__libc_seteuid)(uid_t euid); #endif + #ifdef HAVE_SETREUID - int (*_libc_setreuid)(uid_t ruid, uid_t euid); +typedef int (*__libc_setreuid)(uid_t ruid, uid_t euid); #endif + #ifdef HAVE_SETRESUID - int (*_libc_setresuid)(uid_t ruid, uid_t euid, uid_t suid); +typedef int (*__libc_setresuid)(uid_t ruid, uid_t euid, uid_t suid); #endif + #ifdef HAVE_GETRESUID - int (*_libc_getresuid)(uid_t *ruid, uid_t *euid, uid_t *suid); +typedef int (*__libc_getresuid)(uid_t *ruid, uid_t *euid, uid_t *suid); #endif - uid_t (*_libc_geteuid)(void); - int (*_libc_setgid)(gid_t gid); - gid_t (*_libc_getgid)(void); +typedef uid_t (*__libc_geteuid)(void); + +typedef int (*__libc_setgid)(gid_t gid); + +typedef gid_t (*__libc_getgid)(void); + #ifdef HAVE_SETEGID - int (*_libc_setegid)(uid_t egid); +typedef int (*__libc_setegid)(uid_t egid); #endif + #ifdef HAVE_SETREGID - int (*_libc_setregid)(uid_t rgid, uid_t egid); +typedef int (*__libc_setregid)(uid_t rgid, uid_t egid); #endif + #ifdef HAVE_SETRESGID - int (*_libc_setresgid)(uid_t rgid, uid_t egid, uid_t sgid); +typedef int (*__libc_setresgid)(uid_t rgid, uid_t egid, uid_t sgid); #endif + #ifdef HAVE_GETRESGID - int (*_libc_getresgid)(gid_t *rgid, gid_t *egid, gid_t *sgid); +typedef int (*__libc_getresgid)(gid_t *rgid, gid_t *egid, gid_t *sgid); #endif - gid_t (*_libc_getegid)(void); - int (*_libc_getgroups)(int size, gid_t list[]); - int (*_libc_setgroups)(size_t size, const gid_t *list); + +typedef gid_t (*__libc_getegid)(void); + +typedef int (*__libc_getgroups)(int size, gid_t list[]); + +typedef int (*__libc_setgroups)(size_t size, const gid_t *list); + #ifdef HAVE_SYSCALL - long int (*_libc_syscall)(long int sysno, ...); +typedef long int (*__libc_syscall)(long int sysno, ...); +#endif + +#define UWRAP_SYMBOL_ENTRY(i) \ + union { \ + __libc_##i f; \ + void *obj; \ + } _libc_##i + +struct uwrap_libc_symbols { + UWRAP_SYMBOL_ENTRY(setuid); + UWRAP_SYMBOL_ENTRY(getuid); +#ifdef HAVE_SETEUID + UWRAP_SYMBOL_ENTRY(seteuid); +#endif +#ifdef HAVE_SETREUID + UWRAP_SYMBOL_ENTRY(setreuid); +#endif +#ifdef HAVE_SETRESUID + UWRAP_SYMBOL_ENTRY(setresuid); +#endif +#ifdef HAVE_GETRESUID + UWRAP_SYMBOL_ENTRY(getresuid); +#endif + UWRAP_SYMBOL_ENTRY(geteuid); + UWRAP_SYMBOL_ENTRY(setgid); + UWRAP_SYMBOL_ENTRY(getgid); +#ifdef HAVE_SETEGID + UWRAP_SYMBOL_ENTRY(setegid); +#endif +#ifdef HAVE_SETREGID + UWRAP_SYMBOL_ENTRY(setregid); +#endif +#ifdef HAVE_SETRESGID + UWRAP_SYMBOL_ENTRY(setresgid); +#endif +#ifdef HAVE_GETRESGID + UWRAP_SYMBOL_ENTRY(getresgid); +#endif + UWRAP_SYMBOL_ENTRY(getegid); + UWRAP_SYMBOL_ENTRY(getgroups); + UWRAP_SYMBOL_ENTRY(setgroups); +#ifdef HAVE_SYSCALL + UWRAP_SYMBOL_ENTRY(syscall); #endif }; @@ -244,7 +300,7 @@ struct uwrap { struct { void *handle; - struct uwrap_libc_fns fns; + struct uwrap_libc_symbols symbols; } libc; bool initialised; @@ -276,7 +332,7 @@ static UWRAP_THREAD struct uwrap_thread *uwrap_tls_id; /* The mutex or accessing the id */ static pthread_mutex_t uwrap_id_mutex = PTHREAD_MUTEX_INITIALIZER; -/* The mutex for accessing the global libc.fns */ +/* The mutex for accessing the global libc.symbols */ static pthread_mutex_t libc_symbol_binding_mutex = PTHREAD_MUTEX_INITIALIZER; /********************************************************* @@ -344,7 +400,7 @@ static void *uwrap_load_lib_handle(enum uwrap_lib lib) return handle; } -static void *_uwrap_load_lib_function(enum uwrap_lib lib, const char *fn_name) +static void *_uwrap_bind_symbol(enum uwrap_lib lib, const char *fn_name) { void *handle; void *func; @@ -362,11 +418,11 @@ static void *_uwrap_load_lib_function(enum uwrap_lib lib, const char *fn_name) return func; } -#define uwrap_load_lib_function(lib, fn_name) \ +#define uwrap_bind_symbol(lib, sym_name) \ UWRAP_LOCK(libc_symbol_binding); \ - if (uwrap.libc.fns._libc_##fn_name == NULL) { \ - *(void **) (&uwrap.libc.fns._libc_##fn_name) = \ - _uwrap_load_lib_function(lib, #fn_name); \ + if (uwrap.libc.symbols._libc_##sym_name.obj == NULL) { \ + uwrap.libc.symbols._libc_##sym_name.obj = \ + _uwrap_bind_symbol(lib, #sym_name); \ } \ UWRAP_UNLOCK(libc_symbol_binding) @@ -380,130 +436,130 @@ static void *_uwrap_load_lib_function(enum uwrap_lib lib, const char *fn_name) */ static int libc_setuid(uid_t uid) { - uwrap_load_lib_function(UWRAP_LIBC, setuid); + uwrap_bind_symbol(UWRAP_LIBC, setuid); - return uwrap.libc.fns._libc_setuid(uid); + return uwrap.libc.symbols._libc_setuid.f(uid); } static uid_t libc_getuid(void) { - uwrap_load_lib_function(UWRAP_LIBC, getuid); + uwrap_bind_symbol(UWRAP_LIBC, getuid); - return uwrap.libc.fns._libc_getuid(); + return uwrap.libc.symbols._libc_getuid.f(); } #ifdef HAVE_SETEUID static int libc_seteuid(uid_t euid) { - uwrap_load_lib_function(UWRAP_LIBC, seteuid); + uwrap_bind_symbol(UWRAP_LIBC, seteuid); - return uwrap.libc.fns._libc_seteuid(euid); + return uwrap.libc.symbols._libc_seteuid.f(euid); } #endif #ifdef HAVE_SETREUID static int libc_setreuid(uid_t ruid, uid_t euid) { - uwrap_load_lib_function(UWRAP_LIBC, setreuid); + uwrap_bind_symbol(UWRAP_LIBC, setreuid); - return uwrap.libc.fns._libc_setreuid(ruid, euid); + return uwrap.libc.symbols._libc_setreuid.f(ruid, euid); } #endif #ifdef HAVE_SETRESUID static int libc_setresuid(uid_t ruid, uid_t euid, uid_t suid) { - uwrap_load_lib_function(UWRAP_LIBC, setresuid); + uwrap_bind_symbol(UWRAP_LIBC, setresuid); - return uwrap.libc.fns._libc_setresuid(ruid, euid, suid); + return uwrap.libc.symbols._libc_setresuid.f(ruid, euid, suid); } #endif #ifdef HAVE_GETRESUID static int libc_getresuid(uid_t *ruid, uid_t *euid, uid_t *suid) { - uwrap_load_lib_function(UWRAP_LIBC, getresuid); + uwrap_bind_symbol(UWRAP_LIBC, getresuid); - return uwrap.libc.fns._libc_getresuid(ruid, euid, suid); + return uwrap.libc.symbols._libc_getresuid.f(ruid, euid, suid); } #endif static uid_t libc_geteuid(void) { - uwrap_load_lib_function(UWRAP_LIBC, geteuid); + uwrap_bind_symbol(UWRAP_LIBC, geteuid); - return uwrap.libc.fns._libc_geteuid(); + return uwrap.libc.symbols._libc_geteuid.f(); } static int libc_setgid(gid_t gid) { - uwrap_load_lib_function(UWRAP_LIBC, setgid); + uwrap_bind_symbol(UWRAP_LIBC, setgid); - return uwrap.libc.fns._libc_setgid(gid); + return uwrap.libc.symbols._libc_setgid.f(gid); } static gid_t libc_getgid(void) { - uwrap_load_lib_function(UWRAP_LIBC, getgid); + uwrap_bind_symbol(UWRAP_LIBC, getgid); - return uwrap.libc.fns._libc_getgid(); + return uwrap.libc.symbols._libc_getgid.f(); } #ifdef HAVE_SETEGID static int libc_setegid(gid_t egid) { - uwrap_load_lib_function(UWRAP_LIBC, setegid); + uwrap_bind_symbol(UWRAP_LIBC, setegid); - return uwrap.libc.fns._libc_setegid(egid); + return uwrap.libc.symbols._libc_setegid.f(egid); } #endif #ifdef HAVE_SETREGID static int libc_setregid(gid_t rgid, gid_t egid) { - uwrap_load_lib_function(UWRAP_LIBC, setregid); + uwrap_bind_symbol(UWRAP_LIBC, setregid); - return uwrap.libc.fns._libc_setregid(rgid, egid); + return uwrap.libc.symbols._libc_setregid.f(rgid, egid); } #endif #ifdef HAVE_SETRESGID static int libc_setresgid(gid_t rgid, gid_t egid, gid_t sgid) { - uwrap_load_lib_function(UWRAP_LIBC, setresgid); + uwrap_bind_symbol(UWRAP_LIBC, setresgid); - return uwrap.libc.fns._libc_setresgid(rgid, egid, sgid); + return uwrap.libc.symbols._libc_setresgid.f(rgid, egid, sgid); } #endif #ifdef HAVE_GETRESGID static int libc_getresgid(gid_t *rgid, gid_t *egid, gid_t *sgid) { - uwrap_load_lib_function(UWRAP_LIBC, setresgid); + uwrap_bind_symbol(UWRAP_LIBC, setresgid); - return uwrap.libc.fns._libc_getresgid(rgid, egid, sgid); + return uwrap.libc.symbols._libc_getresgid.f(rgid, egid, sgid); } #endif static gid_t libc_getegid(void) { - uwrap_load_lib_function(UWRAP_LIBC, getegid); + uwrap_bind_symbol(UWRAP_LIBC, getegid); - return uwrap.libc.fns._libc_getegid(); + return uwrap.libc.symbols._libc_getegid.f(); } static int libc_getgroups(int size, gid_t list[]) { - uwrap_load_lib_function(UWRAP_LIBC, getgroups); + uwrap_bind_symbol(UWRAP_LIBC, getgroups); - return uwrap.libc.fns._libc_getgroups(size, list); + return uwrap.libc.symbols._libc_getgroups.f(size, list); } static int libc_setgroups(size_t size, const gid_t *list) { - uwrap_load_lib_function(UWRAP_LIBC, setgroups); + uwrap_bind_symbol(UWRAP_LIBC, setgroups); - return uwrap.libc.fns._libc_setgroups(size, list); + return uwrap.libc.symbols._libc_setgroups.f(size, list); } #ifdef HAVE_SYSCALL @@ -514,13 +570,13 @@ static long int libc_vsyscall(long int sysno, va_list va) long int rc; int i; - uwrap_load_lib_function(UWRAP_LIBC, syscall); + uwrap_bind_symbol(UWRAP_LIBC, syscall); for (i = 0; i < 8; i++) { args[i] = va_arg(va, long int); } - rc = uwrap.libc.fns._libc_syscall(sysno, + rc = uwrap.libc.symbols._libc_syscall.f(sysno, args[0], args[1], args[2], @@ -633,6 +689,7 @@ static void uwrap_init(void) pthread_t tid = pthread_self(); UWRAP_LOCK(uwrap_id); + if (uwrap.initialised) { struct uwrap_thread *id = uwrap_tls_id; int rc; -- 2.11.4.GIT