Skip to content

Commit 22daaea

Browse files
committed
add time64 redirect for, and redirecting implementation of, dlsym
if symbols are being redirected to provide the new time64 ABI, dlsym must perform matching redirections; otherwise, it would poke a hole in the magic and return pointers to functions that are not safe to call from a caller using time64 types. rather than duplicating a table of redirections, use the time64 symbols present in libc's symbol table to derive the decision for whether a particular symbol needs to be redirected.
1 parent c045032 commit 22daaea

File tree

2 files changed

+31
-0
lines changed

2 files changed

+31
-0
lines changed

include/dlfcn.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,10 @@ int dladdr(const void *, Dl_info *);
3535
int dlinfo(void *, int, void *);
3636
#endif
3737

38+
#if _REDIR_TIME64
39+
__REDIR(dlsym, __dlsym_time64);
40+
#endif
41+
3842
#ifdef __cplusplus
3943
}
4044
#endif

ldso/dynlink.c

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2237,6 +2237,33 @@ hidden void *__dlsym(void *restrict p, const char *restrict s, void *restrict ra
22372237
return res;
22382238
}
22392239

2240+
hidden void *__dlsym_redir_time64(void *restrict p, const char *restrict s, void *restrict ra)
2241+
{
2242+
#if _REDIR_TIME64
2243+
const char *suffix, *suffix2 = "";
2244+
char redir[36];
2245+
2246+
/* Map the symbol name to a time64 version of itself according to the
2247+
* pattern used for naming the redirected time64 symbols. */
2248+
size_t l = strnlen(s, sizeof redir);
2249+
if (l<4 || l==sizeof redir) goto no_redir;
2250+
if (s[l-2]=='_' && s[l-1]=='r') {
2251+
l -= 2;
2252+
suffix2 = s+l;
2253+
}
2254+
if (l<4) goto no_redir;
2255+
if (!strcmp(s+l-4, "time")) suffix = "64";
2256+
else suffix = "_time64";
2257+
2258+
/* Use the presence of the remapped symbol name in libc to determine
2259+
* whether it's one that requires time64 redirection; replace if so. */
2260+
snprintf(redir, sizeof redir, "__%.*s%s%s", (int)l, s, suffix, suffix2);
2261+
if (find_sym(&ldso, redir, 1).sym) s = redir;
2262+
no_redir:
2263+
#endif
2264+
return __dlsym(p, s, ra);
2265+
}
2266+
22402267
int dl_iterate_phdr(int(*callback)(struct dl_phdr_info *info, size_t size, void *data), void *data)
22412268
{
22422269
struct dso *current;

0 commit comments

Comments
 (0)