summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRich Felker <dalias@aerifal.cx>2024-06-22 16:54:11 -0400
committerRich Felker <dalias@aerifal.cx>2024-06-22 16:54:11 -0400
commit50ab830633134dac99011219f0210ee2759ffbde (patch)
tree5d2581051dd56822a7a1fcf69352bb60534bae12
parent1b97d0060ba585df41f0a55a1f8c33c704d0dfbe (diff)
downloadmusl-50ab830633134dac99011219f0210ee2759ffbde.tar.gz
dynlink: avoid copying to temp buffer in get_lfs64
while commit 53ac44ff4c0e91536e1e34e8e59e19d2a1196a67 fixed the temp buffer being undersized, the use of a temp buffer to begin with was a mistake. instead, compare the requested symbol name in-place and use the already-null-terminated copy of the name without "64" present in lfs64_list[] to look up the real symbol.
-rw-r--r--ldso/dynlink.c13
1 files changed, 4 insertions, 9 deletions
diff --git a/ldso/dynlink.c b/ldso/dynlink.c
index 8707ae1c..3b57c07f 100644
--- a/ldso/dynlink.c
+++ b/ldso/dynlink.c
@@ -362,19 +362,14 @@ static struct symdef get_lfs64(const char *name)
"pwritev\0readdir\0scandir\0sendfile\0setrlimit\0"
"stat\0statfs\0statvfs\0tmpfile\0truncate\0versionsort\0"
"__fxstat\0__fxstatat\0__lxstat\0__xstat\0";
- size_t l;
- char buf[17];
- for (l=0; name[l]; l++) {
- if (l >= sizeof buf) goto nomatch;
- buf[l] = name[l];
- }
if (!strcmp(name, "readdir64_r"))
return find_sym(&ldso, "readdir_r", 1);
- if (l<2 || name[l-2]!='6' || name[l-1]!='4')
+ size_t l = strnlen(name, 18);
+ if (l<2 || name[l-2]!='6' || name[l-1]!='4' || name[l])
goto nomatch;
- buf[l-=2] = 0;
for (p=lfs64_list; *p; p++) {
- if (!strcmp(buf, p)) return find_sym(&ldso, buf, 1);
+ if (!strncmp(name, p, l-2) && !p[l-2])
+ return find_sym(&ldso, p, 1);
while (*p) p++;
}
nomatch: