summaryrefslogtreecommitdiffstats
path: root/main/musl
diff options
context:
space:
mode:
authorTimo Teräs <timo.teras@iki.fi>2014-07-24 09:32:06 +0300
committerTimo Teräs <timo.teras@iki.fi>2014-07-24 09:38:15 +0300
commit3227b4ad816f850f655b6f44dc497926cb2cdcd1 (patch)
treec76ff993694def59c1fb7cd7bf1c3cb98d2dcaf1 /main/musl
parent8df53c5ae8153f168ffdd6ca011640777e30fff9 (diff)
downloadaports-3227b4ad816f850f655b6f44dc497926cb2cdcd1.tar.bz2
aports-3227b4ad816f850f655b6f44dc497926cb2cdcd1.tar.xz
main/musl: cherry-pick fixes, update alpine specific patches
four additional fixes from upstream git. dns patch fixed to implement ns_{put,get}* as real functions, and macro ns_msg_getflag added. netlink patch is reworked to provide alias interface names for ipv4 where appropriate, and for ipv6 link-local scope ids. few error paths have been fixed, and if_nameindex() memory allocation strategy has been improved. setxid patch added.
Diffstat (limited to 'main/musl')
-rw-r--r--main/musl/0006-make-dynamic-linker-accept-colon-as-a-separator-for-.patch28
-rw-r--r--main/musl/0007-explicitly-reject-empty-names-in-dynamic-linker-load.patch35
-rw-r--r--main/musl/0008-fix-the-m-specifier-in-syslog.patch43
-rw-r--r--main/musl/0009-fix-crash-in-regexec-for-nonzero-nmatch-argument-wit.patch27
-rw-r--r--main/musl/1001-add-basic-dns-record-parsing-functions.patch182
-rw-r--r--main/musl/1002-reimplement-if_nameindex-and-getifaddrs-using-netlin.patch433
-rw-r--r--main/musl/1003-remove-ulimit-fiddling-from-setxid.patch72
-rw-r--r--main/musl/APKBUILD34
8 files changed, 540 insertions, 314 deletions
diff --git a/main/musl/0006-make-dynamic-linker-accept-colon-as-a-separator-for-.patch b/main/musl/0006-make-dynamic-linker-accept-colon-as-a-separator-for-.patch
new file mode 100644
index 000000000..032b3cbf6
--- /dev/null
+++ b/main/musl/0006-make-dynamic-linker-accept-colon-as-a-separator-for-.patch
@@ -0,0 +1,28 @@
+From 349381aa8c0fc385e54e1068dd5f2b27af55cd12 Mon Sep 17 00:00:00 2001
+From: Rich Felker <dalias@aerifal.cx>
+Date: Fri, 11 Jul 2014 00:26:12 -0400
+Subject: [PATCH] make dynamic linker accept colon as a separator for
+ LD_PRELOAD
+
+---
+ src/ldso/dynlink.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/src/ldso/dynlink.c b/src/ldso/dynlink.c
+index 55124ff..6b7f0f3 100644
+--- a/src/ldso/dynlink.c
++++ b/src/ldso/dynlink.c
+@@ -862,8 +862,8 @@ static void load_preload(char *s)
+ int tmp;
+ char *z;
+ for (z=s; *z; s=z) {
+- for ( ; *s && isspace(*s); s++);
+- for (z=s; *z && !isspace(*z); z++);
++ for ( ; *s && (isspace(*s) || *s==':'); s++);
++ for (z=s; *z && !isspace(*z) && *z!=':'; z++);
+ tmp = *z;
+ *z = 0;
+ load_library(s, 0);
+--
+2.0.2
+
diff --git a/main/musl/0007-explicitly-reject-empty-names-in-dynamic-linker-load.patch b/main/musl/0007-explicitly-reject-empty-names-in-dynamic-linker-load.patch
new file mode 100644
index 000000000..fe6fe31da
--- /dev/null
+++ b/main/musl/0007-explicitly-reject-empty-names-in-dynamic-linker-load.patch
@@ -0,0 +1,35 @@
+From 59549313d85fa9a0168ff8164cfe734255585f46 Mon Sep 17 00:00:00 2001
+From: Rich Felker <dalias@aerifal.cx>
+Date: Fri, 11 Jul 2014 00:29:44 -0400
+Subject: [PATCH] explicitly reject empty names in dynamic linker load_library
+ function
+
+previously passing an empty string for name resulted in failure, as
+expected, but only after spurious syscalls, and it produced confusing
+errno values (and thus dlerror strings).
+
+in addition to dlopen calls, this issue affected use of LD_PRELOAD
+with trailing whitespace or colon characters.
+---
+ src/ldso/dynlink.c | 5 +++++
+ 1 file changed, 5 insertions(+)
+
+diff --git a/src/ldso/dynlink.c b/src/ldso/dynlink.c
+index 6b7f0f3..12f14f7 100644
+--- a/src/ldso/dynlink.c
++++ b/src/ldso/dynlink.c
+@@ -663,6 +663,11 @@ static struct dso *load_library(const char *name, struct dso *needed_by)
+ int n_th = 0;
+ int is_self = 0;
+
++ if (!*name) {
++ errno = EINVAL;
++ return 0;
++ }
++
+ /* Catch and block attempts to reload the implementation itself */
+ if (name[0]=='l' && name[1]=='i' && name[2]=='b') {
+ static const char *rp, reserved[] =
+--
+2.0.2
+
diff --git a/main/musl/0008-fix-the-m-specifier-in-syslog.patch b/main/musl/0008-fix-the-m-specifier-in-syslog.patch
new file mode 100644
index 000000000..acf44a9d0
--- /dev/null
+++ b/main/musl/0008-fix-the-m-specifier-in-syslog.patch
@@ -0,0 +1,43 @@
+From da27118157c2942d7652138b8d8b0056fc8f872f Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Cl=C3=A9ment=20Vasseur?= <clement.vasseur@gmail.com>
+Date: Wed, 9 Jul 2014 14:34:18 +0200
+Subject: [PATCH] fix the %m specifier in syslog
+
+errno must be saved upon vsyslog entry, otherwise its value could be
+changed by some libc function before reaching the %m handler in
+vsnprintf.
+---
+ src/misc/syslog.c | 3 +++
+ 1 file changed, 3 insertions(+)
+
+diff --git a/src/misc/syslog.c b/src/misc/syslog.c
+index 1cd61ce..57f1d75 100644
+--- a/src/misc/syslog.c
++++ b/src/misc/syslog.c
+@@ -7,6 +7,7 @@
+ #include <signal.h>
+ #include <string.h>
+ #include <pthread.h>
++#include <errno.h>
+ #include "libc.h"
+ #include "atomic.h"
+
+@@ -76,6 +77,7 @@ static void _vsyslog(int priority, const char *message, va_list ap)
+ time_t now;
+ struct tm tm;
+ char buf[256];
++ int errno_save = errno;
+ int pid;
+ int l, l2;
+
+@@ -93,6 +95,7 @@ static void _vsyslog(int priority, const char *message, va_list ap)
+ pid = (log_opt & LOG_PID) ? getpid() : 0;
+ l = snprintf(buf, sizeof buf, "<%d>%s %s%s%.0d%s: ",
+ priority, timebuf, log_ident, "["+!pid, pid, "]"+!pid);
++ errno = errno_save;
+ l2 = vsnprintf(buf+l, sizeof buf - l, message, ap);
+ if (l2 >= 0) {
+ if (l2 >= sizeof buf - l) l = sizeof buf - 1;
+--
+2.0.2
+
diff --git a/main/musl/0009-fix-crash-in-regexec-for-nonzero-nmatch-argument-wit.patch b/main/musl/0009-fix-crash-in-regexec-for-nonzero-nmatch-argument-wit.patch
new file mode 100644
index 000000000..ffef918c0
--- /dev/null
+++ b/main/musl/0009-fix-crash-in-regexec-for-nonzero-nmatch-argument-wit.patch
@@ -0,0 +1,27 @@
+From 72ed3d47e567b1635a35d3c1d174c8a8b2787e30 Mon Sep 17 00:00:00 2001
+From: Rich Felker <dalias@aerifal.cx>
+Date: Thu, 17 Jul 2014 19:56:27 -0400
+Subject: [PATCH] fix crash in regexec for nonzero nmatch argument with
+ REG_NOSUB
+
+per POSIX, the nmatch and pmatch arguments are ignored when the regex
+was compiled with REG_NOSUB.
+---
+ src/regex/regexec.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/src/regex/regexec.c b/src/regex/regexec.c
+index 855cef5..2e35b83 100644
+--- a/src/regex/regexec.c
++++ b/src/regex/regexec.c
+@@ -983,6 +983,7 @@ regexec(const regex_t *restrict preg, const char *restrict string,
+ tre_tnfa_t *tnfa = (void *)preg->TRE_REGEX_T_FIELD;
+ reg_errcode_t status;
+ int *tags = NULL, eo;
++ if (tnfa->cflags & REG_NOSUB) nmatch = 0;
+ if (tnfa->num_tags > 0 && nmatch > 0)
+ {
+ tags = xmalloc(sizeof(*tags) * tnfa->num_tags);
+--
+2.0.2
+
diff --git a/main/musl/1001-add-basic-dns-record-parsing-functions.patch b/main/musl/1001-add-basic-dns-record-parsing-functions.patch
index 32c31b47f..fcadce491 100644
--- a/main/musl/1001-add-basic-dns-record-parsing-functions.patch
+++ b/main/musl/1001-add-basic-dns-record-parsing-functions.patch
@@ -1,16 +1,16 @@
-From 33ea72845ca2f4244358a67940a5daedeced14ff Mon Sep 17 00:00:00 2001
+From 2f267b57ef0e145e397be571a000a11dc8188af2 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Timo=20Ter=C3=A4s?= <timo.teras@iki.fi>
Date: Mon, 14 Oct 2013 10:01:01 +0300
Subject: [PATCH] add basic dns record parsing functions
---
- include/arpa/nameser.h | 89 ++++++++++++++++++-------------
- src/network/ns_parse.c | 140 +++++++++++++++++++++++++++++++++++++++++++++++++
- 2 files changed, 192 insertions(+), 37 deletions(-)
+ include/arpa/nameser.h | 24 ++++++-
+ src/network/ns_parse.c | 172 +++++++++++++++++++++++++++++++++++++++++++++++++
+ 2 files changed, 195 insertions(+), 1 deletion(-)
create mode 100644 src/network/ns_parse.c
diff --git a/include/arpa/nameser.h b/include/arpa/nameser.h
-index b9ee665..1fc7339 100644
+index b9ee665..9c5f990 100644
--- a/include/arpa/nameser.h
+++ b/include/arpa/nameser.h
@@ -1,6 +1,11 @@
@@ -25,84 +25,26 @@ index b9ee665..1fc7339 100644
#include <stdint.h>
#define __NAMESER 19991006
-@@ -296,43 +301,49 @@ typedef enum __ns_cert_types {
- #define NS_OPT_DNSSEC_OK 0x8000U
- #define NS_OPT_NSID 3
+@@ -48,6 +53,8 @@ extern const struct _ns_flagdata _ns_flagdata[];
+ #define ns_msg_end(handle) ((handle)._eom + 0)
+ #define ns_msg_size(handle) ((handle)._eom - (handle)._msg)
+ #define ns_msg_count(handle, section) ((handle)._counts[section] + 0)
++#define ns_msg_getflag(handle, flag) \
++ ((handle)._flags & _ns_flagdata[flag].mask) >> _ns_flagdata[flag].shift)
+
+ typedef struct __ns_rr {
+ char name[NS_MAXDNAME];
+@@ -332,7 +339,18 @@ typedef enum __ns_cert_types {
+ (cp) += NS_INT32SZ; \
+ } while (0)
--#define NS_GET16(s, cp) do { \
-- register const unsigned char *t_cp = (const unsigned char *)(cp); \
-- (s) = ((uint16_t)t_cp[0] << 8) \
-- | ((uint16_t)t_cp[1]) \
-- ; \
-- (cp) += NS_INT16SZ; \
--} while (0)
--
--#define NS_GET32(l, cp) do { \
-- register const unsigned char *t_cp = (const unsigned char *)(cp); \
-- (l) = ((uint32_t)t_cp[0] << 24) \
-- | ((uint32_t)t_cp[1] << 16) \
-- | ((uint32_t)t_cp[2] << 8) \
-- | ((uint32_t)t_cp[3]) \
-- ; \
-- (cp) += NS_INT32SZ; \
--} while (0)
--
--#define NS_PUT16(s, cp) do { \
-- register uint16_t t_s = (uint16_t)(s); \
-- register unsigned char *t_cp = (unsigned char *)(cp); \
-- *t_cp++ = t_s >> 8; \
-- *t_cp = t_s; \
-- (cp) += NS_INT16SZ; \
--} while (0)
--
--#define NS_PUT32(l, cp) do { \
-- register uint32_t t_l = (uint32_t)(l); \
-- register unsigned char *t_cp = (unsigned char *)(cp); \
-- *t_cp++ = t_l >> 24; \
-- *t_cp++ = t_l >> 16; \
-- *t_cp++ = t_l >> 8; \
-- *t_cp = t_l; \
-- (cp) += NS_INT32SZ; \
--} while (0)
--
-
-+static __inline uint16_t ns_get16(const unsigned char *cp)
-+{
-+ return ((uint16_t)cp[0] << 8)
-+ | ((uint16_t)cp[1]);
-+}
-+
-+#define NS_GET16(s, cp) do { (s) = ns_get16(cp); (cp) += NS_INT16SZ; } while (0)
-+
-+static __inline uint32_t ns_get32(const unsigned char *cp)
-+{
-+ return ((uint32_t)cp[0] << 24)
-+ | ((uint32_t)cp[1] << 16)
-+ | ((uint32_t)cp[2] << 8)
-+ | ((uint32_t)cp[3]);
-+}
-+
-+#define NS_GET32(s, cp) do { (s) = ns_get32(cp); (cp) += NS_INT32SZ; } while (0)
-+
-+static __inline void ns_put16(uint16_t s, unsigned char *cp)
-+{
-+ cp[0] = s >> 8;
-+ cp[1] = s;
-+}
-+
-+#define NS_PUT16(s, cp) do { ns_put16(s, cp); (cp) += NS_INT16SZ; } while (0)
-+
-+static __inline void ns_put32(uint32_t l, unsigned char *cp)
-+{
-+ cp[0] = l >> 24;
-+ cp[1] = l >> 16;
-+ cp[2] = l >> 8;
-+ cp[3] = l;
-+}
-+
-+#define NS_PUT32(s, cp) do { ns_put32(s, cp); (cp) += NS_INT32SZ; } while (0)
-+
+#if defined(_GNU_SOURCE) || defined(_BSD_SOURCE)
++u_int ns_get16(const unsigned char *cp);
++u_long ns_get32(const unsigned char *cp);
++void ns_put16(u_int s, unsigned char *cp);
++void ns_put32(u_long l, unsigned char *cp);
++
+int ns_initparse(const u_char *msg, int msglen, ns_msg *handle);
+int ns_parserr(ns_msg *handle, ns_sect section, int rrnum, ns_rr *rr);
+int ns_skiprr(const u_char *msg, const u_char *eom, ns_sect section, int count);
@@ -112,7 +54,7 @@ index b9ee665..1fc7339 100644
#define __BIND 19950621
-@@ -464,4 +475,8 @@ typedef struct {
+@@ -464,4 +482,8 @@ typedef struct {
#define PUTSHORT NS_PUT16
#define PUTLONG NS_PUT32
@@ -123,29 +65,69 @@ index b9ee665..1fc7339 100644
#endif
diff --git a/src/network/ns_parse.c b/src/network/ns_parse.c
new file mode 100644
-index 0000000..5ef0d90
+index 0000000..7e40237
--- /dev/null
+++ b/src/network/ns_parse.c
-@@ -0,0 +1,140 @@
+@@ -0,0 +1,172 @@
+#define _BSD_SOURCE
+#include <errno.h>
+#include <stddef.h>
+#include <resolv.h>
+#include <arpa/nameser.h>
+
++const struct _ns_flagdata _ns_flagdata[16] = {
++ { 0x8000, 15 },
++ { 0x7800, 11 },
++ { 0x0400, 10 },
++ { 0x0200, 9 },
++ { 0x0100, 8 },
++ { 0x0080, 7 },
++ { 0x0040, 6 },
++ { 0x0020, 5 },
++ { 0x0010, 4 },
++ { 0x000f, 0 },
++ { 0x0000, 0 },
++ { 0x0000, 0 },
++ { 0x0000, 0 },
++ { 0x0000, 0 },
++ { 0x0000, 0 },
++ { 0x0000, 0 },
++};
++
++u_int ns_get16(const unsigned char *cp)
++{
++ u_short s;
++ NS_GET16(s, cp);
++ return s;
++}
++
++u_long ns_get32(const unsigned char *cp)
++{
++ u_long l;
++ NS_GET32(l, cp);
++ return l;
++}
++
++void ns_put16(u_int s, unsigned char *cp)
++{
++ NS_PUT16(s, cp);
++}
++
++void ns_put32(u_long l, unsigned char *cp)
++{
++ NS_PUT32(l, cp);
++}
++
+int ns_initparse(const unsigned char *msg, int msglen, ns_msg *handle)
+{
+ int i, r;
+
+ handle->_msg = msg;
+ handle->_eom = msg + msglen;
-+ if (msglen < (2 + ns_s_max) * NS_INT16SZ)
-+ goto bad;
-+
++ if (msglen < (2 + ns_s_max) * NS_INT16SZ) goto bad;
+ NS_GET16(handle->_id, msg);
+ NS_GET16(handle->_flags, msg);
-+ for (i = 0; i < ns_s_max; i++)
-+ NS_GET16(handle->_counts[i], msg);
++ for (i = 0; i < ns_s_max; i++) NS_GET16(handle->_counts[i], msg);
+ for (i = 0; i < ns_s_max; i++) {
+ if (handle->_counts[i]) {
+ handle->_sections[i] = msg;
@@ -156,9 +138,7 @@ index 0000000..5ef0d90
+ handle->_sections[i] = NULL;
+ }
+ }
-+ if (msg != handle->_eom)
-+ goto bad;
-+
++ if (msg != handle->_eom) goto bad;
+ handle->_sect = ns_s_max;
+ handle->_rrnum = -1;
+ handle->_msg_ptr = NULL;
@@ -195,17 +175,14 @@ index 0000000..5ef0d90
+{
+ int r;
+
-+ if (section < 0 || section >= ns_s_max)
-+ goto bad;
++ if (section < 0 || section >= ns_s_max) goto bad;
+ if (section != handle->_sect) {
+ handle->_sect = section;
+ handle->_rrnum = 0;
+ handle->_msg_ptr = handle->_sections[section];
+ }
-+ if (rrnum == -1)
-+ rrnum = handle->_rrnum;
-+ if (rrnum < 0 || rrnum >= handle->_counts[section])
-+ goto bad;
++ if (rrnum == -1) rrnum = handle->_rrnum;
++ if (rrnum < 0 || rrnum >= handle->_counts[section]) goto bad;
+ if (rrnum < handle->_rrnum) {
+ handle->_rrnum = 0;
+ handle->_msg_ptr = handle->_sections[section];
@@ -219,17 +196,14 @@ index 0000000..5ef0d90
+ r = dn_expand(handle->_msg, handle->_eom, handle->_msg_ptr, rr->name, NS_MAXDNAME);
+ if (r < 0) return -1;
+ handle->_msg_ptr += r;
-+ if (handle->_msg_ptr + 2 * NS_INT16SZ > handle->_eom)
-+ goto size;
++ if (handle->_msg_ptr + 2 * NS_INT16SZ > handle->_eom) goto size;
+ NS_GET16(rr->type, handle->_msg_ptr);
+ NS_GET16(rr->rr_class, handle->_msg_ptr);
+ if (section != ns_s_qd) {
-+ if (handle->_msg_ptr + NS_INT32SZ + NS_INT16SZ > handle->_eom)
-+ goto size;
++ if (handle->_msg_ptr + NS_INT32SZ + NS_INT16SZ > handle->_eom) goto size;
+ NS_GET32(rr->ttl, handle->_msg_ptr);
+ NS_GET16(rr->rdlength, handle->_msg_ptr);
-+ if (handle->_msg_ptr + rr->rdlength > handle->_eom)
-+ goto size;
++ if (handle->_msg_ptr + rr->rdlength > handle->_eom) goto size;
+ rr->rdata = handle->_msg_ptr;
+ handle->_msg_ptr += rr->rdlength;
+ } else {
@@ -268,5 +242,5 @@ index 0000000..5ef0d90
+}
+
--
-1.8.5.1
+2.0.2
diff --git a/main/musl/1002-reimplement-if_nameindex-and-getifaddrs-using-netlin.patch b/main/musl/1002-reimplement-if_nameindex-and-getifaddrs-using-netlin.patch
index f8df5dc39..909b5b26c 100644
--- a/main/musl/1002-reimplement-if_nameindex-and-getifaddrs-using-netlin.patch
+++ b/main/musl/1002-reimplement-if_nameindex-and-getifaddrs-using-netlin.patch
@@ -1,29 +1,30 @@
-From c3d5cce5c550896fd8e9cf856f66f5f264b49ef7 Mon Sep 17 00:00:00 2001
+From 2ab2413e746a5b0e6996eeb7bc10739207b0b560 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Timo=20Ter=C3=A4s?= <timo.teras@iki.fi>
Date: Tue, 8 Apr 2014 14:03:16 +0000
Subject: [PATCH] reimplement if_nameindex and getifaddrs using netlink
---
- src/network/__netlink.c | 38 ++++++
- src/network/__netlink.h | 99 ++++++++++++++
- src/network/getifaddrs.c | 325 +++++++++++++++++++++++++--------------------
- src/network/if_nameindex.c | 107 +++++++++------
- 4 files changed, 382 insertions(+), 187 deletions(-)
+ src/network/__netlink.c | 52 ++++++++
+ src/network/__netlink.h | 100 +++++++++++++++
+ src/network/getifaddrs.c | 312 ++++++++++++++++++++++++---------------------
+ src/network/if_nameindex.c | 130 +++++++++++++------
+ 4 files changed, 409 insertions(+), 185 deletions(-)
create mode 100644 src/network/__netlink.c
create mode 100644 src/network/__netlink.h
diff --git a/src/network/__netlink.c b/src/network/__netlink.c
new file mode 100644
-index 0000000..e75f374
+index 0000000..d02714c
--- /dev/null
+++ b/src/network/__netlink.c
-@@ -0,0 +1,38 @@
+@@ -0,0 +1,52 @@
+#include <errno.h>
+#include <string.h>
++#include <syscall.h>
+#include <sys/socket.h>
+#include "__netlink.h"
+
-+int __netlink_enumerate(int fd, unsigned int seq, int type, int af,
++static int __netlink_enumerate(int fd, unsigned int seq, int type, int af,
+ int (*cb)(void *ctx, struct nlmsghdr *h), void *ctx)
+{
+ struct nlmsghdr *h;
@@ -35,12 +36,12 @@ index 0000000..e75f374
+ } req;
+ struct nlmsghdr reply;
+ } u;
-+ int r, ret = 0;
++ int r, ret;
+
+ memset(&u.req, 0, sizeof(u.req));
+ u.req.nlh.nlmsg_len = sizeof(u.req);
+ u.req.nlh.nlmsg_type = type;
-+ u.req.nlh.nlmsg_flags = NLM_F_ROOT | NLM_F_MATCH | NLM_F_REQUEST;
++ u.req.nlh.nlmsg_flags = NLM_F_DUMP | NLM_F_REQUEST;
+ u.req.nlh.nlmsg_seq = seq;
+ u.req.g.rtgen_family = af;
+ r = send(fd, &u.req, sizeof(u.req), 0);
@@ -50,18 +51,31 @@ index 0000000..e75f374
+ r = recv(fd, u.buf, sizeof(u.buf), MSG_DONTWAIT);
+ if (r <= 0) return -1;
+ for (h = &u.reply; NLMSG_OK(h, (void*)&u.buf[r]); h = NLMSG_NEXT(h)) {
-+ if (h->nlmsg_type == NLMSG_DONE) return ret;
++ if (h->nlmsg_type == NLMSG_DONE) return 0;
+ if (h->nlmsg_type == NLMSG_ERROR) return -1;
-+ if (!ret) ret = cb(ctx, h);
++ ret = cb(ctx, h);
++ if (ret) return ret;
+ }
+ }
+}
++
++int __rtnetlink_enumerate(int link_af, int addr_af, int (*cb)(void *ctx, struct nlmsghdr *h), void *ctx)
++{
++ int fd, r;
++
++ fd = socket(PF_NETLINK, SOCK_RAW|SOCK_CLOEXEC, NETLINK_ROUTE);
++ if (fd < 0) return -1;
++ r = __netlink_enumerate(fd, 1, RTM_GETLINK, link_af, cb, ctx);
++ if (!r) r = __netlink_enumerate(fd, 2, RTM_GETADDR, addr_af, cb, ctx);
++ __syscall(SYS_close,fd);
++ return r;
++}
diff --git a/src/network/__netlink.h b/src/network/__netlink.h
new file mode 100644
-index 0000000..40b12a2
+index 0000000..2476da1
--- /dev/null
+++ b/src/network/__netlink.h
-@@ -0,0 +1,99 @@
+@@ -0,0 +1,100 @@
+#include <stdint.h>
+
+/* linux/netlink.h */
@@ -79,8 +93,6 @@ index 0000000..40b12a2
+#define NLM_F_REQUEST 1
+#define NLM_F_MULTI 2
+#define NLM_F_ACK 4
-+#define NLM_F_ECHO 8
-+#define NLM_F_DUMP_INTR 16
+
+#define NLM_F_ROOT 0x100
+#define NLM_F_MATCH 0x200
@@ -94,7 +106,9 @@ index 0000000..40b12a2
+
+/* linux/rtnetlink.h */
+
++#define RTM_NEWLINK 16
+#define RTM_GETLINK 18
++#define RTM_NEWADDR 20
+#define RTM_GETADDR 22
+
+struct rtattr {
@@ -159,13 +173,14 @@ index 0000000..40b12a2
+#define NLMSG_RTA(nlh,len) ((void*)((char*)(nlh)+sizeof(struct nlmsghdr)+NETLINK_ALIGN(len)))
+#define NLMSG_RTAOK(rta,nlh) RTA_OK(rta,NLMSG_DATAEND(nlh))
+
-+int __netlink_enumerate(int fd, unsigned int seq, int type, int af,
-+ int (*cb)(void *ctx, struct nlmsghdr *h), void *ctx);
++#define IFADDRS_HASH_SIZE 64
++
++int __rtnetlink_enumerate(int link_af, int addr_af, int (*cb)(void *ctx, struct nlmsghdr *h), void *ctx);
diff --git a/src/network/getifaddrs.c b/src/network/getifaddrs.c
-index 5a94cc7..9d4bd5b 100644
+index 5a94cc7..18fc710 100644
--- a/src/network/getifaddrs.c
+++ b/src/network/getifaddrs.c
-@@ -1,181 +1,212 @@
+@@ -1,181 +1,201 @@
-/* (C) 2013 John Spencer. released under musl's standard MIT license. */
-#undef _GNU_SOURCE
#define _GNU_SOURCE
@@ -185,6 +200,7 @@ index 5a94cc7..9d4bd5b 100644
+#include <ifaddrs.h>
+#include <syscall.h>
+#include <net/if.h>
++#include <netinet/in.h>
+#include "__netlink.h"
-typedef union {
@@ -224,7 +240,6 @@ index 5a94cc7..9d4bd5b 100644
+};
-static stor* list_add(stor** list, stor** head, char* ifname)
-+#define IFADDRS_HASH_SIZE 64
+struct ifaddrs_ctx {
+ struct ifaddrs_storage *first;
+ struct ifaddrs_storage *last;
@@ -250,35 +265,38 @@ index 5a94cc7..9d4bd5b 100644
}
-void freeifaddrs(struct ifaddrs *ifp)
-+static void addifaddrs(struct ifaddrs_ctx *ctx, struct ifaddrs_storage *add)
++static void copy_addr(struct sockaddr **r, int af, union sockany *sa, void *addr, size_t addrlen, int ifindex)
{
- stor *head = (stor *) ifp;
- while(head) {
- void *p = head;
- head = (stor *) head->next;
- free(p);
-+ if (!add->ifa.ifa_name) {
-+ free(add);
++ uint8_t *dst;
++ int len;
++
++ switch (af) {
++ case AF_INET:
++ dst = (uint8_t*) &sa->v4.sin_addr;
++ len = 4;
++ break;
++ case AF_INET6:
++ dst = (uint8_t*) &sa->v6.sin6_addr;
++ len = 16;
++ if (IN6_IS_ADDR_LINKLOCAL(addr) || IN6_IS_ADDR_MC_LINKLOCAL(addr))
++ sa->v6.sin6_scope_id = ifindex;
++ break;
++ default:
+ return;
}
-+ if (!ctx->first) ctx->first = add;
-+ if (ctx->last) ctx->last->ifa.ifa_next = &add->ifa;
-+ ctx->last = add;
-+}
-+
-+static struct sockaddr* copy_lladdr(union sockany *sa, struct rtattr *rta, struct ifinfomsg *ifi)
-+{
-+ if (RTA_DATALEN(rta) > sizeof(sa->ll.sll_addr)) return 0;
-+ sa->ll.sll_family = AF_PACKET;
-+ sa->ll.sll_ifindex = ifi->ifi_index;
-+ sa->ll.sll_hatype = ifi->ifi_type;
-+ sa->ll.sll_halen = RTA_DATALEN(rta);
-+ memcpy(sa->ll.sll_addr, RTA_DATA(rta), RTA_DATALEN(rta));
-+ return &sa->sa;
++ if (addrlen < len) return;
++ sa->sa.sa_family = af;
++ memcpy(dst, addr, len);
++ *r = &sa->sa;
}
-static void ipv6netmask(unsigned prefix_length, struct sockaddr_in6 *sa)
-+static uint8_t *sockany_addr(int af, union sockany *sa, int *len)
++static void gen_netmask(struct sockaddr **r, int af, union sockany *sa, int prefixlen)
{
- unsigned char* hb = sa->sin6_addr.s6_addr;
- unsigned onebytes = prefix_length / 8;
@@ -290,15 +308,19 @@ index 5a94cc7..9d4bd5b 100644
- unsigned char x = -1;
- x <<= 8 - bits;
- hb[onebytes] = x;
-+ switch (af) {
-+ case AF_INET: *len = 4; return (uint8_t*) &sa->v4.sin_addr;
-+ case AF_INET6: *len = 16; return (uint8_t*) &sa->v6.sin6_addr;
- }
-+ return 0;
+- }
++ uint8_t addr[16] = {0};
++ int i;
++
++ if (prefixlen > 8*sizeof(addr)) prefixlen = 8*sizeof(addr);
++ i = prefixlen / 8;
++ memset(addr, 0xff, i);
++ if (i < sizeof(addr)) addr[i++] = 0xff << (8 - (prefixlen % 8));
++ copy_addr(r, af, sa, addr, sizeof(addr), 0);
}
-static void dealwithipv6(stor **list, stor** head)
-+static struct sockaddr* copy_addr(int af, union sockany *sa, struct rtattr *rta)
++static void copy_lladdr(struct sockaddr **r, union sockany *sa, void *addr, size_t addrlen, int ifindex, unsigned short hatype)
{
- FILE* f = fopen("/proc/net/if_inet6", "rbe");
- /* 00000000000000000000000000000001 01 80 10 80 lo
@@ -341,34 +363,20 @@ index 5a94cc7..9d4bd5b 100644
- else curr->ifa.ifa_flags = 0;
- } else errno = 0;
- }
-+ int len;
-+ uint8_t *dst = sockany_addr(af, sa, &len);
-+ if (!dst || RTA_DATALEN(rta) != len) return 0;
-+ sa->sa.sa_family = af;
-+ memcpy(dst, RTA_DATA(rta), len);
-+ return &sa->sa;
-+}
-+
-+static struct sockaddr *gen_netmask(int af, union sockany *sa, int prefixlen)
-+{
-+ int maxlen, i;
-+ uint8_t *dst = sockany_addr(af, sa, &maxlen);
-+ if (!dst) return 0;
-+ sa->sa.sa_family = af;
-+ if (prefixlen > 8*maxlen) prefixlen = 8*maxlen;
-+ i = prefixlen / 8;
-+ memset(dst, 0xff, i);
-+ if (i<maxlen) {
-+ dst[i++] = 0xff << (8 - (prefixlen % 8));
-+ if (i<maxlen) memset(&dst[i+1], 0x00, maxlen-i);
- }
+- }
- out:
- fclose(f);
-+ return &sa->sa;
++ if (addrlen > sizeof(sa->ll.sll_addr)) return;
++ sa->ll.sll_family = AF_PACKET;
++ sa->ll.sll_ifindex = ifindex;
++ sa->ll.sll_hatype = hatype;
++ sa->ll.sll_halen = addrlen;
++ memcpy(sa->ll.sll_addr, addr, addrlen);
++ *r = &sa->sa;
}
-int getifaddrs(struct ifaddrs **ifap)
-+static int __handle_link(void *pctx, struct nlmsghdr *h)
++static int __handle(void *pctx, struct nlmsghdr *h)
{
- stor *list = 0, *head = 0;
- struct if_nameindex* ii = if_nameindex();
@@ -379,17 +387,24 @@ index 5a94cc7..9d4bd5b 100644
- if(!curr) {
- if_freenameindex(ii);
- goto err2;
-- }
+ struct ifaddrs_ctx *ctx = pctx;
-+ struct ifaddrs_storage *ifs;
++ struct ifaddrs_storage *ifs, *ifs0;
+ struct ifinfomsg *ifi = NLMSG_DATA(h);
++ struct ifaddrmsg *ifa = NLMSG_DATA(h);
+ struct rtattr *rta;
+ int stats_len = 0;
+
-+ for (rta = NLMSG_RTA(h, sizeof(*ifi)); NLMSG_RTAOK(rta, h); rta = RTA_NEXT(rta)) {
-+ if (rta->rta_type != IFLA_STATS) continue;
-+ stats_len = RTA_DATALEN(rta);
-+ break;
++ if (h->nlmsg_type == RTM_NEWLINK) {
++ for (rta = NLMSG_RTA(h, sizeof(*ifi)); NLMSG_RTAOK(rta, h); rta = RTA_NEXT(rta)) {
++ if (rta->rta_type != IFLA_STATS) continue;
++ stats_len = RTA_DATALEN(rta);
++ break;
+ }
++ } else {
++ for (ifs0 = ctx->hash[ifa->ifa_index % IFADDRS_HASH_SIZE]; ifs0; ifs0 = ifs0->hash_next)
++ if (ifs0->index == ifa->ifa_index)
++ break;
++ if (!ifs0) return 0;
}
- if_freenameindex(ii);
-
@@ -405,32 +420,33 @@ index 5a94cc7..9d4bd5b 100644
- if(!strcmp(reqs[i].ifr_name, head->name)) {
- head->addr.v4 = *(struct sockaddr_in*)&reqs[i].ifr_addr;
- head->ifa.ifa_addr = (struct sockaddr*) &head->addr;
-- break;
+
+ ifs = calloc(1, sizeof(struct ifaddrs_storage) + stats_len);
+ if (ifs == 0) return -1;
+
-+ ifs->index = ifi->ifi_index;
-+ ifs->ifa.ifa_flags = ifi->ifi_flags;
-+
-+ for (rta = NLMSG_RTA(h, sizeof(*ifi)); NLMSG_RTAOK(rta, h); rta = RTA_NEXT(rta)) {
-+ switch (rta->rta_type) {
-+ case IFLA_IFNAME:
-+ if (RTA_DATALEN(rta) <= IFNAMSIZ) {
-+ strncpy(ifs->name, RTA_DATA(rta), RTA_DATALEN(rta));
-+ ifs->ifa.ifa_name = ifs->name;
++ if (h->nlmsg_type == RTM_NEWLINK) {
++ ifs->index = ifi->ifi_index;
++ ifs->ifa.ifa_flags = ifi->ifi_flags;
++
++ for (rta = NLMSG_RTA(h, sizeof(*ifi)); NLMSG_RTAOK(rta, h); rta = RTA_NEXT(rta)) {
++ switch (rta->rta_type) {
++ case IFLA_IFNAME:
++ if (RTA_DATALEN(rta) < sizeof(ifs->name)) {
++ memcpy(ifs->name, RTA_DATA(rta), RTA_DATALEN(rta));
++ ifs->ifa.ifa_name = ifs->name;
++ }
++ break;
++ case IFLA_ADDRESS:
++ copy_lladdr(&ifs->ifa.ifa_addr, &ifs->addr, RTA_DATA(rta), RTA_DATALEN(rta), ifi->ifi_index, ifi->ifi_type);
++ break;
++ case IFLA_BROADCAST:
++ copy_lladdr(&ifs->ifa.ifa_broadaddr, &ifs->ifu, RTA_DATA(rta), RTA_DATALEN(rta), ifi->ifi_index, ifi->ifi_type);
++ break;
++ case IFLA_STATS:
++ ifs->ifa.ifa_data = (void*)(ifs+1);
++ memcpy(ifs->ifa.ifa_data, RTA_DATA(rta), RTA_DATALEN(rta));
+ break;
}
-+ break;
-+ case IFLA_ADDRESS:
-+ ifs->ifa.ifa_addr = copy_lladdr(&ifs->addr, rta, ifi);
-+ break;
-+ case IFLA_BROADCAST:
-+ ifs->ifa.ifa_broadaddr = copy_lladdr(&ifs->ifu, rta, ifi);
-+ break;
-+ case IFLA_STATS:
-+ ifs->ifa.ifa_data = (void*)(ifs+1);
-+ memcpy(ifs->ifa.ifa_data, RTA_DATA(rta), RTA_DATALEN(rta));
-+ break;
}
- struct ifreq req;
- snprintf(req.ifr_name, sizeof req.ifr_name, "%s", head->name);
@@ -450,47 +466,43 @@ index 5a94cc7..9d4bd5b 100644
- } else {
- if(-1 == ioctl(sock, SIOCGIFBRDADDR, &req)) goto err;
- head->dst.v4 = *(struct sockaddr_in*)&req.ifr_broadaddr;
-- }
++ if (ifs->ifa.ifa_name) {
++ unsigned int bucket = ifs->index % IFADDRS_HASH_SIZE;
++ ifs->hash_next = ctx->hash[bucket];
++ ctx->hash[bucket] = ifs;
++ }
++ } else {
++ ifs->ifa.ifa_name = ifs0->ifa.ifa_name;
++ ifs->ifa.ifa_flags = ifs0->ifa.ifa_flags;
++ for (rta = NLMSG_RTA(h, sizeof(*ifa)); NLMSG_RTAOK(rta, h); rta = RTA_NEXT(rta)) {
++ switch (rta->rta_type) {
++ case IFA_ADDRESS:
++ copy_addr(&ifs->ifa.ifa_addr, ifa->ifa_family, &ifs->addr, RTA_DATA(rta), RTA_DATALEN(rta), ifa->ifa_index);
++ break;
++ case IFA_BROADCAST:
++ /* For point-to-point links this is peer, but ifa_broadaddr
++ * and ifa_dstaddr are union, so this works for both. */
++ copy_addr(&ifs->ifa.ifa_broadaddr, ifa->ifa_family, &ifs->ifu, RTA_DATA(rta), RTA_DATALEN(rta), ifa->ifa_index);
++ break;
++ case IFA_LABEL:
++ if (RTA_DATALEN(rta) < sizeof(ifs->name)) {
++ memcpy(ifs->name, RTA_DATA(rta), RTA_DATALEN(rta));
++ ifs->ifa.ifa_name = ifs->name;
++ }
++ break;
+ }
- head->ifa.ifa_ifu.ifu_dstaddr = (struct sockaddr*) &head->dst;
+ }
++ if (ifs->ifa.ifa_addr)
++ gen_netmask(&ifs->ifa.ifa_netmask, ifa->ifa_family, &ifs->netmask, ifa->ifa_prefixlen);
+ }
-+ if (ifs->ifa.ifa_name) {
-+ ifs->hash_next = ctx->hash[ifs->index%IFADDRS_HASH_SIZE];
-+ ctx->hash[ifs->index%IFADDRS_HASH_SIZE] = ifs;
-+ }
-+ addifaddrs(ctx, ifs);
-+ return 0;
-+}
+
-+static int __handle_addr(void *pctx, struct nlmsghdr *h)
-+{
-+ struct ifaddrs_ctx *ctx = pctx;
-+ struct ifaddrs_storage *ifs, *ifs0;
-+ struct ifaddrmsg *ifa = NLMSG_DATA(h);
-+ struct rtattr *rta;
-+
-+ ifs = calloc(1, sizeof(struct ifaddrs_storage));
-+ if (ifs == 0) return -1;
-+
-+ for (ifs0 = ctx->hash[ifa->ifa_index%IFADDRS_HASH_SIZE]; ifs0; ifs0 = ifs0->hash_next)
-+ if (ifs0->index == ifa->ifa_index)
-+ break;
-+ if (!ifs0) return 0;
-+
-+ ifs->ifa.ifa_name = ifs0->ifa.ifa_name;
-+ ifs->ifa.ifa_flags = ifs0->ifa.ifa_flags;
-+ for (rta = NLMSG_RTA(h, sizeof(*ifa)); NLMSG_RTAOK(rta, h); rta = RTA_NEXT(rta)) {
-+ switch (rta->rta_type) {
-+ case IFA_ADDRESS:
-+ ifs->ifa.ifa_addr = copy_addr(ifa->ifa_family, &ifs->addr, rta);
-+ if (ifs->ifa.ifa_addr)
-+ ifs->ifa.ifa_netmask = gen_netmask(ifa->ifa_family, &ifs->netmask, ifa->ifa_prefixlen);
-+ break;
-+ case IFA_BROADCAST:
-+ /* For point-to-point links this is peer, but ifa_broadaddr
-+ * and ifa_dstaddr are union, so this works for both. */
-+ ifs->ifa.ifa_broadaddr = copy_addr(ifa->ifa_family, &ifs->ifu, rta);
-+ break;
- }
++ if (ifs->ifa.ifa_name) {
++ if (!ctx->first) ctx->first = ifs;
++ if (ctx->last) ctx->last->ifa.ifa_next = &ifs->ifa;
++ ctx->last = ifs;
++ } else {
++ free(ifs);
}
- close(sock);
- void* last = 0;
@@ -498,8 +510,6 @@ index 5a94cc7..9d4bd5b 100644
- head = last;
- dealwithipv6(&list, &head);
- *ifap = (struct ifaddrs*) list;
-+
-+ addifaddrs(ctx, ifs);
return 0;
- err:
- close(sock);
@@ -511,60 +521,50 @@ index 5a94cc7..9d4bd5b 100644
+int getifaddrs(struct ifaddrs **ifap)
+{
+ struct ifaddrs_ctx _ctx, *ctx = &_ctx;
-+ int r = 0, fd;
-+
-+ fd = socket(PF_NETLINK, SOCK_RAW|SOCK_CLOEXEC, NETLINK_ROUTE);
-+ if (fd < 0) return -1;
-+
-+ memset(ctx, 0, sizeof(*ctx));
-+ if (__netlink_enumerate(fd, 1, RTM_GETLINK, AF_UNSPEC, __handle_link, ctx)) r = -1;
-+ if (__netlink_enumerate(fd, 1, RTM_GETADDR, AF_UNSPEC, __handle_addr, ctx)) r = -1;
-+ __syscall(SYS_close,fd);
-+
++ int r;
++ memset(ctx, 0, sizeof *ctx);
++ r = __rtnetlink_enumerate(AF_UNSPEC, AF_UNSPEC, __handle, ctx);
+ if (r == 0) *ifap = &ctx->first->ifa;
+ else freeifaddrs(&ctx->first->ifa);
+ return r;
+}
diff --git a/src/network/if_nameindex.c b/src/network/if_nameindex.c
-index 53b80b2..cb5587c 100644
+index 53b80b2..2ad7474 100644
--- a/src/network/if_nameindex.c
+++ b/src/network/if_nameindex.c
-@@ -1,55 +1,82 @@
+@@ -1,55 +1,107 @@
#define _GNU_SOURCE
#include <net/if.h>
-#include <stdlib.h>
- #include <sys/socket.h>
+-#include <sys/socket.h>
-#include <sys/ioctl.h>
#include <errno.h>
-#include "syscall.h"
+#include <unistd.h>
+#include <stdlib.h>
+#include <string.h>
-+#include <syscall.h>
+#include "__netlink.h"
-+
+
+-static void *do_nameindex(int s, size_t n)
+-{
+- size_t i, len, k;
+- struct ifconf conf;
+- struct if_nameindex *idx;
+struct ifnamemap {
++ unsigned int hash_next;
+ unsigned int index;
+ unsigned char namelen;
+ char name[IFNAMSIZ];
+};
-+
+
+- idx = malloc(n * (sizeof(struct if_nameindex)+sizeof(struct ifreq)));
+- if (!idx) return 0;
+struct ifnameindexctx {
-+ unsigned int num;
-+ unsigned int str_bytes;
++ unsigned int num, allocated, str_bytes;
+ struct ifnamemap *list;
++ unsigned int hash[IFADDRS_HASH_SIZE];
+};
--static void *do_nameindex(int s, size_t n)
-+static int __handle_link(void *pctx, struct nlmsghdr *h)
- {
-- size_t i, len, k;
-- struct ifconf conf;
-- struct if_nameindex *idx;
--
-- idx = malloc(n * (sizeof(struct if_nameindex)+sizeof(struct ifreq)));
-- if (!idx) return 0;
--
- conf.ifc_buf = (void *)&idx[n];
- conf.ifc_len = len = n * sizeof(struct ifreq);
- if (ioctl(s, SIOCGIFCONF, &conf) < 0) {
@@ -574,39 +574,72 @@ index 53b80b2..cb5587c 100644
- if (conf.ifc_len == len) {
- free(idx);
- return (void *)-1;
-- }
++static int __handle(void *pctx, struct nlmsghdr *h)
++{
+ struct ifnameindexctx *ctx = pctx;
-+ struct ifinfomsg *ifim = NLMSG_DATA(h);
++ struct ifnamemap *map;
+ struct rtattr *rta;
-+ struct ifnamemap *e;
++ unsigned int i;
++ int index, type, namelen, bucket;
++
++ if (h->nlmsg_type == RTM_NEWLINK) {
++ struct ifinfomsg *ifi = NLMSG_DATA(h);
++ index = ifi->ifi_index;
++ type = IFLA_IFNAME;
++ rta = NLMSG_RTA(h, sizeof(*ifi));
++ } else {
++ struct ifaddrmsg *ifa = NLMSG_DATA(h);
++ index = ifa->ifa_index;
++ type = IFA_LABEL;
++ rta = NLMSG_RTA(h, sizeof(*ifa));
+ }
++ for (; NLMSG_RTAOK(rta, h); rta = RTA_NEXT(rta)) {
++ if (rta->rta_type != type) continue;
+
-+ for (rta = NLMSG_RTA(h, sizeof(*ifim)); NLMSG_RTAOK(rta, h); rta = RTA_NEXT(rta)) {
-+ if (rta->rta_type != IFLA_IFNAME) continue;
-+ if (RTA_DATALEN(rta) > IFNAMSIZ) return -ENOBUFS;
++ namelen = RTA_DATALEN(rta) - 1;
++ if (namelen > IFNAMSIZ) return 0;
- n = conf.ifc_len / sizeof(struct ifreq);
- for (i=k=0; i<n; i++) {
- if (ioctl(s, SIOCGIFINDEX, &conf.ifc_req[i]) < 0) {
- k++;
- continue;
-- }
++ /* suppress duplicates */
++ bucket = index % IFADDRS_HASH_SIZE;
++ i = ctx->hash[bucket];
++ while (i) {
++ map = &ctx->list[i-1];
++ if (map->index == index &&
++ map->namelen == namelen &&
++ memcmp(map->name, RTA_DATA(rta), namelen) == 0)
++ return 0;
++ i = map->hash_next;
+ }
- idx[i-k].if_index = conf.ifc_req[i].ifr_ifindex;
- idx[i-k].if_name = conf.ifc_req[i].ifr_name;
-+ ctx->num++;
-+ ctx->str_bytes += RTA_DATALEN(rta) + 1;
-+ e = realloc(ctx->list, sizeof(struct ifnamemap[ctx->num]));
-+ if (e == 0) return -ENOMEM;
-+ ctx->list = e;
-+
-+ e = &ctx->list[ctx->num-1];
-+ e->index = ifim->ifi_index;
-+ e->namelen = RTA_DATALEN(rta);
-+ memcpy(e->name, RTA_DATA(rta), IFNAMSIZ);
- }
+- }
- idx[i-k].if_name = 0;
- idx[i-k].if_index = 0;
- return idx;
++ if (ctx->num >= ctx->allocated) {
++ size_t a = ctx->allocated ? ctx->allocated * 2 + 1 : 8;
++ if (a > SIZE_MAX/sizeof *map) return -1;
++ map = realloc(ctx->list, a * sizeof *map);
++ if (!map) return -1;
++ ctx->list = map;
++ ctx->allocated = a;
++ }
++ map = &ctx->list[ctx->num];
++ map->index = index;
++ map->namelen = namelen;
++ memcpy(map->name, RTA_DATA(rta), namelen);
++ ctx->str_bytes += namelen + 1;
++ ctx->num++;
++ map->hash_next = ctx->hash[bucket];
++ ctx->hash[bucket] = ctx->num;
++ return 0;
++ }
+ return 0;
}
@@ -619,39 +652,33 @@ index 53b80b2..cb5587c 100644
- for (n=0; (p=do_nameindex(s, n)) == (void *)-1; n++);
- __syscall(SYS_close, s);
+ struct ifnameindexctx _ctx, *ctx = &_ctx;
-+ struct if_nameindex *ifs = NULL;
-+ int fd, r, i;
++ struct if_nameindex *ifs = 0, *d;
++ struct ifnamemap *s;
+ char *p;
-+
-+ fd = socket(PF_NETLINK, SOCK_RAW|SOCK_CLOEXEC, NETLINK_ROUTE);
-+ if (fd < 0) goto err;
++ int i;
+
+ memset(ctx, 0, sizeof(*ctx));
-+ r = __netlink_enumerate(fd, 1, RTM_GETLINK, AF_UNSPEC, __handle_link, ctx);
-+ __syscall(SYS_close,fd);
-+
-+ if (r < 0) goto err;
++ if (__rtnetlink_enumerate(AF_UNSPEC, AF_INET, __handle, ctx) < 0) goto err;
+
+ ifs = malloc(sizeof(struct if_nameindex[ctx->num+1]) + ctx->str_bytes);
-+ if (ifs == 0) goto err;
-+
-+ p = (char*)ifs + sizeof(struct if_nameindex[ctx->num+1]);
-+ for (i = 0; i < ctx->num; i++) {
-+ ifs[i].if_index = ctx->list[i].index;
-+ ifs[i].if_name = p;
-+ memcpy(p, ctx->list[i].name, ctx->list[i].namelen);
-+ p += ctx->list[i].namelen;
++ if (!ifs) goto err;
++
++ p = (char*)(ifs + ctx->num + 1);
++ for (i = ctx->num, d = ifs, s = ctx->list; i; i--, s++, d++) {
++ d->if_index = s->index;
++ d->if_name = p;
++ memcpy(p, s->name, s->namelen);
++ p += s->namelen;
+ *p++ = 0;
}
- errno = ENOBUFS;
- return p;
-+ ifs[i].if_index = 0;
-+ ifs[i].if_name = 0;
++ d->if_index = 0;
++ d->if_name = 0;
+err:
+ free(ctx->list);
-+ if (ifs == NULL) errno = ENOBUFS;
+ return ifs;
}
--
-1.9.2
+2.0.2
diff --git a/main/musl/1003-remove-ulimit-fiddling-from-setxid.patch b/main/musl/1003-remove-ulimit-fiddling-from-setxid.patch
new file mode 100644
index 000000000..e66cdc3b7
--- /dev/null
+++ b/main/musl/1003-remove-ulimit-fiddling-from-setxid.patch
@@ -0,0 +1,72 @@
+From 1a2526fae0f3747ff7f60e60aa16b8148fd8ea07 Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Timo=20Ter=C3=A4s?= <timo.teras@iki.fi>
+Date: Thu, 24 Jul 2014 09:19:46 +0300
+Subject: [PATCH] remove ulimit fiddling from setxid
+
+It was only needed to workaround bugs in linux 3.1 and earlier.
+Incidentally, the ulimit fiddling introduced another bug: it would
+fail for non-root users.
+
+Additionally, this fixes updating c->err with atomic cas.
+---
+ src/unistd/setxid.c | 25 +++++++------------------
+ 1 file changed, 7 insertions(+), 18 deletions(-)
+
+diff --git a/src/unistd/setxid.c b/src/unistd/setxid.c
+index 2f651a1..6fcbc61 100644
+--- a/src/unistd/setxid.c
++++ b/src/unistd/setxid.c
+@@ -1,7 +1,7 @@
+ #include <unistd.h>
+ #include <errno.h>
+-#include <sys/resource.h>
+ #include "syscall.h"
++#include "atomic.h"
+ #include "libc.h"
+
+ struct ctx {
+@@ -9,35 +9,24 @@ struct ctx {
+ int nr, rlim, err;
+ };
+
+-/* We jump through hoops to eliminate the possibility of partial failures. */
++/* This is not reliable on kernels earlier than 3.1, as set*uid can
++ * fail with EAGAIN if ulimit is exceeded. If that happens, the process
++ * is left in inconsistent state. */
+
+ int __setrlimit(int, const struct rlimit *);
+
+ static void do_setxid(void *p)
+ {
+ struct ctx *c = p;
++ int r;
+ if (c->err) return;
+- if (c->rlim && c->id >= 0 && c->id != getuid()) {
+- struct rlimit inf = { RLIM_INFINITY, RLIM_INFINITY }, old;
+- getrlimit(RLIMIT_NPROC, &old);
+- if ((c->err = -__setrlimit(RLIMIT_NPROC, &inf)) && libc.threads_minus_1)
+- return;
+- c->err = -__syscall(c->nr, c->id, c->eid, c->sid);
+- __setrlimit(RLIMIT_NPROC, &old);
+- return;
+- }
+- c->err = -__syscall(c->nr, c->id, c->eid, c->sid);
++ r = __syscall(c->nr, c->id, c->eid, c->sid);
++ if (r) a_cas(&c->err, 0, -r);
+ }
+
+ int __setxid(int nr, int id, int eid, int sid)
+ {
+ struct ctx c = { .nr = nr, .id = id, .eid = eid, .sid = sid };
+- switch (nr) {
+- case SYS_setuid:
+- case SYS_setreuid:
+- case SYS_setresuid:
+- c.rlim = 1;
+- }
+ __synccall(do_setxid, &c);
+ if (c.err) {
+ errno = c.err;
+--
+2.0.2
+
diff --git a/main/musl/APKBUILD b/main/musl/APKBUILD
index 6d59a395e..883ed3988 100644
--- a/main/musl/APKBUILD
+++ b/main/musl/APKBUILD
@@ -2,7 +2,7 @@
# Maintainer: Timo Teräs <timo.teras@iki.fi>
pkgname=musl
pkgver=1.1.3
-pkgrel=2
+pkgrel=3
pkgdesc="the musl c library (libc) implementation"
url="http://www.musl-libc.org/"
arch="all"
@@ -18,8 +18,13 @@ source="http://www.musl-libc.org/releases/musl-$pkgver.tar.gz
0003-fix-incorrect-return-value-for-fwide-function.patch
0004-fix-failure-of-wide-printf-scanf-functions-to-set-wi.patch
0005-fix-multiple-issues-in-legacy-function-getpass.patch
+ 0006-make-dynamic-linker-accept-colon-as-a-separator-for-.patch
+ 0007-explicitly-reject-empty-names-in-dynamic-linker-load.patch
+ 0008-fix-the-m-specifier-in-syslog.patch
+ 0009-fix-crash-in-regexec-for-nonzero-nmatch-argument-wit.patch
1001-add-basic-dns-record-parsing-functions.patch
1002-reimplement-if_nameindex-and-getifaddrs-using-netlin.patch
+ 1003-remove-ulimit-fiddling-from-setxid.patch
ldconfig
getopt_long.c
@@ -126,8 +131,13 @@ fe9d6f28d19f0e8d22073572df7f4e86 0002-fix-aliasing-violations-in-mbtowc-and-mbr
43790c32ecd7cad6622a1b08e2ec14a7 0003-fix-incorrect-return-value-for-fwide-function.patch
73c7c31ef8a93e5a8a3dfba5fe4b970d 0004-fix-failure-of-wide-printf-scanf-functions-to-set-wi.patch
ec24fa025b9a24e5c2ca05839956c1fb 0005-fix-multiple-issues-in-legacy-function-getpass.patch
-a3810683ef61ac27e2f6ec9801280c81 1001-add-basic-dns-record-parsing-functions.patch
-83c3bd2a50b1de5ef948704d3f4e0583 1002-reimplement-if_nameindex-and-getifaddrs-using-netlin.patch
+5e432ef2b8ef6daf76f2e2b0081da4ee 0006-make-dynamic-linker-accept-colon-as-a-separator-for-.patch
+db9e6b1782ab40b08b2bd2fbc237315c 0007-explicitly-reject-empty-names-in-dynamic-linker-load.patch
+d4be3c4e254a34f94f2a18d0fd43824c 0008-fix-the-m-specifier-in-syslog.patch
+f77891cda55e2f54567814eff91934c0 0009-fix-crash-in-regexec-for-nonzero-nmatch-argument-wit.patch
+d10ef84b50bd2a01ce3b7305e699d5da 1001-add-basic-dns-record-parsing-functions.patch
+50bc2caec315ec814f3ffd374008738b 1002-reimplement-if_nameindex-and-getifaddrs-using-netlin.patch
+71b2a4dcc39c436a6b89173943424043 1003-remove-ulimit-fiddling-from-setxid.patch
013be8897f27c3909ada59c62020502f ldconfig
61c6c1e84ed1df82abbe6d75e90cf21c getopt_long.c
0df687757221bbb0fc1aa67f1bd646f9 __stack_chk_fail_local.c
@@ -140,8 +150,13 @@ cb21b6af4a9f9ff478a838b05362a63215fe5721e909acf0f09115ea22be677f 0002-fix-alias
f555678ed344f2d06eff9f2e1e46eff95c7df974023ac2ffee3a7aa72dec699d 0003-fix-incorrect-return-value-for-fwide-function.patch
788279d797f08e8be5857e3124b2684e6d34e5473c0ac9fba60883c518b26d5f 0004-fix-failure-of-wide-printf-scanf-functions-to-set-wi.patch
b72394ced802d6b4e88a2bd9eed24f239c787d0a63d8c2862db13b102c118ce1 0005-fix-multiple-issues-in-legacy-function-getpass.patch
-758390768b1bc4159d56908ca332b9640cd0552ed3b4b2b8d4a6d499c54c11a1 1001-add-basic-dns-record-parsing-functions.patch
-1c25880095e869b827f02997e864fdf4bf157a4e923e52d97dbd05e657aedb70 1002-reimplement-if_nameindex-and-getifaddrs-using-netlin.patch
+0383402d2577a82408a1c5030522f1f81ace8cf374feb5edf41426ab106cb82d 0006-make-dynamic-linker-accept-colon-as-a-separator-for-.patch
+2ba10f0e8efbce263db3147ecd4791d3363b968fcbfb2db4baaaeda1014d0079 0007-explicitly-reject-empty-names-in-dynamic-linker-load.patch
+a48df68855aec62da663ebf05f358bb49d054fbcb46c109db0a2b5e7a92a4259 0008-fix-the-m-specifier-in-syslog.patch
+448280d267f6dcf9d3695b10a037092a0b963f026c83e4b03564d5564faec052 0009-fix-crash-in-regexec-for-nonzero-nmatch-argument-wit.patch
+207d6311489c86951edeab241d3a589fb76007a4950643cfa70e857c2fa1531e 1001-add-basic-dns-record-parsing-functions.patch
+9aee829aadb3e1fb3e61ca3ad56a7512dcfada2658ba31f83290ada86ace455b 1002-reimplement-if_nameindex-and-getifaddrs-using-netlin.patch
+fb542c2bd5081ff2f601c519edb3dac8f54ca5c888f44bc6cfb84e6565472025 1003-remove-ulimit-fiddling-from-setxid.patch
398dc26ec82cc6af056c738e8ac62da212ba978229d9839eb8b61f7ce536da4a ldconfig
d9b644ec20bc33e81a7c52b9fcf7973d835923a69faf50f03db45534b811bd96 getopt_long.c
299a7d75a09de3e2e11e7fb4acc3182e4a14e868093d2f30938fce9bfcff13da __stack_chk_fail_local.c
@@ -154,8 +169,13 @@ d621e097f8b23c9bd1dffa4dbc471db0fee0aa3665d9c4588daa1b1479d011f0963b615af5594330
bc06965a05d1e482a7ab0bcba8230b45778ab19ee907bddb68cf5496c38d23d51780d12980bb68344ff43b4c7c5f8e6edbbb576632f3e2ff50cc515b43e7985c 0003-fix-incorrect-return-value-for-fwide-function.patch
e16fc1a78c128212fc82488b0e2291cb64656d1c0938bda9c6e96aa285676bd959d1cd10192287c339a20a6e76a32176c04a3697b8f6b068629d63eb8494b5dd 0004-fix-failure-of-wide-printf-scanf-functions-to-set-wi.patch
8868b29c1fc520b081601b2c4b750e2b4fdb76166cd64702aa2b22aca86b5a541fbd393243c55a3d59aca9944e17b0fe9c93673547da04b2517163c271c30fbf 0005-fix-multiple-issues-in-legacy-function-getpass.patch
-dad965258daf69371b844f76bfe5a914b0eca0ca76f3fc340b8fd7acf598b5f87bbe6d68b1f43ed0293ee0ed3bfd85d5173ccc169aa6265646248d5b8a906708 1001-add-basic-dns-record-parsing-functions.patch
-72cf33738d2cf31f6ec02312bc494d754c17470b519172bb8bd7e2e29ac3b119023088a2b3fbc0dbc2fddd0078ccbae62096106cae361f8c31d6a9950043af25 1002-reimplement-if_nameindex-and-getifaddrs-using-netlin.patch
+1c3ca3317d7dd3e2959754988b1cb7b56215e18b9481205b9a254f8842cdf2d5cdcdaf0ba45dd7c9d4f4629b53a44415b94016faea0b166cc44a6e1ffd4f5ace 0006-make-dynamic-linker-accept-colon-as-a-separator-for-.patch
+0878ab3babec6ac16d464fbda3151122637c80a30bc9f37b1079d31df17f62062f04bcf0c620014a45cb04255b4db7de56cf906d070dd29be17ef6db756a8060 0007-explicitly-reject-empty-names-in-dynamic-linker-load.patch
+5212d345635b88497a1e050d22c387a75e849ca257b41a01391882510b469a1162259c99f101c26ac1ce4c9cce9e3c55a2f422564a949bb3b438f182cb65a414 0008-fix-the-m-specifier-in-syslog.patch
+29387d468bf06cb53acae098b06268fdfc74a6c5cc612776f96012be49978090e0f74ee1a6128a8cfd452af5c698d4cd07749013dd8c722e1173c9e328677499 0009-fix-crash-in-regexec-for-nonzero-nmatch-argument-wit.patch
+368087d2e25a2c27d6f4fddfed8619f073492490f945323ef7d566dab5a9a29a50526d041f4c6ed292869fe2e748520524ca416a39fbceacf99d3366697ec16a 1001-add-basic-dns-record-parsing-functions.patch
+3df7500a06960490412c15002cdd68916f6d4ad13c3070477d0859874649ff5f6de128b2d9592e614b5ff4ba7616fd074c353f4d2dc2eb1549903a3975fd9e5e 1002-reimplement-if_nameindex-and-getifaddrs-using-netlin.patch
+dae010b45419fcab64410568466f659cdc874e63113025e2cbc2fbab047b470fec23851ecbef08886505924482a069caf37c16b483b6922535fbd31832f1c4a3 1003-remove-ulimit-fiddling-from-setxid.patch
33e13d2242063f3dc9ec199ae9528e469a52ccae4d3726faa3c866e0c7dcf546f69294f9c00307324cee05fd965f84350ae100b8b1138f9d9c8c916de04ab0d1 ldconfig
140f3f20d30bd95ebce8c41b8cc7f616c6cbedf4ea06c729c21014e74f6043796825cc40ebc5180620ea38173afdba23f09ebf6d8b11fa05440b14d23764fca9 getopt_long.c
062bb49fa54839010acd4af113e20f7263dde1c8a2ca359b5fb2661ef9ed9d84a0f7c3bc10c25dcfa10bb3c5a4874588dff636ac43d5dbb3d748d75400756d0b __stack_chk_fail_local.c