NetBSD-Bugs archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
lib/59387: ld.elf_so: needlessly includes libc/gen/sysctl.c user.* data
>Number: 59387
>Category: lib
>Synopsis: ld.elf_so: needlessly includes libc/gen/sysctl.c user.* data
>Confidential: no
>Severity: serious
>Priority: medium
>Responsible: lib-bug-people
>State: open
>Class: sw-bug
>Submitter-Id: net
>Arrival-Date: Fri May 02 22:50:00 +0000 2025
>Originator: Taylor R Campbell
>Release: current
>Organization:
The RtldBloaatD Foundation
>Environment:
>Description:
ld.elf_so calls the libc sysctl() function to query sysctl kern.ostype, kern.osrelease, and hw.machine_arch for expanding $OSNAME, $OSREL, and $PLATFORM in, e.g., DT_RPATH entries:
91 case 3: /* OSNAME */
92 case 4: /* OSREL */
93 case 5: /* PLATFORM */
94 len = sizeof(name);
=> 95 if (sysctl(mib[what - 3], 2, name, &len, NULL, 0) == -1) {
96 xwarn("sysctl");
97 return 0;
98 }
99 ep = (p = name) + len - 1;
100 break;
https://nxr.netbsd.org/xref/src/libexec/ld.elf_so/expand.c?r=1.7#91
The libc sysctl() function is not just the syscall stub, though -- it is a wrapper that implements the user.* sysctl nodes:
72 int
73 sysctl(const int *name, unsigned int namelen,
74 void *oldp, size_t *oldlenp,
75 const void *newp, size_t newlen)
76 {
77 size_t oldlen, savelen;
78 int error;
79
80 if (name[0] != CTL_USER)
81 return (__sysctl(name, namelen, oldp, oldlenp,
82 newp, newlen));
83
84 oldlen = (oldlenp == NULL) ? 0 : *oldlenp;
85 savelen = oldlen;
86 error = user_sysctl(name + 1, namelen - 1, oldp, &oldlen, newp, newlen);
...
104 static int
105 user_sysctl(const int *name, unsigned int namelen,
106 void *oldp, size_t *oldlenp,
107 const void *newp, size_t newlen)
108 {
109 #define _INT(s, n, v, d) { \
110 .sysctl_flags = CTLFLAG_IMMEDIATE|CTLFLAG_PERMANENT| \
111 CTLTYPE_INT|SYSCTL_VERSION, \
112 .sysctl_size = sizeof(int), \
113 .sysctl_name = (s), \
114 .sysctl_num = (n), \
115 .sysctl_un.scu_idata = (v), \
116 .sysctl_desc = (d), \
117 }
118
119 /*
120 * the nodes under the "user" node
121 */
122 static const struct sysctlnode sysctl_usermib[] = {
123 {
124 .sysctl_flags = SYSCTL_VERSION|CTLFLAG_PERMANENT|
125 CTLTYPE_STRING,
126 .sysctl_size = sizeof(_PATH_STDPATH),
127 .sysctl_name = "cs_path",
128 .sysctl_num = USER_CS_PATH,
129 .sysctl_data = __UNCONST(_PATH_STDPATH),
130 .sysctl_desc = __UNCONST(
131 "A value for the PATH environment variable "
132 "that finds all the standard utilities"),
133 },
134 _INT("bc_base_max", USER_BC_BASE_MAX, BC_BASE_MAX,
135 "The maximum ibase/obase values in the bc(1) utility"),
136 _INT("bc_dim_max", USER_BC_DIM_MAX, BC_DIM_MAX,
137 "The maximum array size in the bc(1) utility"),
...
https://nxr.netbsd.org/xref/src/lib/libc/gen/sysctl.c?r=1.38#72
This sysctl_usermib table weighs in at a couple kilobytes and dozens of R_*_RELATIVE relocations at load-time (e.g., netbsd-10 amd64):
$ readelf -s /libexec/ld.elf_so | grep usermib
52: 0000000000210720 2016 OBJECT LOCAL DEFAULT 11 sysctl_usermib.0
$ readelf -r /libexec/ld.elf_so
Relocation section '.rela.dyn' at offset 0x530 contains 28 entries:
Offset Info Type Sym. Value Sym. Name + Addend
000000210750 000000000008 R_X86_64_RELATIVE d628 # <--
000000210778 000000000008 R_X86_64_RELATIVE d680
0000002107d8 000000000008 R_X86_64_RELATIVE d6d0
000000210838 000000000008 R_X86_64_RELATIVE d708
000000210898 000000000008 R_X86_64_RELATIVE d738
0000002108f8 000000000008 R_X86_64_RELATIVE d768
000000210958 000000000008 R_X86_64_RELATIVE d798
0000002109b8 000000000008 R_X86_64_RELATIVE d818
000000210a18 000000000008 R_X86_64_RELATIVE d878
000000210a78 000000000008 R_X86_64_RELATIVE d8c0
000000210ad8 000000000008 R_X86_64_RELATIVE d930
000000210b38 000000000008 R_X86_64_RELATIVE d978
000000210b98 000000000008 R_X86_64_RELATIVE d9d8
000000210bf8 000000000008 R_X86_64_RELATIVE da20
000000210c58 000000000008 R_X86_64_RELATIVE da90
000000210cb8 000000000008 R_X86_64_RELATIVE dad8
000000210d18 000000000008 R_X86_64_RELATIVE db20
000000210d78 000000000008 R_X86_64_RELATIVE db58
000000210dd8 000000000008 R_X86_64_RELATIVE dba0
000000210e38 000000000008 R_X86_64_RELATIVE dbe8
000000210e98 000000000008 R_X86_64_RELATIVE dc40
000000210ef8 000000000008 R_X86_64_RELATIVE dc90 # <--
000000210ff0 000000000008 R_X86_64_RELATIVE 210f00
000000210ff8 000000000008 R_X86_64_RELATIVE 211060
000000211048 000000000008 R_X86_64_RELATIVE 211040
000000211058 000000000008 R_X86_64_RELATIVE 211050
000000211088 000000000008 R_X86_64_RELATIVE d300
000000211090 000000000008 R_X86_64_RELATIVE d520
Relocations from the first `<--' comment to the second one are all for sysctl_usermib.
But ld.elf_so will never use the user.* sysctl nodes! So the table and the logic to search it is useless in ld.elf_so.
>How-To-Repeat:
readelf -a /libexec/ld.elf_so
>Fix:
Use the __sysctl() syscall stub instead of the sysctl() wrapper.
Home |
Main Index |
Thread Index |
Old Index