Skip to content

Commit 538f2b9

Browse files
committed
rwrap: Fix strict aliasing warnings for symbol binding
Signed-off-by: Andreas Schneider <asn@cryptomilk.org> Reviewed-by: Stefan Metzmacher <metze@samba.org>
1 parent 07592c5 commit 538f2b9

File tree

1 file changed

+111
-94
lines changed

1 file changed

+111
-94
lines changed

src/resolv_wrapper.c

Lines changed: 111 additions & 94 deletions
Original file line numberDiff line numberDiff line change
@@ -981,51 +981,68 @@ static int rwrap_res_fake_hosts(const char *hostfile,
981981

982982
#include <dlfcn.h>
983983

984-
struct rwrap_libc_fns {
985-
int (*libc_res_init)(void);
986-
int (*libc___res_init)(void);
987-
int (*libc_res_ninit)(struct __res_state *state);
988-
int (*libc___res_ninit)(struct __res_state *state);
989-
void (*libc_res_nclose)(struct __res_state *state);
990-
void (*libc___res_nclose)(struct __res_state *state);
991-
void (*libc_res_close)(void);
992-
void (*libc___res_close)(void);
993-
int (*libc_res_nquery)(struct __res_state *state,
994-
const char *dname,
995-
int class,
996-
int type,
997-
unsigned char *answer,
998-
int anslen);
999-
int (*libc___res_nquery)(struct __res_state *state,
984+
typedef int (*__libc_res_ninit)(struct __res_state *state);
985+
typedef int (*__libc___res_ninit)(struct __res_state *state);
986+
typedef void (*__libc_res_nclose)(struct __res_state *state);
987+
typedef void (*__libc___res_nclose)(struct __res_state *state);
988+
typedef int (*__libc_res_nquery)(struct __res_state *state,
1000989
const char *dname,
1001990
int class,
1002991
int type,
1003992
unsigned char *answer,
1004993
int anslen);
1005-
int (*libc_res_nsearch)(struct __res_state *state,
1006-
const char *dname,
1007-
int class,
1008-
int type,
1009-
unsigned char *answer,
1010-
int anslen);
1011-
int (*libc___res_nsearch)(struct __res_state *state,
994+
typedef int (*__libc___res_nquery)(struct __res_state *state,
995+
const char *dname,
996+
int class,
997+
int type,
998+
unsigned char *answer,
999+
int anslen);
1000+
typedef int (*__libc_res_nsearch)(struct __res_state *state,
10121001
const char *dname,
10131002
int class,
10141003
int type,
10151004
unsigned char *answer,
10161005
int anslen);
1006+
typedef int (*__libc___res_nsearch)(struct __res_state *state,
1007+
const char *dname,
1008+
int class,
1009+
int type,
1010+
unsigned char *answer,
1011+
int anslen);
1012+
1013+
#define RWRAP_SYMBOL_ENTRY(i) \
1014+
union { \
1015+
__libc_##i f; \
1016+
void *obj; \
1017+
} _libc_##i
1018+
1019+
struct rwrap_libc_symbols {
1020+
RWRAP_SYMBOL_ENTRY(res_ninit);
1021+
RWRAP_SYMBOL_ENTRY(__res_ninit);
1022+
RWRAP_SYMBOL_ENTRY(res_nclose);
1023+
RWRAP_SYMBOL_ENTRY(__res_nclose);
1024+
RWRAP_SYMBOL_ENTRY(res_nquery);
1025+
RWRAP_SYMBOL_ENTRY(__res_nquery);
1026+
RWRAP_SYMBOL_ENTRY(res_nsearch);
1027+
RWRAP_SYMBOL_ENTRY(__res_nsearch);
10171028
};
1029+
#undef RWRAP_SYMBOL_ENTRY
10181030

10191031
struct rwrap {
1020-
void *libc_handle;
1021-
void *libresolv_handle;
1032+
struct {
1033+
void *handle;
1034+
struct rwrap_libc_symbols symbols;
1035+
} libc;
1036+
1037+
struct {
1038+
void *handle;
1039+
struct rwrap_libc_symbols symbols;
1040+
} libresolv;
10221041

10231042
bool initialised;
10241043
bool enabled;
10251044

10261045
char *socket_dir;
1027-
1028-
struct rwrap_libc_fns fns;
10291046
};
10301047

10311048
static struct rwrap rwrap;
@@ -1063,7 +1080,7 @@ static void *rwrap_load_lib_handle(enum rwrap_lib lib)
10631080
switch (lib) {
10641081
case RWRAP_LIBRESOLV:
10651082
#ifdef HAVE_LIBRESOLV
1066-
handle = rwrap.libresolv_handle;
1083+
handle = rwrap.libresolv.handle;
10671084
if (handle == NULL) {
10681085
for (i = 10; i >= 0; i--) {
10691086
char soname[256] = {0};
@@ -1075,18 +1092,18 @@ static void *rwrap_load_lib_handle(enum rwrap_lib lib)
10751092
}
10761093
}
10771094

1078-
rwrap.libresolv_handle = handle;
1095+
rwrap.libresolv.handle = handle;
10791096
}
10801097
break;
10811098
#endif
10821099
/* FALL TROUGH */
10831100
case RWRAP_LIBC:
1084-
handle = rwrap.libc_handle;
1101+
handle = rwrap.libc.handle;
10851102
#ifdef LIBC_SO
10861103
if (handle == NULL) {
10871104
handle = dlopen(LIBC_SO, flags);
10881105

1089-
rwrap.libc_handle = handle;
1106+
rwrap.libc.handle = handle;
10901107
}
10911108
#endif
10921109
if (handle == NULL) {
@@ -1100,14 +1117,14 @@ static void *rwrap_load_lib_handle(enum rwrap_lib lib)
11001117
}
11011118
}
11021119

1103-
rwrap.libc_handle = handle;
1120+
rwrap.libc.handle = handle;
11041121
}
11051122
break;
11061123
}
11071124

11081125
if (handle == NULL) {
11091126
#ifdef RTLD_NEXT
1110-
handle = rwrap.libc_handle = rwrap.libresolv_handle = RTLD_NEXT;
1127+
handle = rwrap.libc.handle = rwrap.libresolv.handle = RTLD_NEXT;
11111128
#else
11121129
RWRAP_LOG(RWRAP_LOG_ERROR,
11131130
"Failed to dlopen library: %s\n",
@@ -1119,7 +1136,7 @@ static void *rwrap_load_lib_handle(enum rwrap_lib lib)
11191136
return handle;
11201137
}
11211138

1122-
static void *_rwrap_load_lib_function(enum rwrap_lib lib, const char *fn_name)
1139+
static void *_rwrap_bind_symbol(enum rwrap_lib lib, const char *fn_name)
11231140
{
11241141
void *handle;
11251142
void *func;
@@ -1140,10 +1157,16 @@ static void *_rwrap_load_lib_function(enum rwrap_lib lib, const char *fn_name)
11401157
return func;
11411158
}
11421159

1143-
#define rwrap_load_lib_function(lib, fn_name) \
1144-
if (rwrap.fns.libc_##fn_name == NULL) { \
1145-
*(void **) (&rwrap.fns.libc_##fn_name) = \
1146-
_rwrap_load_lib_function(lib, #fn_name); \
1160+
#define rwrap_bind_symbol_libc(sym_name) \
1161+
if (rwrap.libc.symbols._libc_##sym_name.obj == NULL) { \
1162+
rwrap.libc.symbols._libc_##sym_name.obj = \
1163+
_rwrap_bind_symbol(RWRAP_LIBC, #sym_name); \
1164+
}
1165+
1166+
#define rwrap_bind_symbol_libresolv(sym_name) \
1167+
if (rwrap.libresolv.symbols._libc_##sym_name.obj == NULL) { \
1168+
rwrap.libresolv.symbols._libc_##sym_name.obj = \
1169+
_rwrap_bind_symbol(RWRAP_LIBRESOLV, #sym_name); \
11471170
}
11481171

11491172
/*
@@ -1154,36 +1177,25 @@ static void *_rwrap_load_lib_function(enum rwrap_lib lib, const char *fn_name)
11541177
* has probably something todo with with the linker.
11551178
* So we need load each function at the point it is called the first time.
11561179
*/
1157-
#if 0
1158-
static int libc_res_init(void)
1159-
{
1160-
#if !defined(res_init) && defined(HAVE_RES_INIT)
1161-
rwrap_load_lib_function(RWRAP_LIBRESOLV, res_init);
1162-
1163-
return rwrap.fns.libc_res_init();
1164-
#elif defined(HAVE___RES_INIT)
1165-
rwrap_load_lib_function(RWRAP_LIBRESOLV, __res_init);
1166-
1167-
return rwrap.fns.libc___res_init();
1168-
#endif
1169-
}
1170-
#endif
11711180

11721181
static int libc_res_ninit(struct __res_state *state)
11731182
{
11741183
#if !defined(res_ninit) && defined(HAVE_RES_NINIT)
11751184

11761185
#if defined(HAVE_RES_NINIT_IN_LIBRESOLV)
1177-
rwrap_load_lib_function(RWRAP_LIBRESOLV, res_ninit);
1186+
rwrap_bind_symbol_libresolv(res_ninit);
1187+
1188+
return rwrap.libresolv.symbols._libc_res_ninit.f(state);
11781189
#else /* HAVE_RES_NINIT_IN_LIBRESOLV */
1179-
rwrap_load_lib_function(RWRAP_LIBC, res_ninit);
1190+
rwrap_bind_symbol_libc(res_ninit);
1191+
1192+
return rwrap.libc.symbols._libc_res_ninit.f(state);
11801193
#endif /* HAVE_RES_NINIT_IN_LIBRESOLV */
11811194

1182-
return rwrap.fns.libc_res_ninit(state);
11831195
#elif defined(HAVE___RES_NINIT)
1184-
rwrap_load_lib_function(RWRAP_LIBC, __res_ninit);
1196+
rwrap_bind_symbol_libc(__res_ninit);
11851197

1186-
return rwrap.fns.libc___res_ninit(state);
1198+
return rwrap.libc.symbols._libc___res_ninit.f(state);
11871199
#else
11881200
#error "No res_ninit function"
11891201
#endif
@@ -1194,16 +1206,21 @@ static void libc_res_nclose(struct __res_state *state)
11941206
#if !defined(res_close) && defined(HAVE_RES_NCLOSE)
11951207

11961208
#if defined(HAVE_RES_NCLOSE_IN_LIBRESOLV)
1197-
rwrap_load_lib_function(RWRAP_LIBRESOLV, res_nclose);
1209+
rwrap_bind_symbol_libresolv(res_nclose);
1210+
1211+
rwrap.libresolv.symbols._libc_res_nclose.f(state);
1212+
return;
11981213
#else /* HAVE_RES_NCLOSE_IN_LIBRESOLV */
1199-
rwrap_load_lib_function(RWRAP_LIBC, res_nclose);
1214+
rwrap_bind_symbol_libc(res_nclose);
1215+
1216+
rwrap.libc.symbols._libc_res_nclose.f(state);
1217+
return;
12001218
#endif /* HAVE_RES_NCLOSE_IN_LIBRESOLV */
12011219

1202-
rwrap.fns.libc_res_nclose(state);
12031220
#elif defined(HAVE___RES_NCLOSE)
1204-
rwrap_load_lib_function(RWRAP_LIBC, __res_nclose);
1221+
rwrap_bind_symbol_libc(__res_nclose);
12051222

1206-
rwrap.fns.libc___res_nclose(state);
1223+
rwrap.libc.symbols._libc___res_nclose.f(state);
12071224
#else
12081225
#error "No res_nclose function"
12091226
#endif
@@ -1217,23 +1234,23 @@ static int libc_res_nquery(struct __res_state *state,
12171234
int anslen)
12181235
{
12191236
#if !defined(res_nquery) && defined(HAVE_RES_NQUERY)
1220-
rwrap_load_lib_function(RWRAP_LIBRESOLV, res_nquery);
1221-
1222-
return rwrap.fns.libc_res_nquery(state,
1223-
dname,
1224-
class,
1225-
type,
1226-
answer,
1227-
anslen);
1237+
rwrap_bind_symbol_libresolv(res_nquery);
1238+
1239+
return rwrap.libresolv.symbols._libc_res_nquery.f(state,
1240+
dname,
1241+
class,
1242+
type,
1243+
answer,
1244+
anslen);
12281245
#elif defined(HAVE___RES_NQUERY)
1229-
rwrap_load_lib_function(RWRAP_LIBRESOLV, __res_nquery);
1230-
1231-
return rwrap.fns.libc___res_nquery(state,
1232-
dname,
1233-
class,
1234-
type,
1235-
answer,
1236-
anslen);
1246+
rwrap_bind_symbol_libresolv(__res_nquery);
1247+
1248+
return rwrap.libresolv.symbols._libc___res_nquery.f(state,
1249+
dname,
1250+
class,
1251+
type,
1252+
answer,
1253+
anslen);
12371254
#else
12381255
#error "No res_nquery function"
12391256
#endif
@@ -1247,23 +1264,23 @@ static int libc_res_nsearch(struct __res_state *state,
12471264
int anslen)
12481265
{
12491266
#if !defined(res_nsearch) && defined(HAVE_RES_NSEARCH)
1250-
rwrap_load_lib_function(RWRAP_LIBRESOLV, res_nsearch);
1251-
1252-
return rwrap.fns.libc_res_nsearch(state,
1253-
dname,
1254-
class,
1255-
type,
1256-
answer,
1257-
anslen);
1267+
rwrap_bind_symbol_libresolv(res_nsearch);
1268+
1269+
return rwrap.libresolv.symbols._libc_res_nsearch.f(state,
1270+
dname,
1271+
class,
1272+
type,
1273+
answer,
1274+
anslen);
12581275
#elif defined(HAVE___RES_NSEARCH)
1259-
rwrap_load_lib_function(RWRAP_LIBRESOLV, __res_nsearch);
1260-
1261-
return rwrap.fns.libc___res_nsearch(state,
1262-
dname,
1263-
class,
1264-
type,
1265-
answer,
1266-
anslen);
1276+
rwrap_bind_symbol_libresolv(__res_nsearch);
1277+
1278+
return rwrap.libresolv.symbols._libc___res_nsearch.f(state,
1279+
dname,
1280+
class,
1281+
type,
1282+
answer,
1283+
anslen);
12671284
#else
12681285
#error "No res_nsearch function"
12691286
#endif

0 commit comments

Comments
 (0)