diff options
Diffstat (limited to 'core/musl')
| -rw-r--r-- | core/musl/.footprint | 247 | ||||
| -rw-r--r-- | core/musl/.signature | 12 | ||||
| -rw-r--r-- | core/musl/CVE-2026-40200.patch | 179 | ||||
| -rw-r--r-- | core/musl/CVE-2026-6042.patch | 321 | ||||
| -rw-r--r-- | core/musl/MAKEPKG | 67 | ||||
| -rw-r--r-- | core/musl/getconf.c | 338 | ||||
| -rw-r--r-- | core/musl/getent.c | 536 | ||||
| -rw-r--r-- | core/musl/iconv.c | 110 | ||||
| -rw-r--r-- | core/musl/ldd | 19 |
9 files changed, 1829 insertions, 0 deletions
diff --git a/core/musl/.footprint b/core/musl/.footprint new file mode 100644 index 0000000..e27870b --- /dev/null +++ b/core/musl/.footprint @@ -0,0 +1,247 @@ +drwxr-xr-x root/root bin/ +-rwxr-xr-x root/root bin/getconf +-rwxr-xr-x root/root bin/getent +-rwxr-xr-x root/root bin/iconv +-rwxr-xr-x root/root bin/ldd +drwxr-xr-x root/root include/ +-rw-r--r-- root/root include/aio.h +-rw-r--r-- root/root include/alloca.h +-rw-r--r-- root/root include/ar.h +-rw-r--r-- root/root include/assert.h +-rw-r--r-- root/root include/byteswap.h +-rw-r--r-- root/root include/complex.h +-rw-r--r-- root/root include/cpio.h +-rw-r--r-- root/root include/crypt.h +-rw-r--r-- root/root include/ctype.h +-rw-r--r-- root/root include/dirent.h +-rw-r--r-- root/root include/dlfcn.h +-rw-r--r-- root/root include/elf.h +-rw-r--r-- root/root include/endian.h +-rw-r--r-- root/root include/err.h +-rw-r--r-- root/root include/errno.h +-rw-r--r-- root/root include/fcntl.h +-rw-r--r-- root/root include/features.h +-rw-r--r-- root/root include/fenv.h +-rw-r--r-- root/root include/float.h +-rw-r--r-- root/root include/fmtmsg.h +-rw-r--r-- root/root include/fnmatch.h +-rw-r--r-- root/root include/ftw.h +-rw-r--r-- root/root include/getopt.h +-rw-r--r-- root/root include/glob.h +-rw-r--r-- root/root include/grp.h +-rw-r--r-- root/root include/iconv.h +-rw-r--r-- root/root include/ifaddrs.h +-rw-r--r-- root/root include/inttypes.h +-rw-r--r-- root/root include/iso646.h +-rw-r--r-- root/root include/langinfo.h +-rw-r--r-- root/root include/lastlog.h +-rw-r--r-- root/root include/libgen.h +-rw-r--r-- root/root include/libintl.h +-rw-r--r-- root/root include/limits.h +-rw-r--r-- root/root include/link.h +-rw-r--r-- root/root include/locale.h +-rw-r--r-- root/root include/malloc.h +-rw-r--r-- root/root include/math.h +-rw-r--r-- root/root include/memory.h +-rw-r--r-- root/root include/mntent.h +-rw-r--r-- root/root include/monetary.h +-rw-r--r-- root/root include/mqueue.h +-rw-r--r-- root/root include/netdb.h +-rw-r--r-- root/root include/nl_types.h +-rw-r--r-- root/root include/paths.h +-rw-r--r-- root/root include/poll.h +-rw-r--r-- root/root include/pthread.h +-rw-r--r-- root/root include/pty.h +-rw-r--r-- root/root include/pwd.h +-rw-r--r-- root/root include/regex.h +-rw-r--r-- root/root include/resolv.h +-rw-r--r-- root/root include/sched.h +-rw-r--r-- root/root include/search.h +-rw-r--r-- root/root include/semaphore.h +-rw-r--r-- root/root include/setjmp.h +-rw-r--r-- root/root include/shadow.h +-rw-r--r-- root/root include/signal.h +-rw-r--r-- root/root include/spawn.h +-rw-r--r-- root/root include/stdalign.h +-rw-r--r-- root/root include/stdarg.h +-rw-r--r-- root/root include/stdbool.h +-rw-r--r-- root/root include/stdc-predef.h +-rw-r--r-- root/root include/stddef.h +-rw-r--r-- root/root include/stdint.h +-rw-r--r-- root/root include/stdio.h +-rw-r--r-- root/root include/stdio_ext.h +-rw-r--r-- root/root include/stdlib.h +-rw-r--r-- root/root include/stdnoreturn.h +-rw-r--r-- root/root include/string.h +-rw-r--r-- root/root include/strings.h +-rw-r--r-- root/root include/stropts.h +-rw-r--r-- root/root include/syscall.h +-rw-r--r-- root/root include/sysexits.h +-rw-r--r-- root/root include/syslog.h +-rw-r--r-- root/root include/tar.h +-rw-r--r-- root/root include/termios.h +-rw-r--r-- root/root include/tgmath.h +-rw-r--r-- root/root include/threads.h +-rw-r--r-- root/root include/time.h +-rw-r--r-- root/root include/uchar.h +-rw-r--r-- root/root include/ucontext.h +-rw-r--r-- root/root include/ulimit.h +-rw-r--r-- root/root include/unistd.h +-rw-r--r-- root/root include/utime.h +-rw-r--r-- root/root include/utmp.h +-rw-r--r-- root/root include/utmpx.h +-rw-r--r-- root/root include/values.h +-rw-r--r-- root/root include/wait.h +-rw-r--r-- root/root include/wchar.h +-rw-r--r-- root/root include/wctype.h +-rw-r--r-- root/root include/wordexp.h +drwxr-xr-x root/root include/arpa/ +-rw-r--r-- root/root include/arpa/ftp.h +-rw-r--r-- root/root include/arpa/inet.h +-rw-r--r-- root/root include/arpa/nameser.h +-rw-r--r-- root/root include/arpa/nameser_compat.h +-rw-r--r-- root/root include/arpa/telnet.h +-rw-r--r-- root/root include/arpa/tftp.h +drwxr-xr-x root/root include/bits/ +-rw-r--r-- root/root include/bits/alltypes.h +-rw-r--r-- root/root include/bits/dirent.h +-rw-r--r-- root/root include/bits/errno.h +-rw-r--r-- root/root include/bits/fcntl.h +-rw-r--r-- root/root include/bits/fenv.h +-rw-r--r-- root/root include/bits/float.h +-rw-r--r-- root/root include/bits/hwcap.h (EMPTY) +-rw-r--r-- root/root include/bits/io.h +-rw-r--r-- root/root include/bits/ioctl.h +-rw-r--r-- root/root include/bits/ioctl_fix.h (EMPTY) +-rw-r--r-- root/root include/bits/ipc.h +-rw-r--r-- root/root include/bits/ipcstat.h +-rw-r--r-- root/root include/bits/kd.h +-rw-r--r-- root/root include/bits/limits.h +-rw-r--r-- root/root include/bits/link.h +-rw-r--r-- root/root include/bits/mman.h +-rw-r--r-- root/root include/bits/msg.h +-rw-r--r-- root/root include/bits/poll.h (EMPTY) +-rw-r--r-- root/root include/bits/ptrace.h +-rw-r--r-- root/root include/bits/reg.h +-rw-r--r-- root/root include/bits/resource.h (EMPTY) +-rw-r--r-- root/root include/bits/sem.h +-rw-r--r-- root/root include/bits/setjmp.h +-rw-r--r-- root/root include/bits/shm.h +-rw-r--r-- root/root include/bits/signal.h +-rw-r--r-- root/root include/bits/socket.h (EMPTY) +-rw-r--r-- root/root include/bits/soundcard.h +-rw-r--r-- root/root include/bits/stat.h +-rw-r--r-- root/root include/bits/statfs.h +-rw-r--r-- root/root include/bits/stdint.h +-rw-r--r-- root/root include/bits/syscall.h +-rw-r--r-- root/root include/bits/termios.h +-rw-r--r-- root/root include/bits/user.h +-rw-r--r-- root/root include/bits/vt.h +drwxr-xr-x root/root include/net/ +-rw-r--r-- root/root include/net/ethernet.h +-rw-r--r-- root/root include/net/if.h +-rw-r--r-- root/root include/net/if_arp.h +-rw-r--r-- root/root include/net/route.h +drwxr-xr-x root/root include/netinet/ +-rw-r--r-- root/root include/netinet/ether.h +-rw-r--r-- root/root include/netinet/icmp6.h +-rw-r--r-- root/root include/netinet/if_ether.h +-rw-r--r-- root/root include/netinet/igmp.h +-rw-r--r-- root/root include/netinet/in.h +-rw-r--r-- root/root include/netinet/in_systm.h +-rw-r--r-- root/root include/netinet/ip.h +-rw-r--r-- root/root include/netinet/ip6.h +-rw-r--r-- root/root include/netinet/ip_icmp.h +-rw-r--r-- root/root include/netinet/tcp.h +-rw-r--r-- root/root include/netinet/udp.h +drwxr-xr-x root/root include/netpacket/ +-rw-r--r-- root/root include/netpacket/packet.h +drwxr-xr-x root/root include/scsi/ +-rw-r--r-- root/root include/scsi/scsi.h +-rw-r--r-- root/root include/scsi/scsi_ioctl.h +-rw-r--r-- root/root include/scsi/sg.h +drwxr-xr-x root/root include/sys/ +-rw-r--r-- root/root include/sys/acct.h +-rw-r--r-- root/root include/sys/auxv.h +-rw-r--r-- root/root include/sys/cachectl.h +-rw-r--r-- root/root include/sys/dir.h +-rw-r--r-- root/root include/sys/epoll.h +-rw-r--r-- root/root include/sys/errno.h +-rw-r--r-- root/root include/sys/eventfd.h +-rw-r--r-- root/root include/sys/fanotify.h +-rw-r--r-- root/root include/sys/fcntl.h +-rw-r--r-- root/root include/sys/file.h +-rw-r--r-- root/root include/sys/fsuid.h +-rw-r--r-- root/root include/sys/inotify.h +-rw-r--r-- root/root include/sys/io.h +-rw-r--r-- root/root include/sys/ioctl.h +-rw-r--r-- root/root include/sys/ipc.h +-rw-r--r-- root/root include/sys/kd.h +-rw-r--r-- root/root include/sys/klog.h +-rw-r--r-- root/root include/sys/membarrier.h +-rw-r--r-- root/root include/sys/mman.h +-rw-r--r-- root/root include/sys/mount.h +-rw-r--r-- root/root include/sys/msg.h +-rw-r--r-- root/root include/sys/mtio.h +-rw-r--r-- root/root include/sys/param.h +-rw-r--r-- root/root include/sys/personality.h +-rw-r--r-- root/root include/sys/poll.h +-rw-r--r-- root/root include/sys/prctl.h +-rw-r--r-- root/root include/sys/procfs.h +-rw-r--r-- root/root include/sys/ptrace.h +-rw-r--r-- root/root include/sys/quota.h +-rw-r--r-- root/root include/sys/random.h +-rw-r--r-- root/root include/sys/reboot.h +-rw-r--r-- root/root include/sys/reg.h +-rw-r--r-- root/root include/sys/resource.h +-rw-r--r-- root/root include/sys/select.h +-rw-r--r-- root/root include/sys/sem.h +-rw-r--r-- root/root include/sys/sendfile.h +-rw-r--r-- root/root include/sys/shm.h +-rw-r--r-- root/root include/sys/signal.h +-rw-r--r-- root/root include/sys/signalfd.h +-rw-r--r-- root/root include/sys/socket.h +-rw-r--r-- root/root include/sys/soundcard.h +-rw-r--r-- root/root include/sys/stat.h +-rw-r--r-- root/root include/sys/statfs.h +-rw-r--r-- root/root include/sys/statvfs.h +-rw-r--r-- root/root include/sys/stropts.h +-rw-r--r-- root/root include/sys/swap.h +-rw-r--r-- root/root include/sys/syscall.h +-rw-r--r-- root/root include/sys/sysinfo.h +-rw-r--r-- root/root include/sys/syslog.h +-rw-r--r-- root/root include/sys/sysmacros.h +-rw-r--r-- root/root include/sys/termios.h +-rw-r--r-- root/root include/sys/time.h +-rw-r--r-- root/root include/sys/timeb.h +-rw-r--r-- root/root include/sys/timerfd.h +-rw-r--r-- root/root include/sys/times.h +-rw-r--r-- root/root include/sys/timex.h +-rw-r--r-- root/root include/sys/ttydefaults.h +-rw-r--r-- root/root include/sys/types.h +-rw-r--r-- root/root include/sys/ucontext.h +-rw-r--r-- root/root include/sys/uio.h +-rw-r--r-- root/root include/sys/un.h +-rw-r--r-- root/root include/sys/user.h +-rw-r--r-- root/root include/sys/utsname.h +-rw-r--r-- root/root include/sys/vfs.h +-rw-r--r-- root/root include/sys/vt.h +-rw-r--r-- root/root include/sys/wait.h +-rw-r--r-- root/root include/sys/xattr.h +drwxr-xr-x root/root lib/ +-rw-r--r-- root/root lib/Scrt1.o +-rw-r--r-- root/root lib/crt1.o +-rw-r--r-- root/root lib/crti.o +-rw-r--r-- root/root lib/crtn.o +-rw-r--r-- root/root lib/libc.a +-rwxr-xr-x root/root lib/libc.so +-rw-r--r-- root/root lib/libcrypt.a +-rw-r--r-- root/root lib/libdl.a +-rw-r--r-- root/root lib/libm.a +-rw-r--r-- root/root lib/libpthread.a +-rw-r--r-- root/root lib/libresolv.a +-rw-r--r-- root/root lib/librt.a +-rw-r--r-- root/root lib/libutil.a +-rw-r--r-- root/root lib/libxnet.a +-rw-r--r-- root/root lib/rcrt1.o +lrwxrwxrwx root/root lib/ld-musl-x86_64.so.1 -> /lib/libc.so diff --git a/core/musl/.signature b/core/musl/.signature new file mode 100644 index 0000000..9ea0e0c --- /dev/null +++ b/core/musl/.signature @@ -0,0 +1,12 @@ +RWTZ9IduCSQ/mAv94vrHB7zLW7p+eq/IEsava58afNULwTx8gOTEZkmx33m2WGxampPVpOXVDEBSi7LE31fIHjtCBNppn+K6Ig8= + +SHA256 (MAKEPKG) = 668235489d990b7873b1784dc7e03875525ecece3b85c94abd50613fe9185e3e +SHA256 (.footprint) = f69e9387d6a3fd18eae0f6bd91d0fda9948af756de244a2099a50e91a403c491 +SHA256 (musl-1.2.6.tar.gz) = d585fd3b613c66151fc3249e8ed44f77020cb5e6c1e635a616d3f9f82460512a +SHA256 (getconf.c) = d87d0cbb3690ae2c5d8cc218349fd8278b93855dd625deaf7ae50e320aad247c +SHA256 (getent.c) = b25f32d306d542246e9358ef65cd67c12b3e3a77656bc467853d3b0c76b5fbbd +SHA256 (iconv.c) = f79a2930a2e5bb0624321589edf8b889d1e9b603e01e6b7ae214616605b3fdd7 +SHA256 (ldd) = 2218e5f493a08cc981ef0888fb03d3b8f840d61e3025d9cc767d3963d3a55508 +SHA256 (CVE-2026-6042.patch) = 444fa70e52ca158fb7d4bad560637790bbf8f72e80b82fff840dd66fa83091e3 +SHA256 (CVE-2026-40200.patch) = 1ee29f64f9ca8e8ad7c349779d661ff6b52126a27575d3586981357a52c406fb +SHA256 (musl#1.2.6-2.pkg.tar.gz) = 79e9b5e5ea46bae973feacbea7c03a814f62b829fa49cddd8574ec8d6c142862 diff --git a/core/musl/CVE-2026-40200.patch b/core/musl/CVE-2026-40200.patch new file mode 100644 index 0000000..88298ca --- /dev/null +++ b/core/musl/CVE-2026-40200.patch @@ -0,0 +1,179 @@ +>From 228da39e38c1cae13cbe637e771412c1984dba5d Mon Sep 17 00:00:00 2001 +From: Rich Felker <dalias@aerifal.cx> +Date: Thu, 9 Apr 2026 22:51:30 -0400 +Subject: [PATCH 1/3] qsort: fix leonardo heap corruption from bug in + doubleword ctz primitive + +the pntz function, implementing a "count trailing zeros" variant for a +bit vector consisting of two size_t words, erroneously returned zero +rather than the number of bits in the low word when the first bit set +was the low bit of the high word. + +as a result, a loop in the trinkle function which should have a +guaranteed small bound on the number of iterations, could run +unboundedly, thereby overflowing a stack-based working-space array +which was sized for the bound. + +CVE-2026-40200 has been assigned for this issue. +--- + src/stdlib/qsort.c | 8 ++++---- + 1 file changed, 4 insertions(+), 4 deletions(-) + +diff --git a/src/stdlib/qsort.c b/src/stdlib/qsort.c +index ab79dc6f..13219ab3 100644 +--- a/src/stdlib/qsort.c ++++ b/src/stdlib/qsort.c +@@ -34,11 +34,11 @@ + + typedef int (*cmpfun)(const void *, const void *, void *); + ++/* returns index of first bit set, excluding the low bit assumed to always ++ * be set, starting from low bit of p[0] up through high bit of p[1] */ + static inline int pntz(size_t p[2]) { +- int r = ntz(p[0] - 1); +- if(r != 0 || (r = 8*sizeof(size_t) + ntz(p[1])) != 8*sizeof(size_t)) { +- return r; +- } ++ if (p[0] != 1) return ntz(p[0] - 1); ++ if (p[1]) return 8*sizeof(size_t) + ntz(p[1]); + return 0; + } + +-- +2.21.0 + + +>From b3291b9a9f77f1f993d2b4f8c68a26cf09221ae7 Mon Sep 17 00:00:00 2001 +From: Rich Felker <dalias@aerifal.cx> +Date: Thu, 9 Apr 2026 23:40:53 -0400 +Subject: [PATCH 2/3] qsort: hard-preclude oob array writes independent of any + invariants + +while the root cause of CVE-2026-40200 was a faulty ctz primitive, the +fallout of the bug would have been limited to erroneous sorting or +infinite loop if not for the stores to a stack-based array that +depended on trusting invariants in order not to go out of bounds. + +increase the size of the array to a power of two so that we can mask +indices into it to force them into range. in the absence of any +further bug, the masking is a no-op, but it does not have any +measurable performance cost, and it makes spatial memory safety +trivial to prove (and for readers not familiar with the algorithms to +trust). +--- + src/stdlib/qsort.c | 20 +++++++++++++------- + 1 file changed, 13 insertions(+), 7 deletions(-) + +diff --git a/src/stdlib/qsort.c b/src/stdlib/qsort.c +index 13219ab3..e4bce9f7 100644 +--- a/src/stdlib/qsort.c ++++ b/src/stdlib/qsort.c +@@ -89,10 +89,16 @@ static inline void shr(size_t p[2], int n) + p[1] >>= n; + } + ++/* power-of-two length for working array so that we can mask indices and ++ * not depend on any invariant of the algorithm for spatial memory safety. ++ * the original size was just 14*sizeof(size_t)+1 */ ++#define AR_LEN (16 * sizeof(size_t)) ++#define AR_MASK (AR_LEN - 1) ++ + static void sift(unsigned char *head, size_t width, cmpfun cmp, void *arg, int pshift, size_t lp[]) + { + unsigned char *rt, *lf; +- unsigned char *ar[14 * sizeof(size_t) + 1]; ++ unsigned char *ar[AR_LEN]; + int i = 1; + + ar[0] = head; +@@ -104,16 +110,16 @@ static void sift(unsigned char *head, size_t width, cmpfun cmp, void *arg, int p + break; + } + if(cmp(lf, rt, arg) >= 0) { +- ar[i++] = lf; ++ ar[i++ & AR_MASK] = lf; + head = lf; + pshift -= 1; + } else { +- ar[i++] = rt; ++ ar[i++ & AR_MASK] = rt; + head = rt; + pshift -= 2; + } + } +- cycle(width, ar, i); ++ cycle(width, ar, i & AR_MASK); + } + + static void trinkle(unsigned char *head, size_t width, cmpfun cmp, void *arg, size_t pp[2], int pshift, int trusty, size_t lp[]) +@@ -121,7 +127,7 @@ static void trinkle(unsigned char *head, size_t width, cmpfun cmp, void *arg, si + unsigned char *stepson, + *rt, *lf; + size_t p[2]; +- unsigned char *ar[14 * sizeof(size_t) + 1]; ++ unsigned char *ar[AR_LEN]; + int i = 1; + int trail; + +@@ -142,7 +148,7 @@ static void trinkle(unsigned char *head, size_t width, cmpfun cmp, void *arg, si + } + } + +- ar[i++] = stepson; ++ ar[i++ & AR_MASK] = stepson; + head = stepson; + trail = pntz(p); + shr(p, trail); +@@ -150,7 +156,7 @@ static void trinkle(unsigned char *head, size_t width, cmpfun cmp, void *arg, si + trusty = 0; + } + if(!trusty) { +- cycle(width, ar, i); ++ cycle(width, ar, i & AR_MASK); + sift(head, width, cmp, arg, pshift, lp); + } + } +-- +2.21.0 + + +>From 5122f9f3c99fee366167c5de98b31546312921ab Mon Sep 17 00:00:00 2001 +From: Luca Kellermann <mailto.luca.kellermann@gmail.com> +Date: Fri, 10 Apr 2026 03:03:22 +0200 +Subject: [PATCH 3/3] qsort: fix shift UB in shl and shr + +if shl() or shr() are called with n==8*sizeof(size_t), n is adjusted +to 0. the shift by (sizeof(size_t) * 8 - n) that then follows will +consequently shift by the width of size_t, which is UB and in practice +produces an incorrect result. + +return early in this case. the bitvector p was already shifted by the +required amount. +--- + src/stdlib/qsort.c | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/src/stdlib/qsort.c b/src/stdlib/qsort.c +index e4bce9f7..28607450 100644 +--- a/src/stdlib/qsort.c ++++ b/src/stdlib/qsort.c +@@ -71,6 +71,7 @@ static inline void shl(size_t p[2], int n) + n -= 8 * sizeof(size_t); + p[1] = p[0]; + p[0] = 0; ++ if (!n) return; + } + p[1] <<= n; + p[1] |= p[0] >> (sizeof(size_t) * 8 - n); +@@ -83,6 +84,7 @@ static inline void shr(size_t p[2], int n) + n -= 8 * sizeof(size_t); + p[0] = p[1]; + p[1] = 0; ++ if (!n) return; + } + p[0] >>= n; + p[0] |= p[1] << (sizeof(size_t) * 8 - n); +-- +2.21.0 + + diff --git a/core/musl/CVE-2026-6042.patch b/core/musl/CVE-2026-6042.patch new file mode 100644 index 0000000..9b39420 --- /dev/null +++ b/core/musl/CVE-2026-6042.patch @@ -0,0 +1,321 @@ +>From 67219f0130ec7c876ac0b299046460fad31caabf Mon Sep 17 00:00:00 2001 +From: Rich Felker <dalias@aerifal.cx> +Date: Mon, 30 Mar 2026 16:00:50 -0400 +Subject: [PATCH] fix pathological slowness & incorrect mappings in iconv + gb18030 decoder + +in order to implement the "UTF" aspect of gb18030 (ability to +represent arbitrary unicode characters not present in the 2-byte +mapping), we have to apply the index obtained from the encoded 4-byte +sequence into the set of unmapped characters. this was done by +scanning repeatedly over the table of mapped characters and counting +off mapped characters below a running index by which to adjust the +running index by on each iteration. this iterative process eventually +leaves us with the value of the Nth unmapped character replacing the +index, but depending on which particular character that is, the number +of iterations needed to find it can be in the tens of thousands, and +each iteration traverses the whole 126x190 table in the inner loop. +this can lead to run times exceeding an entire second per character on +moderate-speed machines. + +on top of that, the transformation logic produced wrong results for +BMP characters above the the surrogate range, as a result of not +correctly accounting for it being excluded, and for characters outside +the BMP, as a result of a misunderstanding of how gb18030 encodes +them. + +this patch replaces the unmapped character lookup with a single linear +search of a list of unmapped ranges. there are only 206 such ranges, +and these are permanently assigned and unchangeable as a consequence +of the character encoding having to be stable, so a simple array of +16-bit start/length values for each range consumes only 824 bytes, a +very reasonable size cost here. + +this new table accounts for the previously-incorrect surrogate +handling, and non-BMP characters are handled correctly by a single +offset, without the need for any unmapped-range search. + +there are still a small number of mappings that are incorrect due to +late changes made in the definition of gb18030, swapping PUA +codepoints with proper Unicode characters. correcting these requires a +postprocessing step that will be added later. +--- + src/locale/gb18030utf.h | 206 ++++++++++++++++++++++++++++++++++++++++ + src/locale/iconv.c | 33 +++++-- + 2 files changed, 230 insertions(+), 9 deletions(-) + create mode 100644 src/locale/gb18030utf.h + +diff --git a/src/locale/gb18030utf.h b/src/locale/gb18030utf.h +new file mode 100644 +index 00000000..322a2440 +--- /dev/null ++++ b/src/locale/gb18030utf.h +@@ -0,0 +1,206 @@ ++{ 0x80, 36 }, ++{ 0xa5, 2 }, ++{ 0xa9, 7 }, ++{ 0xb2, 5 }, ++{ 0xb8, 31 }, ++{ 0xd8, 8 }, ++{ 0xe2, 6 }, ++{ 0xeb, 1 }, ++{ 0xee, 4 }, ++{ 0xf4, 3 }, ++{ 0xf8, 1 }, ++{ 0xfb, 1 }, ++{ 0xfd, 4 }, ++{ 0x102, 17 }, ++{ 0x114, 7 }, ++{ 0x11c, 15 }, ++{ 0x12c, 24 }, ++{ 0x145, 3 }, ++{ 0x149, 4 }, ++{ 0x14e, 29 }, ++{ 0x16c, 98 }, ++{ 0x1cf, 1 }, ++{ 0x1d1, 1 }, ++{ 0x1d3, 1 }, ++{ 0x1d5, 1 }, ++{ 0x1d7, 1 }, ++{ 0x1d9, 1 }, ++{ 0x1db, 1 }, ++{ 0x1dd, 28 }, ++{ 0x1fa, 87 }, ++{ 0x252, 15 }, ++{ 0x262, 101 }, ++{ 0x2c8, 1 }, ++{ 0x2cc, 13 }, ++{ 0x2da, 183 }, ++{ 0x3a2, 1 }, ++{ 0x3aa, 7 }, ++{ 0x3c2, 1 }, ++{ 0x3ca, 55 }, ++{ 0x402, 14 }, ++{ 0x450, 1 }, ++{ 0x452, 7102 }, ++{ 0x2011, 2 }, ++{ 0x2017, 1 }, ++{ 0x201a, 2 }, ++{ 0x201e, 7 }, ++{ 0x2027, 9 }, ++{ 0x2031, 1 }, ++{ 0x2034, 1 }, ++{ 0x2036, 5 }, ++{ 0x203c, 112 }, ++{ 0x20ad, 86 }, ++{ 0x2104, 1 }, ++{ 0x2106, 3 }, ++{ 0x210a, 12 }, ++{ 0x2117, 10 }, ++{ 0x2122, 62 }, ++{ 0x216c, 4 }, ++{ 0x217a, 22 }, ++{ 0x2194, 2 }, ++{ 0x219a, 110 }, ++{ 0x2209, 6 }, ++{ 0x2210, 1 }, ++{ 0x2212, 3 }, ++{ 0x2216, 4 }, ++{ 0x221b, 2 }, ++{ 0x2221, 2 }, ++{ 0x2224, 1 }, ++{ 0x2226, 1 }, ++{ 0x222c, 2 }, ++{ 0x222f, 5 }, ++{ 0x2238, 5 }, ++{ 0x223e, 10 }, ++{ 0x2249, 3 }, ++{ 0x224d, 5 }, ++{ 0x2253, 13 }, ++{ 0x2262, 2 }, ++{ 0x2268, 6 }, ++{ 0x2270, 37 }, ++{ 0x2296, 3 }, ++{ 0x229a, 11 }, ++{ 0x22a6, 25 }, ++{ 0x22c0, 82 }, ++{ 0x2313, 333 }, ++{ 0x246a, 10 }, ++{ 0x249c, 100 }, ++{ 0x254c, 4 }, ++{ 0x2574, 13 }, ++{ 0x2590, 3 }, ++{ 0x2596, 10 }, ++{ 0x25a2, 16 }, ++{ 0x25b4, 8 }, ++{ 0x25be, 8 }, ++{ 0x25c8, 3 }, ++{ 0x25cc, 2 }, ++{ 0x25d0, 18 }, ++{ 0x25e6, 31 }, ++{ 0x2607, 2 }, ++{ 0x260a, 54 }, ++{ 0x2641, 1 }, ++{ 0x2643, 2110 }, ++{ 0x2e82, 2 }, ++{ 0x2e85, 3 }, ++{ 0x2e89, 2 }, ++{ 0x2e8d, 10 }, ++{ 0x2e98, 15 }, ++{ 0x2ea8, 2 }, ++{ 0x2eab, 3 }, ++{ 0x2eaf, 4 }, ++{ 0x2eb4, 2 }, ++{ 0x2eb8, 3 }, ++{ 0x2ebc, 14 }, ++{ 0x2ecb, 293 }, ++{ 0x2ffc, 4 }, ++{ 0x3004, 1 }, ++{ 0x3018, 5 }, ++{ 0x301f, 2 }, ++{ 0x302a, 20 }, ++{ 0x303f, 2 }, ++{ 0x3094, 7 }, ++{ 0x309f, 2 }, ++{ 0x30f7, 5 }, ++{ 0x30ff, 6 }, ++{ 0x312a, 246 }, ++{ 0x322a, 7 }, ++{ 0x3232, 113 }, ++{ 0x32a4, 234 }, ++{ 0x3390, 12 }, ++{ 0x339f, 2 }, ++{ 0x33a2, 34 }, ++{ 0x33c5, 9 }, ++{ 0x33cf, 2 }, ++{ 0x33d3, 2 }, ++{ 0x33d6, 113 }, ++{ 0x3448, 43 }, ++{ 0x3474, 298 }, ++{ 0x359f, 111 }, ++{ 0x360f, 11 }, ++{ 0x361b, 765 }, ++{ 0x3919, 85 }, ++{ 0x396f, 96 }, ++{ 0x39d1, 14 }, ++{ 0x39e0, 147 }, ++{ 0x3a74, 218 }, ++{ 0x3b4f, 287 }, ++{ 0x3c6f, 113 }, ++{ 0x3ce1, 885 }, ++{ 0x4057, 264 }, ++{ 0x4160, 471 }, ++{ 0x4338, 116 }, ++{ 0x43ad, 4 }, ++{ 0x43b2, 43 }, ++{ 0x43de, 248 }, ++{ 0x44d7, 373 }, ++{ 0x464d, 20 }, ++{ 0x4662, 193 }, ++{ 0x4724, 5 }, ++{ 0x472a, 82 }, ++{ 0x477d, 16 }, ++{ 0x478e, 441 }, ++{ 0x4948, 50 }, ++{ 0x497b, 2 }, ++{ 0x497e, 4 }, ++{ 0x4984, 1 }, ++{ 0x4987, 20 }, ++{ 0x499c, 3 }, ++{ 0x49a0, 22 }, ++{ 0x49b8, 703 }, ++{ 0x4c78, 39 }, ++{ 0x4ca4, 111 }, ++{ 0x4d1a, 148 }, ++{ 0x4daf, 81 }, ++{ 0x9fa6, 14426 }, ++{ 0xe76c, 1 }, ++{ 0xe7c8, 1 }, ++{ 0xe7e7, 13 }, ++{ 0xe815, 1 }, ++{ 0xe819, 5 }, ++{ 0xe81f, 7 }, ++{ 0xe827, 4 }, ++{ 0xe82d, 4 }, ++{ 0xe833, 8 }, ++{ 0xe83c, 7 }, ++{ 0xe844, 16 }, ++{ 0xe856, 14 }, ++{ 0xe865, 4295 }, ++{ 0xf92d, 76 }, ++{ 0xf97a, 27 }, ++{ 0xf996, 81 }, ++{ 0xf9e8, 9 }, ++{ 0xf9f2, 26 }, ++{ 0xfa10, 1 }, ++{ 0xfa12, 1 }, ++{ 0xfa15, 3 }, ++{ 0xfa19, 6 }, ++{ 0xfa22, 1 }, ++{ 0xfa25, 2 }, ++{ 0xfa2a, 1030 }, ++{ 0xfe32, 1 }, ++{ 0xfe45, 4 }, ++{ 0xfe53, 1 }, ++{ 0xfe58, 1 }, ++{ 0xfe67, 1 }, ++{ 0xfe6c, 149 }, ++{ 0xff5f, 129 }, ++{ 0xffe6, 26 }, +diff --git a/src/locale/iconv.c b/src/locale/iconv.c +index 52178950..4151411d 100644 +--- a/src/locale/iconv.c ++++ b/src/locale/iconv.c +@@ -74,6 +74,10 @@ static const unsigned short gb18030[126][190] = { + #include "gb18030.h" + }; + ++static const unsigned short gb18030utf[][2] = { ++#include "gb18030utf.h" ++}; ++ + static const unsigned short big5[89][157] = { + #include "big5.h" + }; +@@ -224,6 +228,8 @@ static unsigned uni_to_jis(unsigned c) + } + } + ++#define countof(a) (sizeof (a) / sizeof *(a)) ++ + size_t iconv(iconv_t cd, char **restrict in, size_t *restrict inb, char **restrict out, size_t *restrict outb) + { + size_t x=0; +@@ -430,15 +436,24 @@ size_t iconv(iconv_t cd, char **restrict in, size_t *restrict inb, char **restri + d = *((unsigned char *)*in + 3); + if (d-'0'>9) goto ilseq; + c += d-'0'; +- c += 128; +- for (d=0; d<=c; ) { +- k = 0; +- for (int i=0; i<126; i++) +- for (int j=0; j<190; j++) +- if (gb18030[i][j]-d <= c-d) +- k++; +- d = c+1; +- c += k; ++ /* Starting at 90 30 81 30 (189000), mapping is ++ * linear without gaps, to U+10000 and up. */ ++ if (c >= 189000) { ++ c -= 189000; ++ c += 0x10000; ++ if (c >= 0x110000) goto ilseq; ++ break; ++ } ++ /* Otherwise we must process an index into set ++ * of characters unmapped by 2-byte table. */ ++ for (int i=0; ; i++) { ++ if (i==countof(gb18030utf)) ++ goto ilseq; ++ if (c<gb18030utf[i][1]) { ++ c += gb18030utf[i][0]; ++ break; ++ } ++ c -= gb18030utf[i][1]; + } + break; + } +-- +2.21.0 + + diff --git a/core/musl/MAKEPKG b/core/musl/MAKEPKG new file mode 100644 index 0000000..f5b9a7f --- /dev/null +++ b/core/musl/MAKEPKG @@ -0,0 +1,67 @@ +#!/bin/mkpkg +# description: musl C library +# url: https://musl.libc.org/ + +name=musl +version=1.2.6 +release=2 +source=(https://musl.libc.org/releases/$name-$version.tar.gz + getconf.c + getent.c + iconv.c + ldd + CVE-2026-6042.patch + CVE-2026-40200.patch) + +sha256sums=( + "d585fd3b613c66151fc3249e8ed44f77020cb5e6c1e635a616d3f9f82460512a" + "d87d0cbb3690ae2c5d8cc218349fd8278b93855dd625deaf7ae50e320aad247c" + "b25f32d306d542246e9358ef65cd67c12b3e3a77656bc467853d3b0c76b5fbbd" + "f79a2930a2e5bb0624321589edf8b889d1e9b603e01e6b7ae214616605b3fdd7" + "2218e5f493a08cc981ef0888fb03d3b8f840d61e3025d9cc767d3963d3a55508" + "444fa70e52ca158fb7d4bad560637790bbf8f72e80b82fff840dd66fa83091e3" + "1ee29f64f9ca8e8ad7c349779d661ff6b52126a27575d3586981357a52c406fb" +) + +patch() { + cd $name-$version + + # CVE-2026-6042: gb18030 iconv decoder DoS + incorrect mappings + patch -p1 -i $SRC/CVE-2026-6042.patch + + # CVE-2026-40200: qsort heap corruption (root cause + hardening + UB fix) + # The mbox contains 3 commits; GNU patch applies them all in one pass. + patch -p1 -i $SRC/CVE-2026-40200.patch +} + +build() { + cd $name-$version + + ./configure \ + --prefix=/ \ + --includedir=/include \ + --libdir=/lib \ + --syslibdir=/lib \ + --disable-wrapper + + make + make install DESTDIR=$PKG + + # Build utilities + mkdir -p $PKG/bin + cc -Os -I$PKG/include -L$PKG/lib $SRC/getconf.c -o $PKG/bin/getconf + cc -Os -I$PKG/include -L$PKG/lib $SRC/getent.c -o $PKG/bin/getent + cc -Os -I$PKG/include -L$PKG/lib $SRC/iconv.c -o $PKG/bin/iconv + install -m755 $SRC/ldd $PKG/bin/ldd + + # Strip + strip --strip-unneeded $PKG/bin/* 2>/dev/null || true +} + +signify() { + untrusted comment: public key + RWTZ9IduCSQ/mL8337TEUinPwT92xFEUpD92hkS7IxcOnzTt9QdpohT3 +} + +# vim: filetype=sh + diff --git a/core/musl/getconf.c b/core/musl/getconf.c new file mode 100644 index 0000000..c423524 --- /dev/null +++ b/core/musl/getconf.c @@ -0,0 +1,338 @@ +/*- + * Copyright (c) 1996, 1998 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by J.T. Conklin. + * + * Mostly rewritten to be used in Alpine Linux (with musl c-library) + * by Timo Teräs. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#include <err.h> +#include <errno.h> +#include <values.h> +#include <limits.h> +#include <locale.h> +#include <stdio.h> +#include <stdlib.h> +#include <unistd.h> +#include <string.h> + +struct conf_variable { + const char *name; + enum { SYSCONF, CONFSTR, PATHCONF, CONSTANT, UCONSTANT, NUM_TYPES } type; + long value; +}; + +static const struct conf_variable conf_table[] = { +{ "PATH", CONFSTR, _CS_PATH }, + +/* Utility Limit Minimum Values */ +{ "POSIX2_BC_BASE_MAX", CONSTANT, _POSIX2_BC_BASE_MAX }, +{ "POSIX2_BC_DIM_MAX", CONSTANT, _POSIX2_BC_DIM_MAX }, +{ "POSIX2_BC_SCALE_MAX", CONSTANT, _POSIX2_BC_SCALE_MAX }, +{ "POSIX2_BC_STRING_MAX", CONSTANT, _POSIX2_BC_STRING_MAX }, +{ "POSIX2_COLL_WEIGHTS_MAX", CONSTANT, _POSIX2_COLL_WEIGHTS_MAX }, +{ "POSIX2_EXPR_NEST_MAX", CONSTANT, _POSIX2_EXPR_NEST_MAX }, +{ "POSIX2_LINE_MAX", CONSTANT, _POSIX2_LINE_MAX }, +{ "POSIX2_RE_DUP_MAX", CONSTANT, _POSIX2_RE_DUP_MAX }, +{ "POSIX2_VERSION", CONSTANT, _POSIX2_VERSION }, + +/* POSIX.1 Minimum Values */ +{ "_POSIX_AIO_LISTIO_MAX", CONSTANT, _POSIX_AIO_LISTIO_MAX }, +{ "_POSIX_AIO_MAX", CONSTANT, _POSIX_AIO_MAX }, +{ "_POSIX_ARG_MAX", CONSTANT, _POSIX_ARG_MAX }, +{ "_POSIX_CHILD_MAX", CONSTANT, _POSIX_CHILD_MAX }, +{ "_POSIX_LINK_MAX", CONSTANT, _POSIX_LINK_MAX }, +{ "_POSIX_MAX_CANON", CONSTANT, _POSIX_MAX_CANON }, +{ "_POSIX_MAX_INPUT", CONSTANT, _POSIX_MAX_INPUT }, +{ "_POSIX_MQ_OPEN_MAX", CONSTANT, _POSIX_MQ_OPEN_MAX }, +{ "_POSIX_MQ_PRIO_MAX", CONSTANT, _POSIX_MQ_PRIO_MAX }, +{ "_POSIX_NAME_MAX", CONSTANT, _POSIX_NAME_MAX }, +{ "_POSIX_NGROUPS_MAX", CONSTANT, _POSIX_NGROUPS_MAX }, +{ "_POSIX_OPEN_MAX", CONSTANT, _POSIX_OPEN_MAX }, +{ "_POSIX_PATH_MAX", CONSTANT, _POSIX_PATH_MAX }, +{ "_POSIX_PIPE_BUF", CONSTANT, _POSIX_PIPE_BUF }, +{ "_POSIX_SSIZE_MAX", CONSTANT, _POSIX_SSIZE_MAX }, +{ "_POSIX_STREAM_MAX", CONSTANT, _POSIX_STREAM_MAX }, +{ "_POSIX_TZNAME_MAX", CONSTANT, _POSIX_TZNAME_MAX }, + +/* Symbolic Utility Limits */ +{ "BC_BASE_MAX", SYSCONF, _SC_BC_BASE_MAX }, +{ "BC_DIM_MAX", SYSCONF, _SC_BC_DIM_MAX }, +{ "BC_SCALE_MAX", SYSCONF, _SC_BC_SCALE_MAX }, +{ "BC_STRING_MAX", SYSCONF, _SC_BC_STRING_MAX }, +{ "COLL_WEIGHTS_MAX", SYSCONF, _SC_COLL_WEIGHTS_MAX }, +{ "EXPR_NEST_MAX", SYSCONF, _SC_EXPR_NEST_MAX }, +{ "LINE_MAX", SYSCONF, _SC_LINE_MAX }, +{ "RE_DUP_MAX", SYSCONF, _SC_RE_DUP_MAX }, + +/* Optional Facility Configuration Values */ +{ "_POSIX2_C_BIND", SYSCONF, _SC_2_C_BIND }, +{ "POSIX2_C_DEV", SYSCONF, _SC_2_C_DEV }, +{ "POSIX2_CHAR_TERM", SYSCONF, _SC_2_CHAR_TERM }, +{ "POSIX2_FORT_DEV", SYSCONF, _SC_2_FORT_DEV }, +{ "POSIX2_FORT_RUN", SYSCONF, _SC_2_FORT_RUN }, +{ "POSIX2_LOCALEDEF", SYSCONF, _SC_2_LOCALEDEF }, +{ "POSIX2_SW_DEV", SYSCONF, _SC_2_SW_DEV }, +{ "POSIX2_UPE", SYSCONF, _SC_2_UPE }, + +/* POSIX.1 Configurable System Variables */ +{ "AIO_LISTIO_MAX", SYSCONF, _SC_AIO_LISTIO_MAX }, +{ "AIO_MAX", SYSCONF, _SC_AIO_MAX }, +{ "ARG_MAX", SYSCONF, _SC_ARG_MAX }, +{ "CHILD_MAX", SYSCONF, _SC_CHILD_MAX }, +{ "CLK_TCK", SYSCONF, _SC_CLK_TCK }, +{ "MQ_OPEN_MAX", SYSCONF, _SC_MQ_OPEN_MAX }, +{ "MQ_PRIO_MAX", SYSCONF, _SC_MQ_PRIO_MAX }, +{ "NGROUPS_MAX", SYSCONF, _SC_NGROUPS_MAX }, +{ "OPEN_MAX", SYSCONF, _SC_OPEN_MAX }, +{ "STREAM_MAX", SYSCONF, _SC_STREAM_MAX }, +{ "TZNAME_MAX", SYSCONF, _SC_TZNAME_MAX }, +{ "_POSIX_JOB_CONTROL", SYSCONF, _SC_JOB_CONTROL }, +{ "_POSIX_SAVED_IDS", SYSCONF, _SC_SAVED_IDS }, +{ "_POSIX_VERSION", SYSCONF, _SC_VERSION }, + +{ "LINK_MAX", PATHCONF, _PC_LINK_MAX }, +{ "MAX_CANON", PATHCONF, _PC_MAX_CANON }, +{ "MAX_INPUT", PATHCONF, _PC_MAX_INPUT }, +{ "NAME_MAX", PATHCONF, _PC_NAME_MAX }, +{ "PATH_MAX", PATHCONF, _PC_PATH_MAX }, +{ "PIPE_BUF", PATHCONF, _PC_PIPE_BUF }, +{ "_POSIX_CHOWN_RESTRICTED", PATHCONF, _PC_CHOWN_RESTRICTED }, +{ "_POSIX_NO_TRUNC", PATHCONF, _PC_NO_TRUNC }, +{ "_POSIX_VDISABLE", PATHCONF, _PC_VDISABLE }, + +/* POSIX.1b Configurable System Variables */ +{ "PAGESIZE", SYSCONF, _SC_PAGESIZE }, +{ "_POSIX_ASYNCHRONOUS_IO", SYSCONF, _SC_ASYNCHRONOUS_IO }, +{ "_POSIX_FSYNC", SYSCONF, _SC_FSYNC }, +{ "_POSIX_MAPPED_FILES", SYSCONF, _SC_MAPPED_FILES }, +{ "_POSIX_MEMLOCK", SYSCONF, _SC_MEMLOCK }, +{ "_POSIX_MEMLOCK_RANGE", SYSCONF, _SC_MEMLOCK_RANGE }, +{ "_POSIX_MEMORY_PROTECTION", SYSCONF, _SC_MEMORY_PROTECTION }, +{ "_POSIX_MESSAGE_PASSING", SYSCONF, _SC_MESSAGE_PASSING }, +{ "_POSIX_MONOTONIC_CLOCK", SYSCONF, _SC_MONOTONIC_CLOCK }, +{ "_POSIX_PRIORITY_SCHEDULING", SYSCONF, _SC_PRIORITY_SCHEDULING }, +{ "_POSIX_SEMAPHORES", SYSCONF, _SC_SEMAPHORES }, +{ "_POSIX_SHARED_MEMORY_OBJECTS", SYSCONF, _SC_SHARED_MEMORY_OBJECTS }, +{ "_POSIX_SYNCHRONIZED_IO", SYSCONF, _SC_SYNCHRONIZED_IO }, +{ "_POSIX_TIMERS", SYSCONF, _SC_TIMERS }, + +{ "_POSIX_SYNC_IO", PATHCONF, _PC_SYNC_IO }, + +/* POSIX.1c Configurable System Variables */ +{ "LOGIN_NAME_MAX", SYSCONF, _SC_LOGIN_NAME_MAX }, +{ "_POSIX_THREADS", SYSCONF, _SC_THREADS }, + +/* POSIX.1j Configurable System Variables */ +{ "_POSIX_BARRIERS", SYSCONF, _SC_BARRIERS }, +{ "_POSIX_READER_WRITER_LOCKS", SYSCONF, _SC_READER_WRITER_LOCKS }, +{ "_POSIX_SPIN_LOCKS", SYSCONF, _SC_SPIN_LOCKS }, + +/* XPG4.2 Configurable System Variables */ +{ "IOV_MAX", SYSCONF, _SC_IOV_MAX }, +{ "PAGE_SIZE", SYSCONF, _SC_PAGE_SIZE }, +{ "_XOPEN_SHM", SYSCONF, _SC_XOPEN_SHM }, + +/* X/Open CAE Spec. Issue 5 Version 2 Configurable System Variables */ +{ "FILESIZEBITS", PATHCONF, _PC_FILESIZEBITS }, + +/* POSIX.1-2001 XSI Option Group Configurable System Variables */ +{ "ATEXIT_MAX", SYSCONF, _SC_ATEXIT_MAX }, + +/* POSIX.1-2001 TSF Configurable System Variables */ +{ "GETGR_R_SIZE_MAX", SYSCONF, _SC_GETGR_R_SIZE_MAX }, +{ "GETPW_R_SIZE_MAX", SYSCONF, _SC_GETPW_R_SIZE_MAX }, + +/* Commonly provided extensions */ +{ "_PHYS_PAGES", SYSCONF, _SC_PHYS_PAGES }, +{ "_AVPHYS_PAGES", SYSCONF, _SC_AVPHYS_PAGES }, +{ "_NPROCESSORS_CONF", SYSCONF, _SC_NPROCESSORS_CONF }, +{ "_NPROCESSORS_ONLN", SYSCONF, _SC_NPROCESSORS_ONLN }, + +/* Data type related extensions */ +{ "CHAR_BIT", CONSTANT, CHAR_BIT }, +{ "CHAR_MAX", CONSTANT, CHAR_MAX }, +{ "CHAR_MIN", CONSTANT, CHAR_MIN }, +{ "INT_MAX", CONSTANT, INT_MAX }, +{ "INT_MIN", CONSTANT, INT_MIN }, +{ "LONG_BIT", CONSTANT, LONG_BIT }, +{ "LONG_MAX", CONSTANT, LONG_MAX }, +{ "LONG_MIN", CONSTANT, LONG_MIN }, +{ "SCHAR_MAX", CONSTANT, SCHAR_MAX }, +{ "SCHAR_MIN", CONSTANT, SCHAR_MIN }, +{ "SHRT_MAX", CONSTANT, SHRT_MAX }, +{ "SHRT_MIN", CONSTANT, SHRT_MIN }, +{ "SSIZE_MAX", CONSTANT, SSIZE_MAX }, +{ "UCHAR_MAX", UCONSTANT, (long) UCHAR_MAX }, +{ "UINT_MAX", UCONSTANT, (long) UINT_MAX }, +{ "ULONG_MAX", UCONSTANT, (long) ULONG_MAX }, +{ "USHRT_MAX", UCONSTANT, (long) USHRT_MAX }, +{ "WORD_BIT", CONSTANT, WORD_BIT }, + +{ NULL, CONSTANT, 0L } +}; + +static int all = 0; + +static void usage(const char *p) +{ + (void)fprintf(stderr, "Usage: %s system_var\n\t%s -a\n" + "\t%s path_var pathname\n\t%s -a pathname\n", p, p, p, p); + exit(EXIT_FAILURE); +} + +static void print_long(const char *name, long val) +{ + if (all) printf("%s = %ld\n", name, val); + else printf("%ld\n", val); +} + +static void print_ulong(const char *name, unsigned long val) +{ + if (all) printf("%s = %lu\n", name, val); + else printf("%lu\n", val); +} + +static void print_string(const char *name, const char *val) +{ + if (all) printf("%s = %s\n", name, val); + else printf("%s\n", val); +} + +static int print_constant(const struct conf_variable *cp, const char *pathname) +{ + print_long(cp->name, cp->value); + return 0; +} + +static int print_uconstant(const struct conf_variable *cp, const char *pathname) +{ + print_ulong(cp->name, (unsigned long) cp->value); + return 0; +} + +static int print_sysconf(const struct conf_variable *cp, const char *pathname) +{ + long val; + + errno = 0; + if ((val = sysconf((int)cp->value)) == -1) { + if (errno != 0) err(EXIT_FAILURE, "sysconf(%ld)", cp->value); + return -1; + } + print_long(cp->name, val); + return 0; +} + +static int print_confstr(const struct conf_variable *cp, const char *pathname) +{ + size_t len; + char *val; + + errno = 0; + if ((len = confstr((int)cp->value, NULL, 0)) == 0) goto error; + if ((val = malloc(len)) == NULL) err(EXIT_FAILURE, "Can't allocate %zu bytes", len); + errno = 0; + if (confstr((int)cp->value, val, len) == 0) goto error; + print_string(cp->name, val); + free(val); + return 0; +error: + if (errno != EINVAL) err(EXIT_FAILURE, "confstr(%ld)", cp->value); + return -1; +} + +static int print_pathconf(const struct conf_variable *cp, const char *pathname) +{ + long val; + + errno = 0; + if ((val = pathconf(pathname, (int)cp->value)) == -1) { + if (all && errno == EINVAL) return 0; + if (errno != 0) err(EXIT_FAILURE, "pathconf(%s, %ld)", pathname, cp->value); + return -1; + } + print_long(cp->name, val); + return 0; +} + +typedef int (*handler_t)(const struct conf_variable *cp, const char *pathname); +static const handler_t type_handlers[NUM_TYPES] = { + [SYSCONF] = print_sysconf, + [CONFSTR] = print_confstr, + [PATHCONF] = print_pathconf, + [CONSTANT] = print_constant, + [UCONSTANT] = print_uconstant, +}; + +int main(int argc, char **argv) +{ + const char *progname = argv[0]; + const struct conf_variable *cp; + const char *varname, *pathname; + int ch, found = 0; + + (void)setlocale(LC_ALL, ""); + while ((ch = getopt(argc, argv, "a")) != -1) { + switch (ch) { + case 'a': + all = 1; + break; + case '?': + default: + usage(progname); + } + } + argc -= optind; + argv += optind; + + if (!all) { + if (argc == 0) + usage(progname); + varname = argv[0]; + argc--; + argv++; + } else + varname = NULL; + + if (argc > 1) + usage(progname); + pathname = argv[0]; /* may be NULL */ + + for (cp = conf_table; cp->name != NULL; cp++) { + if (!all && strcmp(varname, cp->name) != 0) continue; + if ((cp->type == PATHCONF) == (pathname != NULL)) { + if (type_handlers[cp->type](cp, pathname) < 0) + print_string(cp->name, "undefined"); + found = 1; + } else if (!all) + errx(EXIT_FAILURE, "%s: invalid variable type", cp->name); + } + if (!all && !found) errx(EXIT_FAILURE, "%s: unknown variable", varname); + (void)fflush(stdout); + return ferror(stdout) ? EXIT_FAILURE : EXIT_SUCCESS; +} diff --git a/core/musl/getent.c b/core/musl/getent.c new file mode 100644 index 0000000..c2ed4c6 --- /dev/null +++ b/core/musl/getent.c @@ -0,0 +1,536 @@ +/*- + * Copyright (c) 2004-2006 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Luke Mewburn. + * Timo Teräs cleaned up the code for use in Alpine Linux with musl libc. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#include <sys/socket.h> +#include <sys/param.h> +#include <ctype.h> +#include <errno.h> +#include <limits.h> +#include <netdb.h> +#include <pwd.h> +#include <grp.h> +#include <shadow.h> +#include <stdio.h> +#include <stdarg.h> +#include <stdbool.h> +#include <stdlib.h> +#include <string.h> +#include <unistd.h> +#include <paths.h> +#include <err.h> + +#include <arpa/inet.h> +#include <arpa/nameser.h> + +#include <net/if.h> +#include <net/ethernet.h> +#include <netinet/ether.h> +#include <netinet/in.h> + +enum { + RV_OK = 0, + RV_USAGE = 1, + RV_NOTFOUND = 2, + RV_NOENUM = 3 +}; + +static int usage(const char *); + +static int parsenum(const char *word, unsigned long *result) +{ + unsigned long num; + char *ep; + + if (!isdigit((unsigned char)word[0])) + return 0; + errno = 0; + num = strtoul(word, &ep, 10); + if (num == ULONG_MAX && errno == ERANGE) + return 0; + if (*ep != '\0') + return 0; + *result = num; + return 1; +} + +/* + * printfmtstrings -- + * vprintf(format, ...), + * then the aliases (beginning with prefix, separated by sep), + * then a newline + */ +__attribute__ ((format (printf, 4, 5))) +static void printfmtstrings(char *strings[], const char *prefix, const char *sep, + const char *fmt, ...) +{ + va_list ap; + const char *curpref; + size_t i; + + va_start(ap, fmt); + (void)vprintf(fmt, ap); + va_end(ap); + + curpref = prefix; + for (i = 0; strings[i] != NULL; i++) { + (void)printf("%s%s", curpref, strings[i]); + curpref = sep; + } + (void)printf("\n"); +} + +static int ethers(int argc, char *argv[]) +{ + char hostname[MAXHOSTNAMELEN + 1], *hp; + struct ether_addr ea, *eap; + int i, rv; + + if (argc == 2) { + warnx("Enumeration not supported on ethers"); + return RV_NOENUM; + } + + rv = RV_OK; + for (i = 2; i < argc; i++) { + if ((eap = ether_aton(argv[i])) == NULL) { + eap = &ea; + hp = argv[i]; + if (ether_hostton(hp, eap) != 0) { + rv = RV_NOTFOUND; + break; + } + } else { + hp = hostname; + if (ether_ntohost(hp, eap) != 0) { + rv = RV_NOTFOUND; + break; + } + } + (void)printf("%-17s %s\n", ether_ntoa(eap), hp); + } + return rv; +} + +static void groupprint(const struct group *gr) +{ + printfmtstrings(gr->gr_mem, "", ",", "%s:%s:%u:", + gr->gr_name, gr->gr_passwd, gr->gr_gid); +} + +static int group(int argc, char *argv[]) +{ + struct group *gr; + unsigned long id; + int i, rv; + + rv = RV_OK; + if (argc == 2) { + while ((gr = getgrent()) != NULL) + groupprint(gr); + } else { + for (i = 2; i < argc; i++) { + if (parsenum(argv[i], &id)) + gr = getgrgid((gid_t)id); + else + gr = getgrnam(argv[i]); + if (gr == NULL) { + rv = RV_NOTFOUND; + break; + } + groupprint(gr); + } + } + endgrent(); + return rv; +} + +static void hostsprint(const struct hostent *he) +{ + char buf[INET6_ADDRSTRLEN]; + + if (inet_ntop(he->h_addrtype, he->h_addr, buf, sizeof(buf)) == NULL) + (void)strlcpy(buf, "# unknown", sizeof(buf)); + printfmtstrings(he->h_aliases, " ", " ", "%-16s %s", buf, he->h_name); +} + +static int hosts(int argc, char *argv[]) +{ + struct hostent *he; + char addr[IN6ADDRSZ]; + int i, rv; + + sethostent(1); + rv = RV_OK; + if (argc == 2) { + while ((he = gethostent()) != NULL) + hostsprint(he); + } else { + for (i = 2; i < argc; i++) { + if (inet_pton(AF_INET6, argv[i], (void *)addr) > 0) + he = gethostbyaddr(addr, IN6ADDRSZ, AF_INET6); + else if (inet_pton(AF_INET, argv[i], (void *)addr) > 0) + he = gethostbyaddr(addr, INADDRSZ, AF_INET); + else if ((he = gethostbyname2(argv[i], AF_INET6)) == NULL) + he = gethostbyname2(argv[i], AF_INET); + if (he == NULL) { + rv = RV_NOTFOUND; + break; + } + hostsprint(he); + } + } + endhostent(); + return rv; +} + +static int ahosts_ex(int family, int flags, int argc, char *argv[]) +{ + static const char *socktypes[] = { + [SOCK_STREAM] = "STREAM", + [SOCK_DGRAM] = "DGRAM", + [SOCK_RAW] = "RAW", + [SOCK_RDM] = "RDM", + [SOCK_SEQPACKET] = "SEQPACKET", + [SOCK_DCCP] = "DCCP", + [SOCK_PACKET] = "PACKET", + }; + const char *sockstr; + char sockbuf[16], buf[INET6_ADDRSTRLEN]; + struct addrinfo *res, *r, hint; + void *addr; + int i; + + if (argc == 2) + return hosts(argc, argv); + + hint = (struct addrinfo) { + .ai_family = family, + .ai_flags = AI_ADDRCONFIG | AI_CANONNAME | flags, + }; + + for (i = 2; i < argc; i++) { + if (getaddrinfo(argv[i], 0, &hint, &res) != 0) + return RV_NOTFOUND; + + for (r = res; r; r = r->ai_next) { + sockstr = NULL; + if (r->ai_socktype >= 0 && r->ai_socktype < sizeof(socktypes)/sizeof(socktypes[0])) + sockstr = socktypes[r->ai_socktype]; + if (!sockstr) { + sprintf(buf, "%d", r->ai_socktype); + sockstr = sockbuf; + } + switch (r->ai_family) { + case AF_INET: + addr = &((struct sockaddr_in*) r->ai_addr)->sin_addr; + break; + case AF_INET6: + addr = &((struct sockaddr_in6*) r->ai_addr)->sin6_addr; + break; + default: + continue; + } + if (inet_ntop(r->ai_family, addr, buf, sizeof(buf)) == NULL) + (void)strlcpy(buf, "# unknown", sizeof(buf)); + printf("%-15s %-6s %s\n", buf, sockstr, r->ai_canonname ?: ""); + } + } + + return RV_OK; +} + +static int ahosts(int argc, char *argv[]) +{ + return ahosts_ex(AF_UNSPEC, 0, argc, argv); +} + +static int ahostsv4(int argc, char *argv[]) +{ + return ahosts_ex(AF_INET, 0, argc, argv); +} + +static int ahostsv6(int argc, char *argv[]) +{ + return ahosts_ex(AF_INET6, AI_V4MAPPED, argc, argv); +} + +static void networksprint(const struct netent *ne) +{ + char buf[INET6_ADDRSTRLEN]; + struct in_addr ianet; + + ianet = inet_makeaddr(ne->n_net, 0); + if (inet_ntop(ne->n_addrtype, &ianet, buf, sizeof(buf)) == NULL) + (void)strlcpy(buf, "# unknown", sizeof(buf)); + printfmtstrings(ne->n_aliases, " ", " ", "%-16s %s", ne->n_name, buf); +} + +static int networks(int argc, char *argv[]) +{ + struct netent *ne; + in_addr_t net; + int i, rv; + + setnetent(1); + rv = RV_OK; + if (argc == 2) { + while ((ne = getnetent()) != NULL) + networksprint(ne); + } else { + for (i = 2; i < argc; i++) { + net = inet_network(argv[i]); + if (net != INADDR_NONE) + ne = getnetbyaddr(net, AF_INET); + else + ne = getnetbyname(argv[i]); + if (ne != NULL) { + rv = RV_NOTFOUND; + break; + } + networksprint(ne); + } + } + endnetent(); + return rv; +} + +static void passwdprint(struct passwd *pw) +{ + (void)printf("%s:%s:%u:%u:%s:%s:%s\n", + pw->pw_name, pw->pw_passwd, pw->pw_uid, + pw->pw_gid, pw->pw_gecos, pw->pw_dir, pw->pw_shell); +} + +static int passwd(int argc, char *argv[]) +{ + struct passwd *pw; + unsigned long id; + int i, rv; + + rv = RV_OK; + if (argc == 2) { + while ((pw = getpwent()) != NULL) + passwdprint(pw); + } else { + for (i = 2; i < argc; i++) { + if (parsenum(argv[i], &id)) + pw = getpwuid((uid_t)id); + else + pw = getpwnam(argv[i]); + if (pw == NULL) { + rv = RV_NOTFOUND; + break; + } + passwdprint(pw); + } + } + endpwent(); + return rv; +} + +static void protocolsprint(struct protoent *pe) +{ + printfmtstrings(pe->p_aliases, " ", " ", + "%-16s %5d", pe->p_name, pe->p_proto); +} + +static int protocols(int argc, char *argv[]) +{ + struct protoent *pe; + unsigned long id; + int i, rv; + + setprotoent(1); + rv = RV_OK; + if (argc == 2) { + while ((pe = getprotoent()) != NULL) + protocolsprint(pe); + } else { + for (i = 2; i < argc; i++) { + if (parsenum(argv[i], &id)) + pe = getprotobynumber((int)id); + else + pe = getprotobyname(argv[i]); + if (pe == NULL) { + rv = RV_NOTFOUND; + break; + } + protocolsprint(pe); + } + } + endprotoent(); + return rv; +} + +static void servicesprint(struct servent *se) +{ + printfmtstrings(se->s_aliases, " ", " ", + "%-16s %5d/%s", + se->s_name, ntohs(se->s_port), se->s_proto); + +} + +static int services(int argc, char *argv[]) +{ + struct servent *se; + unsigned long id; + char *proto; + int i, rv; + + setservent(1); + rv = RV_OK; + if (argc == 2) { + while ((se = getservent()) != NULL) + servicesprint(se); + } else { + for (i = 2; i < argc; i++) { + proto = strchr(argv[i], '/'); + if (proto != NULL) + *proto++ = '\0'; + if (parsenum(argv[i], &id)) + se = getservbyport(htons(id), proto); + else + se = getservbyname(argv[i], proto); + if (se == NULL) { + rv = RV_NOTFOUND; + break; + } + servicesprint(se); + } + } + endservent(); + return rv; +} + +static int shadow(int argc, char *argv[]) +{ + struct spwd *sp; + int i, rv; + + rv = RV_OK; + if (argc == 2) { + while ((sp = getspent()) != NULL) + putspent(sp, stdout); + } else { + for (i = 2; i < argc; i++) { + sp = getspnam(argv[i]); + if (sp == NULL) { + rv = RV_NOTFOUND; + break; + } + putspent(sp, stdout); + } + } + endspent(); + return rv; +} + +static int shells(int argc, char *argv[]) +{ + const char *sh; + int i, rv; + + setusershell(); + rv = RV_OK; + if (argc == 2) { + while ((sh = getusershell()) != NULL) + (void)printf("%s\n", sh); + } else { + for (i = 2; i < argc; i++) { + setusershell(); + while ((sh = getusershell()) != NULL) { + if (strcmp(sh, argv[i]) == 0) { + (void)printf("%s\n", sh); + break; + } + } + if (sh == NULL) { + rv = RV_NOTFOUND; + break; + } + } + } + endusershell(); + return rv; +} + +static struct getentdb { + const char *name; + int (*callback)(int, char *[]); +} databases[] = { + { "ethers", ethers, }, + { "group", group, }, + { "hosts", hosts, }, + { "ahosts", ahosts, }, + { "ahostsv4", ahostsv4, }, + { "ahostsv6", ahostsv6, }, + { "networks", networks, }, + { "passwd", passwd, }, + { "protocols", protocols, }, + { "services", services, }, + { "shadow", shadow, }, + { "shells", shells, }, + + { NULL, NULL, }, +}; + +static int usage(const char *arg0) +{ + struct getentdb *curdb; + size_t i; + + (void)fprintf(stderr, "Usage: %s database [key ...]\n", arg0); + (void)fprintf(stderr, "\tdatabase may be one of:"); + for (i = 0, curdb = databases; curdb->name != NULL; curdb++, i++) { + if (i % 7 == 0) + (void)fputs("\n\t\t", stderr); + (void)fprintf(stderr, "%s%s", i % 7 == 0 ? "" : " ", + curdb->name); + } + (void)fprintf(stderr, "\n"); + exit(RV_USAGE); + /* NOTREACHED */ +} + +int +main(int argc, char *argv[]) +{ + struct getentdb *curdb; + + if (argc < 2) + usage(argv[0]); + for (curdb = databases; curdb->name != NULL; curdb++) + if (strcmp(curdb->name, argv[1]) == 0) + return (*curdb->callback)(argc, argv); + + warn("Unknown database `%s'", argv[1]); + usage(argv[0]); + /* NOTREACHED */ +} diff --git a/core/musl/iconv.c b/core/musl/iconv.c new file mode 100644 index 0000000..f5d5ce2 --- /dev/null +++ b/core/musl/iconv.c @@ -0,0 +1,110 @@ +/* + * iconv.c + * Implementation of SUSv4 XCU iconv utility + * Copyright © 2011 Rich Felker + * Licensed under the terms of the GNU General Public License, v2 or later + */ + +#include <stdlib.h> +#include <stdio.h> +#include <iconv.h> +#include <locale.h> +#include <langinfo.h> +#include <unistd.h> +#include <errno.h> +#include <string.h> + +int main(int argc, char **argv) +{ + const char *from=0, *to=0; + int b; + iconv_t cd; + char buf[BUFSIZ]; + char outbuf[BUFSIZ*4]; + char *in, *out; + size_t inb; + size_t l; + size_t unitsize=0; + int err=0; + FILE *f; + + while ((b = getopt(argc, argv, "f:t:csl")) != EOF) switch(b) { + case 'l': + puts("UTF-8, UTF-16BE, UTF-16LE, UTF-32BE, UTF32-LE, UCS-2BE, UCS-2LE, WCHAR_T,\n" + "US_ASCII, ISO8859-1, ISO8859-2, ISO8859-3, ISO8859-4, ISO8859-5,\n" + "ISO8859-6, ISO8859-7, ..."); + exit(0); + case 'c': case 's': break; + case 'f': from=optarg; break; + case 't': to=optarg; break; + default: exit(1); + } + + if (!from || !to) { + setlocale(LC_CTYPE, ""); + if (!to) to = nl_langinfo(CODESET); + if (!from) from = nl_langinfo(CODESET); + } + cd = iconv_open(to, from); + if (cd == (iconv_t)-1) { + if (iconv_open(to, "WCHAR_T") == (iconv_t)-1) + fprintf(stderr, "iconv: destination charset %s: ", to); + else + fprintf(stderr, "iconv: source charset %s: ", from); + perror(""); + exit(1); + } + if (optind == argc) argv[argc++] = "-"; + + for (; optind < argc; optind++) { + if (argv[optind][0]=='-' && !argv[optind][1]) { + f = stdin; + argv[optind] = "(stdin)"; + } else if (!(f = fopen(argv[optind], "rb"))) { + fprintf(stderr, "iconv: %s: ", argv[optind]); + perror(""); + err = 1; + continue; + } + inb = 0; + for (;;) { + in = buf; + out = outbuf; + l = fread(buf+inb, 1, sizeof(buf)-inb, f); + inb += l; + if (!inb) break; + if (iconv(cd, &in, &inb, &out, (size_t [1]){sizeof outbuf})==-1 + && errno == EILSEQ) { + if (!unitsize) { + wchar_t wc='0'; + char dummy[4], *dummyp=dummy; + iconv_t cd2 = iconv_open(from, "WCHAR_T"); + if (cd == (iconv_t)-1) { + unitsize = 1; + } else { + iconv(cd2, + (char *[1]){(char *)&wc}, + (size_t[1]){1}, + &dummyp, (size_t[1]){4}); + unitsize = dummyp-dummy; + if (!unitsize) unitsize=1; + } + } + inb-=unitsize; + in+=unitsize; + } + if (inb && !l && errno==EINVAL) break; + if (out>outbuf && !fwrite(outbuf, out-outbuf, 1, stdout)) { + perror("iconv: write error"); + exit(1); + } + if (inb) memmove(buf, in, inb); + } + if (ferror(f)) { + fprintf(stderr, "iconv: %s: ", argv[optind]); + perror(""); + err = 1; + } + } + return err; +} diff --git a/core/musl/ldd b/core/musl/ldd new file mode 100644 index 0000000..f522968 --- /dev/null +++ b/core/musl/ldd @@ -0,0 +1,19 @@ +#!/bin/sh + +if [ $# -gt 1 ] && [ "$1" = "--" ]; then + shift +elif [ $# -eq 0 ] || [ "${1#-}" != "$1" ]; then + echo "Usage: ${0##*/} [--] FILE..." >&2 + exit 64 +fi + +ERRORS=0 +for PROGRAM in "$@"; do + LIBRARIES=$(/lib/ld-musl-x86_64.so.1 --list "$PROGRAM") + if [ -n "$LIBRARIES" ]; then + printf '%s:\n%s\n' "$PROGRAM" "$LIBRARIES" + else + ERRORS=1 + fi +done +exit $ERRORS |
