Hello community, here is the log from the commit of package slirp4netns for openSUSE:Factory checked in at 2020-03-27 21:56:07 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/slirp4netns (Old) and /work/SRC/openSUSE:Factory/.slirp4netns.new.3160 (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "slirp4netns" Fri Mar 27 21:56:07 2020 rev:9 rq:789009 version:0.4.4 Changes: -------- --- /work/SRC/openSUSE:Factory/slirp4netns/slirp4netns.changes 2019-12-23 22:43:21.981974470 +0100 +++ /work/SRC/openSUSE:Factory/.slirp4netns.new.3160/slirp4netns.changes 2020-03-27 21:56:23.726761273 +0100 @@ -1,0 +2,19 @@ +Fri Mar 27 09:28:47 UTC 2020 - Ralf Haferkamp <[email protected]> + +- Update to 0.4.4 (bsc#1167850) + * libslirp: Update to v4.2.0: + * New API function slirp_add_unix: add a forward rule to a Unix + socket. + * New API function slirp_remove_guestfwd: remove a forward rule + previously added by slirp_add_exec, slirp_add_unix or + slirp_add_guestfwd + * New SlirpConfig.outbound_addr{,6} fields to bind output + socket to a specific address + * socket: do not fallback on host loopback if get_dns_addr() + failed or the address is in slirp network + * ncsi: fix checksum OOB memory access + * tcp_emu(): fix OOB accesses + * tftp: restrict relative path access + * state: fix loading of guestfwd state + +------------------------------------------------------------------- Old: ---- slirp4netns-0.4.3.tar.xz New: ---- slirp4netns-0.4.4.tar.xz ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ slirp4netns.spec ++++++ --- /var/tmp/diff_new_pack.rW6ysY/_old 2020-03-27 21:56:25.386762238 +0100 +++ /var/tmp/diff_new_pack.rW6ysY/_new 2020-03-27 21:56:25.418762257 +0100 @@ -1,7 +1,7 @@ # # spec file for package slirp4netns # -# Copyright (c) 2019 SUSE LLC +# Copyright (c) 2020 SUSE LLC # # All modifications and additions to the file contributed by third parties # remain the property of their copyright owners, unless otherwise agreed @@ -17,7 +17,7 @@ Name: slirp4netns -Version: 0.4.3 +Version: 0.4.4 Release: 0 Summary: User-mode networking for unprivileged network namespaces License: GPL-2.0-only AND MIT AND BSD-2-Clause ++++++ _service ++++++ --- /var/tmp/diff_new_pack.rW6ysY/_old 2020-03-27 21:56:25.758762454 +0100 +++ /var/tmp/diff_new_pack.rW6ysY/_new 2020-03-27 21:56:25.774762464 +0100 @@ -4,8 +4,8 @@ <param name="url">https://github.com/rootless-containers/slirp4netns.git</param> <param name="scm">git</param> <param name="filename">slirp4netns</param> -<param name="versionformat">0.4.3</param> -<param name="revision">v0.4.3</param> +<param name="versionformat">0.4.4</param> +<param name="revision">v0.4.4</param> </service> <service name="recompress" mode="disabled"> ++++++ slirp4netns-0.4.3.tar.xz -> slirp4netns-0.4.4.tar.xz ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/slirp4netns-0.4.3/configure.ac new/slirp4netns-0.4.4/configure.ac --- old/slirp4netns-0.4.3/configure.ac 2019-12-18 03:34:42.000000000 +0100 +++ new/slirp4netns-0.4.4/configure.ac 2020-03-19 01:38:45.000000000 +0100 @@ -1,5 +1,5 @@ AC_PREREQ([2.69]) -AC_INIT([slirp4netns], [0.4.3], [https://github.com/rootless-containers/slirp4netns/issues]) +AC_INIT([slirp4netns], [0.4.4], [https://github.com/rootless-containers/slirp4netns/issues]) AC_CONFIG_SRCDIR([main.c]) AC_CONFIG_HEADERS([config.h]) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/slirp4netns-0.4.3/main.c new/slirp4netns-0.4.4/main.c --- old/slirp4netns-0.4.3/main.c 2019-12-18 03:34:42.000000000 +0100 +++ new/slirp4netns-0.4.4/main.c 2020-03-19 01:38:45.000000000 +0100 @@ -19,6 +19,7 @@ #include <getopt.h> #include <stdbool.h> #include <regex.h> +#include "vendor/libslirp/src/libslirp.h" #include "slirp4netns.h" #define DEFAULT_MTU (1500) @@ -342,6 +343,7 @@ #ifdef COMMIT printf("commit: %s\n", COMMIT); #endif + printf("libslirp: %s\n", slirp_version_string()); } struct options { diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/slirp4netns-0.4.3/vendor/README.md new/slirp4netns-0.4.4/vendor/README.md --- old/slirp4netns-0.4.3/vendor/README.md 2019-12-18 03:34:42.000000000 +0100 +++ new/slirp4netns-0.4.4/vendor/README.md 2020-03-19 01:38:45.000000000 +0100 @@ -1,8 +1,8 @@ # DO NOT EDIT MANUALLY Vendored components: -* libslirp: https://gitlab.freedesktop.org/slirp/libslirp.git (`6651ba26c4e94f64d6448a2db4991269ce553bd9`) -* parson: https://github.com/kgabis/parson.git (`c5bb9557fe98367aa8e041c65863909f12ee76b2`) +* libslirp: https://gitlab.freedesktop.org/slirp/libslirp.git (`daba14c3416fa9641ab4453a9a11e7f8bde08875`) +* parson: https://github.com/kgabis/parson.git (`70dc239f8f54c80bf58477b25435fd3dd3102804`) Please do not edit the contents under this directory manually. diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/slirp4netns-0.4.3/vendor/libslirp/src/bootp.c new/slirp4netns-0.4.4/vendor/libslirp/src/bootp.c --- old/slirp4netns-0.4.3/vendor/libslirp/src/bootp.c 2019-12-18 03:34:42.000000000 +0100 +++ new/slirp4netns-0.4.4/vendor/libslirp/src/bootp.c 2020-03-19 01:38:45.000000000 +0100 @@ -254,9 +254,10 @@ *q++ = DHCPACK; } - if (slirp->bootp_filename) - snprintf((char *)rbp->bp_file, sizeof(rbp->bp_file), "%s", - slirp->bootp_filename); + if (slirp->bootp_filename) { + g_assert(strlen(slirp->bootp_filename) < sizeof(rbp->bp_file)); + strcpy(rbp->bp_file, slirp->bootp_filename); + } *q++ = RFC2132_SRV_ID; *q++ = 4; diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/slirp4netns-0.4.3/vendor/libslirp/src/bootp.h new/slirp4netns-0.4.4/vendor/libslirp/src/bootp.h --- old/slirp4netns-0.4.3/vendor/libslirp/src/bootp.h 2019-12-18 03:34:42.000000000 +0100 +++ new/slirp4netns-0.4.4/vendor/libslirp/src/bootp.h 2020-03-19 01:38:45.000000000 +0100 @@ -113,7 +113,7 @@ struct in_addr bp_giaddr; uint8_t bp_hwaddr[16]; uint8_t bp_sname[64]; - uint8_t bp_file[128]; + char bp_file[128]; uint8_t bp_vend[DHCP_OPT_LEN]; }; diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/slirp4netns-0.4.3/vendor/libslirp/src/dhcpv6.c new/slirp4netns-0.4.4/vendor/libslirp/src/dhcpv6.c --- old/slirp4netns-0.4.3/vendor/libslirp/src/dhcpv6.c 2019-12-18 03:34:42.000000000 +0100 +++ new/slirp4netns-0.4.4/vendor/libslirp/src/dhcpv6.c 2020-03-19 01:38:45.000000000 +0100 @@ -179,13 +179,12 @@ *resp++ = OPTION_BOOTFILE_URL >> 8; /* option-code high byte */ *resp++ = OPTION_BOOTFILE_URL; /* option-code low byte */ smaxlen = (uint8_t *)m->m_data + slirp->if_mtu - (resp + 2); - slen = snprintf((char *)resp + 2, smaxlen, - "tftp://[%02x%02x:%02x%02x:%02x%02x:%02x%02x:" - "%02x%02x:%02x%02x:%02x%02x:%02x%02x]/%s", - sa[0], sa[1], sa[2], sa[3], sa[4], sa[5], sa[6], sa[7], - sa[8], sa[9], sa[10], sa[11], sa[12], sa[13], sa[14], - sa[15], slirp->bootp_filename); - slen = MIN(slen, smaxlen); + slen = slirp_fmt((char *)resp + 2, smaxlen, + "tftp://[%02x%02x:%02x%02x:%02x%02x:%02x%02x:" + "%02x%02x:%02x%02x:%02x%02x:%02x%02x]/%s", + sa[0], sa[1], sa[2], sa[3], sa[4], sa[5], sa[6], sa[7], + sa[8], sa[9], sa[10], sa[11], sa[12], sa[13], sa[14], + sa[15], slirp->bootp_filename); *resp++ = slen >> 8; /* option-len high byte */ *resp++ = slen; /* option-len low byte */ resp += slen; diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/slirp4netns-0.4.3/vendor/libslirp/src/ip_icmp.c new/slirp4netns-0.4.4/vendor/libslirp/src/ip_icmp.c --- old/slirp4netns-0.4.3/vendor/libslirp/src/ip_icmp.c 2019-12-18 03:34:42.000000000 +0100 +++ new/slirp4netns-0.4.4/vendor/libslirp/src/ip_icmp.c 2020-03-19 01:38:45.000000000 +0100 @@ -90,6 +90,13 @@ return -1; } + if (slirp_bind_outbound(so, AF_INET) != 0) { + // bind failed - close socket + closesocket(so->s); + so->s = -1; + return -1; + } + so->so_m = m; so->so_faddr = ip->ip_dst; so->so_laddr = ip->ip_src; diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/slirp4netns-0.4.3/vendor/libslirp/src/libslirp-version.h new/slirp4netns-0.4.4/vendor/libslirp/src/libslirp-version.h --- old/slirp4netns-0.4.3/vendor/libslirp/src/libslirp-version.h 2019-12-18 03:34:42.000000000 +0100 +++ new/slirp4netns-0.4.4/vendor/libslirp/src/libslirp-version.h 2020-03-19 01:38:45.000000000 +0100 @@ -7,7 +7,7 @@ #endif #define SLIRP_MAJOR_VERSION 4 -#define SLIRP_MINOR_VERSION 1 +#define SLIRP_MINOR_VERSION 2 #define SLIRP_MICRO_VERSION 0 #define SLIRP_CHECK_VERSION(major,minor,micro) \ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/slirp4netns-0.4.3/vendor/libslirp/src/libslirp.h new/slirp4netns-0.4.4/vendor/libslirp/src/libslirp.h --- old/slirp4netns-0.4.3/vendor/libslirp/src/libslirp.h 2019-12-18 03:34:42.000000000 +0100 +++ new/slirp4netns-0.4.4/vendor/libslirp/src/libslirp.h 2020-03-19 01:38:45.000000000 +0100 @@ -67,7 +67,7 @@ } SlirpCb; #define SLIRP_CONFIG_VERSION_MIN 1 -#define SLIRP_CONFIG_VERSION_MAX 1 +#define SLIRP_CONFIG_VERSION_MAX 2 typedef struct SlirpConfig { /* Version must be provided */ @@ -107,6 +107,8 @@ /* * Fields introduced in SlirpConfig version 2 begin */ + struct sockaddr_in *outbound_addr; + struct sockaddr_in6 *outbound_addr6; } SlirpConfig; Slirp *slirp_new(const SlirpConfig *cfg, const SlirpCb *callbacks, @@ -138,8 +140,13 @@ int host_port); int slirp_add_exec(Slirp *slirp, const char *cmdline, struct in_addr *guest_addr, int guest_port); +int slirp_add_unix(Slirp *slirp, const char *unixsock, + struct in_addr *guest_addr, int guest_port); int slirp_add_guestfwd(Slirp *slirp, SlirpWriteCb write_cb, void *opaque, struct in_addr *guest_addr, int guest_port); +/* remove entries added by slirp_add_exec, slirp_add_unix or slirp_add_guestfwd */ +int slirp_remove_guestfwd(Slirp *slirp, struct in_addr guest_addr, + int guest_port); char *slirp_connection_info(Slirp *slirp); diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/slirp4netns-0.4.3/vendor/libslirp/src/misc.c new/slirp4netns-0.4.4/vendor/libslirp/src/misc.c --- old/slirp4netns-0.4.3/vendor/libslirp/src/misc.c 2019-12-18 03:34:42.000000000 +0100 +++ new/slirp4netns-0.4.4/vendor/libslirp/src/misc.c 2020-03-19 01:38:45.000000000 +0100 @@ -4,6 +4,9 @@ */ #include "slirp.h" +#ifdef G_OS_UNIX +#include <sys/un.h> +#endif inline void insque(void *a, void *b) { @@ -50,6 +53,30 @@ return f; } +struct gfwd_list *add_unix(struct gfwd_list **ex_ptr, const char *unixsock, + struct in_addr addr, int port) +{ + struct gfwd_list *f = add_guestfwd(ex_ptr, NULL, NULL, addr, port); + + f->ex_unix = g_strdup(unixsock); + + return f; +} + +int remove_guestfwd(struct gfwd_list **ex_ptr, struct in_addr addr, int port) +{ + for (; *ex_ptr != NULL; ex_ptr = &((*ex_ptr)->ex_next)) { + struct gfwd_list *f = *ex_ptr; + if (f->ex_addr.s_addr == addr.s_addr && f->ex_fport == port) { + *ex_ptr = f->ex_next; + g_free(f->ex_exec); + g_free(f); + return 0; + } + } + return -1; +} + static int slirp_socketpair_with_oob(int sv[2]) { struct sockaddr_in addr = { @@ -210,6 +237,45 @@ return 1; } +int open_unix(struct socket *so, const char *unixpath) +{ +#ifdef G_OS_UNIX + struct sockaddr_un sa; + int s; + + DEBUG_CALL("open_unix"); + DEBUG_ARG("so = %p", so); + DEBUG_ARG("unixpath = %s", unixpath); + + memset(&sa, 0, sizeof(sa)); + sa.sun_family = AF_UNIX; + if (g_strlcpy(sa.sun_path, unixpath, sizeof(sa.sun_path)) >= sizeof(sa.sun_path)) { + g_critical("Bad unix path: %s", unixpath); + return 0; + } + + s = slirp_socket(PF_UNIX, SOCK_STREAM, 0); + if (s < 0) { + g_critical("open_unix(): %s", strerror(errno)); + return 0; + } + + if (connect(s, (struct sockaddr *)&sa, sizeof(sa)) < 0) { + g_critical("open_unix(): %s", strerror(errno)); + closesocket(s); + return 0; + } + + so->s = s; + slirp_set_nonblock(so->s); + so->slirp->cb->register_poll_fd(so->s, so->slirp->opaque); + + return 1; +#else + g_assert_not_reached(); +#endif +} + char *slirp_connection_info(Slirp *slirp) { GString *str = g_string_new(NULL); @@ -254,7 +320,7 @@ dst_addr = so->so_faddr; dst_port = so->so_fport; } - snprintf(buf, sizeof(buf), " TCP[%s]", state); + slirp_fmt0(buf, sizeof(buf), " TCP[%s]", state); g_string_append_printf(str, "%-19s %3d %15s %5d ", buf, so->s, src.sin_addr.s_addr ? inet_ntoa(src.sin_addr) : "*", @@ -266,14 +332,14 @@ for (so = slirp->udb.so_next; so != &slirp->udb; so = so->so_next) { if (so->so_state & SS_HOSTFWD) { - snprintf(buf, sizeof(buf), " UDP[HOST_FORWARD]"); + slirp_fmt0(buf, sizeof(buf), " UDP[HOST_FORWARD]"); src_len = sizeof(src); getsockname(so->s, (struct sockaddr *)&src, &src_len); dst_addr = so->so_laddr; dst_port = so->so_lport; } else { - snprintf(buf, sizeof(buf), " UDP[%d sec]", - (so->so_expire - curtime) / 1000); + slirp_fmt0(buf, sizeof(buf), " UDP[%d sec]", + (so->so_expire - curtime) / 1000); src.sin_addr = so->so_laddr; src.sin_port = so->so_lport; dst_addr = so->so_faddr; @@ -289,8 +355,8 @@ } for (so = slirp->icmp.so_next; so != &slirp->icmp; so = so->so_next) { - snprintf(buf, sizeof(buf), " ICMP[%d sec]", - (so->so_expire - curtime) / 1000); + slirp_fmt0(buf, sizeof(buf), " ICMP[%d sec]", + (so->so_expire - curtime) / 1000); src.sin_addr = so->so_laddr; dst_addr = so->so_faddr; g_string_append_printf(str, "%-19s %3d %15s - ", buf, so->s, @@ -302,3 +368,23 @@ return g_string_free(str, FALSE); } + +int slirp_bind_outbound(struct socket *so, unsigned short af) +{ + int ret = 0; + struct sockaddr *addr = NULL; + int addr_size = 0; + + if (af == AF_INET && so->slirp->outbound_addr != NULL) { + addr = (struct sockaddr *)so->slirp->outbound_addr; + addr_size = sizeof(struct sockaddr_in); + } else if (af == AF_INET6 && so->slirp->outbound_addr6 != NULL) { + addr = (struct sockaddr *)so->slirp->outbound_addr6; + addr_size = sizeof(struct sockaddr_in6); + } + + if (addr != NULL) { + ret = bind(so->s, addr, addr_size); + } + return ret; +} \ No newline at end of file diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/slirp4netns-0.4.3/vendor/libslirp/src/misc.h new/slirp4netns-0.4.4/vendor/libslirp/src/misc.h --- old/slirp4netns-0.4.3/vendor/libslirp/src/misc.h 2019-12-18 03:34:42.000000000 +0100 +++ new/slirp4netns-0.4.4/vendor/libslirp/src/misc.h 2020-03-19 01:38:45.000000000 +0100 @@ -14,6 +14,7 @@ struct in_addr ex_addr; /* Server address */ int ex_fport; /* Port to telnet to */ char *ex_exec; /* Command line of what to exec */ + char *ex_unix; /* unix socket */ struct gfwd_list *ex_next; }; @@ -53,6 +54,7 @@ void slirp_insque(void *, void *); void slirp_remque(void *); int fork_exec(struct socket *so, const char *ex); +int open_unix(struct socket *so, const char *unixsock); struct gfwd_list *add_guestfwd(struct gfwd_list **ex_ptr, SlirpWriteCb write_cb, void *opaque, struct in_addr addr, int port); @@ -60,4 +62,11 @@ struct gfwd_list *add_exec(struct gfwd_list **ex_ptr, const char *cmdline, struct in_addr addr, int port); +struct gfwd_list *add_unix(struct gfwd_list **ex_ptr, const char *unixsock, + struct in_addr addr, int port); + +int remove_guestfwd(struct gfwd_list **ex_ptr, struct in_addr addr, int port); + +int slirp_bind_outbound(struct socket *so, unsigned short af); + #endif diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/slirp4netns-0.4.3/vendor/libslirp/src/ncsi.c new/slirp4netns-0.4.4/vendor/libslirp/src/ncsi.c --- old/slirp4netns-0.4.3/vendor/libslirp/src/ncsi.c 2019-12-18 03:34:42.000000000 +0100 +++ new/slirp4netns-0.4.4/vendor/libslirp/src/ncsi.c 2020-03-19 01:38:45.000000000 +0100 @@ -47,7 +47,7 @@ * 32-bit unsigned sum of the NC-SI packet header and NC-SI packet * payload interpreted as a series of 16-bit unsigned integer values. */ - for (i = 0; i < len; i++) { + for (i = 0; i < len / 2; i++) { checksum += htons(data[i]); } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/slirp4netns-0.4.3/vendor/libslirp/src/slirp.c new/slirp4netns-0.4.4/vendor/libslirp/src/slirp.c --- old/slirp4netns-0.4.3/vendor/libslirp/src/slirp.c 2019-12-18 03:34:42.000000000 +0100 +++ new/slirp4netns-0.4.4/vendor/libslirp/src/slirp.c 2020-03-19 01:38:45.000000000 +0100 @@ -278,6 +278,9 @@ g_return_val_if_fail(cfg->if_mtu <= IF_MTU_MAX, NULL); g_return_val_if_fail(cfg->if_mru >= IF_MRU_MIN || cfg->if_mru == 0, NULL); g_return_val_if_fail(cfg->if_mru <= IF_MRU_MAX, NULL); + g_return_val_if_fail(!cfg->bootfile || + (strlen(cfg->bootfile) < + G_SIZEOF_MEMBER(struct bootp_t, bp_file)), NULL); slirp = g_malloc0(sizeof(Slirp)); @@ -323,6 +326,13 @@ slirp->disable_host_loopback = cfg->disable_host_loopback; slirp->enable_emu = cfg->enable_emu; + if (cfg->version >= 2) { + slirp->outbound_addr = cfg->outbound_addr; + slirp->outbound_addr6 = cfg->outbound_addr6; + } else { + slirp->outbound_addr = NULL; + slirp->outbound_addr6 = NULL; + } return slirp; } @@ -368,6 +378,7 @@ for (e = slirp->guestfwd_list; e; e = next) { next = e->ex_next; g_free(e->ex_exec); + g_free(e->ex_unix); g_free(e); } @@ -1049,6 +1060,22 @@ return 0; } +int slirp_add_unix(Slirp *slirp, const char *unixsock, + struct in_addr *guest_addr, int guest_port) +{ +#ifdef G_OS_UNIX + if (!check_guestfwd(slirp, guest_addr, guest_port)) { + return -1; + } + + add_unix(&slirp->guestfwd_list, unixsock, *guest_addr, htons(guest_port)); + return 0; +#else + g_warn_if_reached(); + return -1; +#endif +} + int slirp_add_guestfwd(Slirp *slirp, SlirpWriteCb write_cb, void *opaque, struct in_addr *guest_addr, int guest_port) { @@ -1061,6 +1088,13 @@ return 0; } +int slirp_remove_guestfwd(Slirp *slirp, struct in_addr guest_addr, + int guest_port) +{ + return remove_guestfwd(&slirp->guestfwd_list, guest_addr, + htons(guest_port)); +} + ssize_t slirp_send(struct socket *so, const void *buf, size_t len, int flags) { if (so->s == -1 && so->guestfwd) { diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/slirp4netns-0.4.3/vendor/libslirp/src/slirp.h new/slirp4netns-0.4.4/vendor/libslirp/src/slirp.h --- old/slirp4netns-0.4.3/vendor/libslirp/src/slirp.h 2019-12-18 03:34:42.000000000 +0100 +++ new/slirp4netns-0.4.4/vendor/libslirp/src/slirp.h 2020-03-19 01:38:45.000000000 +0100 @@ -199,6 +199,9 @@ const SlirpCb *cb; void *opaque; + + struct sockaddr_in *outbound_addr; + struct sockaddr_in6 *outbound_addr6; }; void if_start(Slirp *); diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/slirp4netns-0.4.3/vendor/libslirp/src/socket.c new/slirp4netns-0.4.4/vendor/libslirp/src/socket.c --- old/slirp4netns-0.4.3/vendor/libslirp/src/socket.c 2019-12-18 03:34:42.000000000 +0100 +++ new/slirp4netns-0.4.4/vendor/libslirp/src/socket.c 2020-03-19 01:38:45.000000000 +0100 @@ -819,66 +819,65 @@ sofcantsendmore(so); } +static bool sotranslate_out4(Slirp *s, struct socket *so, struct sockaddr_in *sin) +{ + if (so->so_faddr.s_addr == s->vnameserver_addr.s_addr) { + return get_dns_addr(&sin->sin_addr) >= 0; + } + + if (so->so_faddr.s_addr == s->vhost_addr.s_addr || + so->so_faddr.s_addr == 0xffffffff) { + if (s->disable_host_loopback) { + return false; + } + + sin->sin_addr = loopback_addr; + } + + return true; +} + +static bool sotranslate_out6(Slirp *s, struct socket *so, struct sockaddr_in6 *sin) +{ + if (in6_equal(&so->so_faddr6, &s->vnameserver_addr6)) { + return get_dns6_addr(&sin->sin6_addr, &sin->sin6_scope_id) >= 0; + } + + if (in6_equal_net(&so->so_faddr6, &s->vprefix_addr6, s->vprefix_len) || + in6_equal(&so->so_faddr6, &(struct in6_addr)ALLNODES_MULTICAST)) { + if (s->disable_host_loopback) { + return false; + } + + sin->sin6_addr = in6addr_loopback; + } + + return true; +} + + /* * Translate addr in host addr when it is a virtual address */ int sotranslate_out(struct socket *so, struct sockaddr_storage *addr) { - int rc = 0; - Slirp *slirp = so->slirp; - struct sockaddr_in *sin = (struct sockaddr_in *)addr; - struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *)addr; + bool ok = true; switch (addr->ss_family) { case AF_INET: - if ((so->so_faddr.s_addr & slirp->vnetwork_mask.s_addr) == - slirp->vnetwork_addr.s_addr) { - /* It's an alias */ - if (so->so_faddr.s_addr == slirp->vnameserver_addr.s_addr) { - if (get_dns_addr(&sin->sin_addr) >= 0) { - goto ret; - } - } - if (slirp->disable_host_loopback) { - rc = -1; - errno = EPERM; - goto ret; - } else { - sin->sin_addr = loopback_addr; - } - } else if (!slirp->disable_host_loopback && so->so_faddr.s_addr == 0xffffffff) { - /* Receive broadcast as well */ - sin->sin_addr = loopback_addr; - } + ok = sotranslate_out4(so->slirp, so, (struct sockaddr_in *)addr); break; case AF_INET6: - if (in6_equal_net(&so->so_faddr6, &slirp->vprefix_addr6, - slirp->vprefix_len)) { - if (in6_equal(&so->so_faddr6, &slirp->vnameserver_addr6)) { - uint32_t scope_id; - if (get_dns6_addr(&sin6->sin6_addr, &scope_id) >= 0) { - sin6->sin6_scope_id = scope_id; - goto ret; - } - } - if (slirp->disable_host_loopback) { - rc = -1; - errno = EPERM; - goto ret; - } else { - sin6->sin6_addr = in6addr_loopback; - } - } else if (!slirp->disable_host_loopback - && in6_equal(&so->so_faddr6, &(struct in6_addr) ALLNODES_MULTICAST)) { - sin6->sin6_addr = in6addr_loopback; - } + ok = sotranslate_out6(so->slirp, so, (struct sockaddr_in6 *)addr); break; + } - default: - break; + if (!ok) { + errno = EPERM; + return -1; } -ret: - return rc; + + return 0; } void sotranslate_in(struct socket *so, struct sockaddr_storage *addr) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/slirp4netns-0.4.3/vendor/libslirp/src/state.c new/slirp4netns-0.4.4/vendor/libslirp/src/state.c --- old/slirp4netns-0.4.3/vendor/libslirp/src/state.c 2019-12-18 03:34:42.000000000 +0100 +++ new/slirp4netns-0.4.4/vendor/libslirp/src/state.c 2020-03-19 01:38:45.000000000 +0100 @@ -366,6 +366,8 @@ if (!ex_ptr) { return -EINVAL; } + + so->guestfwd = ex_ptr; } return slirp_vmstate_load_state(&f, &vmstate_slirp, slirp, version_id); diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/slirp4netns-0.4.3/vendor/libslirp/src/tcp_subr.c new/slirp4netns-0.4.4/vendor/libslirp/src/tcp_subr.c --- old/slirp4netns-0.4.3/vendor/libslirp/src/tcp_subr.c 2019-12-18 03:34:42.000000000 +0100 +++ new/slirp4netns-0.4.4/vendor/libslirp/src/tcp_subr.c 2020-03-19 01:38:45.000000000 +0100 @@ -407,6 +407,16 @@ ret = so->s = slirp_socket(af, SOCK_STREAM, 0); if (ret >= 0) { + ret = slirp_bind_outbound(so, af); + if (ret < 0) { + // bind failed - close socket + closesocket(so->s); + so->s = -1; + return (ret); + } + } + + if (ret >= 0) { int opt, s = so->s; struct sockaddr_storage addr; @@ -575,6 +585,9 @@ * more checks are needed here * * XXX Assumes the whole command came in one packet + * XXX If there is more than one command in the packet, the others may + * be truncated. + * XXX If the command is too long, it may be truncated. * * XXX Some ftp clients will have their TOS set to * LOWDELAY and so Nagel will kick in. Because of this, @@ -639,9 +652,8 @@ } NTOHS(n1); NTOHS(n2); - m_inc(m, snprintf(NULL, 0, "%d,%d\r\n", n1, n2) + 1); - m->m_len = snprintf(m->m_data, M_ROOM(m), "%d,%d\r\n", n1, n2); - assert(m->m_len < M_ROOM(m)); + m_inc(m, g_snprintf(NULL, 0, "%d,%d\r\n", n1, n2) + 1); + m->m_len = slirp_fmt(m->m_data, M_ROOM(m), "%d,%d\r\n", n1, n2); } else { *eol = '\r'; } @@ -681,9 +693,9 @@ n4 = (laddr & 0xff); m->m_len = bptr - m->m_data; /* Adjust length */ - m->m_len += snprintf(bptr, m->m_size - m->m_len, - "ORT %d,%d,%d,%d,%d,%d\r\n%s", n1, n2, n3, n4, - n5, n6, x == 7 ? buff : ""); + m->m_len += slirp_fmt(bptr, M_FREEROOM(m), + "ORT %d,%d,%d,%d,%d,%d\r\n%s", + n1, n2, n3, n4, n5, n6, x == 7 ? buff : ""); return 1; } else if ((bptr = (char *)strstr(m->m_data, "27 Entering")) != NULL) { /* @@ -716,11 +728,9 @@ n4 = (laddr & 0xff); m->m_len = bptr - m->m_data; /* Adjust length */ - m->m_len += - snprintf(bptr, m->m_size - m->m_len, - "27 Entering Passive Mode (%d,%d,%d,%d,%d,%d)\r\n%s", - n1, n2, n3, n4, n5, n6, x == 7 ? buff : ""); - + m->m_len += slirp_fmt(bptr, M_FREEROOM(m), + "27 Entering Passive Mode (%d,%d,%d,%d,%d,%d)\r\n%s", + n1, n2, n3, n4, n5, n6, x == 7 ? buff : ""); return 1; } @@ -743,8 +753,8 @@ if (m->m_data[m->m_len - 1] == '\0' && lport != 0 && (so = tcp_listen(slirp, INADDR_ANY, 0, so->so_laddr.s_addr, htons(lport), SS_FACCEPTONCE)) != NULL) - m->m_len = - snprintf(m->m_data, m->m_size, "%d", ntohs(so->so_fport)) + 1; + m->m_len = slirp_fmt0(m->m_data, M_ROOM(m), + "%d", ntohs(so->so_fport)); return 1; case EMU_IRC: @@ -763,9 +773,10 @@ return 1; } m->m_len = bptr - m->m_data; /* Adjust length */ - m->m_len += snprintf(bptr, m->m_size, "DCC CHAT chat %lu %u%c\n", - (unsigned long)ntohl(so->so_faddr.s_addr), - ntohs(so->so_fport), 1); + m->m_len += slirp_fmt(bptr, M_FREEROOM(m), + "DCC CHAT chat %lu %u%c\n", + (unsigned long)ntohl(so->so_faddr.s_addr), + ntohs(so->so_fport), 1); } else if (sscanf(bptr, "DCC SEND %256s %u %u %u", buff, &laddr, &lport, &n1) == 4) { if ((so = tcp_listen(slirp, INADDR_ANY, 0, htonl(laddr), @@ -773,10 +784,10 @@ return 1; } m->m_len = bptr - m->m_data; /* Adjust length */ - m->m_len += - snprintf(bptr, m->m_size, "DCC SEND %s %lu %u %u%c\n", buff, - (unsigned long)ntohl(so->so_faddr.s_addr), - ntohs(so->so_fport), n1, 1); + m->m_len += slirp_fmt(bptr, M_FREEROOM(m), + "DCC SEND %s %lu %u %u%c\n", buff, + (unsigned long)ntohl(so->so_faddr.s_addr), + ntohs(so->so_fport), n1, 1); } else if (sscanf(bptr, "DCC MOVE %256s %u %u %u", buff, &laddr, &lport, &n1) == 4) { if ((so = tcp_listen(slirp, INADDR_ANY, 0, htonl(laddr), @@ -784,10 +795,10 @@ return 1; } m->m_len = bptr - m->m_data; /* Adjust length */ - m->m_len += - snprintf(bptr, m->m_size, "DCC MOVE %s %lu %u %u%c\n", buff, - (unsigned long)ntohl(so->so_faddr.s_addr), - ntohs(so->so_fport), n1, 1); + m->m_len += slirp_fmt(bptr, M_FREEROOM(m), + "DCC MOVE %s %lu %u %u%c\n", buff, + (unsigned long)ntohl(so->so_faddr.s_addr), + ntohs(so->so_fport), n1, 1); } return 1; @@ -871,6 +882,9 @@ break; case 5: + if (bptr == m->m_data + m->m_len - 1) + return 1; /* We need two bytes */ + /* * The difference between versions 1.0 and * 2.0 is here. For future versions of @@ -886,6 +900,10 @@ /* This is the field containing the port * number that RA-player is listening to. */ + + if (bptr == m->m_data + m->m_len - 1) + return 1; /* We need two bytes */ + lport = (((uint8_t *)bptr)[0] << 8) + ((uint8_t *)bptr)[1]; if (lport < 6970) lport += 256; /* don't know why */ @@ -948,13 +966,15 @@ return 1; } DEBUG_MISC(" executing %s", ex_ptr->ex_exec); - return fork_exec(so, ex_ptr->ex_exec); + if (ex_ptr->ex_unix) + return open_unix(so, ex_ptr->ex_unix); + else + return fork_exec(so, ex_ptr->ex_exec); } } } - sb->sb_cc = - snprintf(sb->sb_wptr, sb->sb_datalen - (sb->sb_wptr - sb->sb_data), - "Error: No application configured.\r\n"); + sb->sb_cc = slirp_fmt(sb->sb_wptr, sb->sb_datalen - (sb->sb_wptr - sb->sb_data), + "Error: No application configured.\r\n"); sb->sb_wptr += sb->sb_cc; return 0; } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/slirp4netns-0.4.3/vendor/libslirp/src/tftp.c new/slirp4netns-0.4.4/vendor/libslirp/src/tftp.c --- old/slirp4netns-0.4.3/vendor/libslirp/src/tftp.c 2019-12-18 03:34:42.000000000 +0100 +++ new/slirp4netns-0.4.4/vendor/libslirp/src/tftp.c 2020-03-19 01:38:45.000000000 +0100 @@ -185,16 +185,11 @@ tp->tp_op = htons(TFTP_OACK); for (i = 0; i < nb; i++) { - n += snprintf(tp->x.tp_buf + n, sizeof(tp->x.tp_buf) - n, "%s", - keys[i]) + - 1; - n += snprintf(tp->x.tp_buf + n, sizeof(tp->x.tp_buf) - n, "%u", - values[i]) + - 1; + n += slirp_fmt0(tp->x.tp_buf + n, sizeof(tp->x.tp_buf) - n, "%s", keys[i]); + n += slirp_fmt0(tp->x.tp_buf + n, sizeof(tp->x.tp_buf) - n, "%u", values[i]); } - m->m_len = sizeof(struct tftp_t) - (TFTP_BLOCKSIZE_MAX + 2) + n - - sizeof(struct udphdr); + m->m_len = G_SIZEOF_MEMBER(struct tftp_t, tp_op) + n; tftp_udp_output(spt, m, recv_tp); return 0; @@ -344,8 +339,13 @@ k += 6; /* skipping octet */ /* do sanity checks on the filename */ - if (!strncmp(req_fname, "../", 3) || - req_fname[strlen(req_fname) - 1] == '/' || strstr(req_fname, "/../")) { + if ( +#ifdef G_OS_WIN32 + strstr(req_fname, "..\\") || + req_fname[strlen(req_fname) - 1] == '\\' || +#endif + strstr(req_fname, "../") || + req_fname[strlen(req_fname) - 1] == '/') { tftp_send_error(spt, 2, "Access violation", tp); return; } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/slirp4netns-0.4.3/vendor/libslirp/src/udp.c new/slirp4netns-0.4.4/vendor/libslirp/src/udp.c --- old/slirp4netns-0.4.3/vendor/libslirp/src/udp.c 2019-12-18 03:34:42.000000000 +0100 +++ new/slirp4netns-0.4.4/vendor/libslirp/src/udp.c 2020-03-19 01:38:45.000000000 +0100 @@ -279,6 +279,12 @@ { so->s = slirp_socket(af, SOCK_DGRAM, 0); if (so->s != -1) { + if (slirp_bind_outbound(so, af) != 0) { + // bind failed - close socket + closesocket(so->s); + so->s = -1; + return -1; + } so->so_expire = curtime + SO_EXPIRE; insque(so, &so->slirp->udb); } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/slirp4netns-0.4.3/vendor/libslirp/src/util.c new/slirp4netns-0.4.4/vendor/libslirp/src/util.c --- old/slirp4netns-0.4.3/vendor/libslirp/src/util.c 2019-12-18 03:34:42.000000000 +0100 +++ new/slirp4netns-0.4.4/vendor/libslirp/src/util.c 2020-03-19 01:38:45.000000000 +0100 @@ -364,3 +364,65 @@ } *q = '\0'; } + +static int slirp_vsnprintf(char *str, size_t size, + const char *format, va_list args) +{ + int rv = g_vsnprintf(str, size, format, args); + + if (rv < 0) { + g_error("g_vsnprintf() failed: %s", g_strerror(errno)); + } + + return rv; +} + +/* + * A snprintf()-like function that: + * - returns the number of bytes written (excluding optional \0-ending) + * - dies on error + * - warn on truncation + */ +int slirp_fmt(char *str, size_t size, const char *format, ...) +{ + va_list args; + int rv; + + va_start(args, format); + rv = slirp_vsnprintf(str, size, format, args); + va_end(args); + + if (rv > size) { + g_critical("slirp_fmt() truncation"); + } + + return MIN(rv, size); +} + +/* + * A snprintf()-like function that: + * - always \0-end (unless size == 0) + * - returns the number of bytes actually written, including \0 ending + * - dies on error + * - warn on truncation + */ +int slirp_fmt0(char *str, size_t size, const char *format, ...) +{ + va_list args; + int rv; + + va_start(args, format); + rv = slirp_vsnprintf(str, size, format, args); + va_end(args); + + if (rv >= size) { + g_critical("slirp_fmt0() truncation"); + if (size > 0) + str[size - 1] = '\0'; + rv = size; + } else { + rv += 1; /* include \0 */ + } + + return rv; +} diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/slirp4netns-0.4.3/vendor/libslirp/src/util.h new/slirp4netns-0.4.4/vendor/libslirp/src/util.h --- old/slirp4netns-0.4.3/vendor/libslirp/src/util.h 2019-12-18 03:34:42.000000000 +0100 +++ new/slirp4netns-0.4.4/vendor/libslirp/src/util.h 2020-03-19 01:38:45.000000000 +0100 @@ -24,6 +24,8 @@ #ifndef UTIL_H_ #define UTIL_H_ +#include <glib.h> + #include <stdlib.h> #include <stdio.h> #include <assert.h> @@ -61,6 +63,10 @@ }) #endif +#ifndef G_SIZEOF_MEMBER +#define G_SIZEOF_MEMBER(type, member) sizeof(((type *)0)->member) +#endif + #if defined(_WIN32) /* CONFIG_IOVEC */ #if !defined(IOV_MAX) /* XXX: to avoid duplicate with QEMU osdep.h */ struct iovec { @@ -177,4 +183,7 @@ void slirp_pstrcpy(char *buf, int buf_size, const char *str); +int slirp_fmt(char *str, size_t size, const char *format, ...) G_GNUC_PRINTF(3, 4); +int slirp_fmt0(char *str, size_t size, const char *format, ...) G_GNUC_PRINTF(3, 4); + #endif diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/slirp4netns-0.4.3/vendor/parson/parson.c new/slirp4netns-0.4.4/vendor/parson/parson.c --- old/slirp4netns-0.4.3/vendor/parson/parson.c 2019-12-18 03:34:42.000000000 +0100 +++ new/slirp4netns-0.4.4/vendor/parson/parson.c 2020-03-19 01:38:45.000000000 +0100 @@ -1,7 +1,7 @@ /* SPDX-License-Identifier: MIT - Parson ( http://kgabis.github.com/parson/ ) + Parson 1.0.2 ( http://kgabis.github.com/parson/ ) Copyright (c) 2012 - 2019 Krzysztof Gabis Permission is hereby granted, free of charge, to any person obtaining a copy @@ -156,7 +156,7 @@ return NULL; } output_string[n] = '\0'; - strncpy(output_string, string, n); + memcpy(output_string, string, n); return output_string; } @@ -1496,7 +1496,7 @@ size_t json_serialization_size(const JSON_Value *value) { char num_buf[NUM_BUF_SIZE]; /* recursively allocating buffer on stack is a bad idea, so let's do it only once */ int res = json_serialize_to_buffer_r(value, NULL, 0, 0, num_buf); - return res < 0 ? 0 : (size_t)(res + 1); + return res < 0 ? 0 : (size_t)(res) + 1; } JSON_Status json_serialize_to_buffer(const JSON_Value *value, char *buf, size_t buf_size_in_bytes) { @@ -1556,7 +1556,7 @@ size_t json_serialization_size_pretty(const JSON_Value *value) { char num_buf[NUM_BUF_SIZE]; /* recursively allocating buffer on stack is a bad idea, so let's do it only once */ int res = json_serialize_to_buffer_r(value, NULL, 0, 1, num_buf); - return res < 0 ? 0 : (size_t)(res + 1); + return res < 0 ? 0 : (size_t)(res) + 1; } JSON_Status json_serialize_to_buffer_pretty(const JSON_Value *value, char *buf, size_t buf_size_in_bytes) { @@ -1776,19 +1776,39 @@ } JSON_Status json_object_set_string(JSON_Object *object, const char *name, const char *string) { - return json_object_set_value(object, name, json_value_init_string(string)); + JSON_Value *value = json_value_init_string(string); + JSON_Status status = json_object_set_value(object, name, value); + if (status == JSONFailure) { + json_value_free(value); + } + return status; } JSON_Status json_object_set_number(JSON_Object *object, const char *name, double number) { - return json_object_set_value(object, name, json_value_init_number(number)); + JSON_Value *value = json_value_init_number(number); + JSON_Status status = json_object_set_value(object, name, value); + if (status == JSONFailure) { + json_value_free(value); + } + return status; } JSON_Status json_object_set_boolean(JSON_Object *object, const char *name, int boolean) { - return json_object_set_value(object, name, json_value_init_boolean(boolean)); + JSON_Value *value = json_value_init_boolean(boolean); + JSON_Status status = json_object_set_value(object, name, value); + if (status == JSONFailure) { + json_value_free(value); + } + return status; } JSON_Status json_object_set_null(JSON_Object *object, const char *name) { - return json_object_set_value(object, name, json_value_init_null()); + JSON_Value *value = json_value_init_null(); + JSON_Status status = json_object_set_value(object, name, value); + if (status == JSONFailure) { + json_value_free(value); + } + return status; } JSON_Status json_object_dotset_value(JSON_Object *object, const char *name, JSON_Value *value) { diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/slirp4netns-0.4.3/vendor/parson/parson.h new/slirp4netns-0.4.4/vendor/parson/parson.h --- old/slirp4netns-0.4.3/vendor/parson/parson.h 2019-12-18 03:34:42.000000000 +0100 +++ new/slirp4netns-0.4.4/vendor/parson/parson.h 2020-03-19 01:38:45.000000000 +0100 @@ -1,7 +1,7 @@ /* SPDX-License-Identifier: MIT - Parson ( http://kgabis.github.com/parson/ ) + Parson 1.0.2 ( http://kgabis.github.com/parson/ ) Copyright (c) 2012 - 2019 Krzysztof Gabis Permission is hereby granted, free of charge, to any person obtaining a copy diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/slirp4netns-0.4.3/vendor.sh new/slirp4netns-0.4.4/vendor.sh --- old/slirp4netns-0.4.3/vendor.sh 2019-12-18 03:34:42.000000000 +0100 +++ new/slirp4netns-0.4.4/vendor.sh 2020-03-19 01:38:45.000000000 +0100 @@ -1,11 +1,11 @@ #!/bin/bash set -eux -o pipefail -# Dec 4, 2019 (v4.1.0) -LIBSLIRP_COMMIT=6651ba26c4e94f64d6448a2db4991269ce553bd9 +# Mar 17, 2020 (v4.2.0) +LIBSLIRP_COMMIT=daba14c3416fa9641ab4453a9a11e7f8bde08875 LIBSLIRP_REPO=https://gitlab.freedesktop.org/slirp/libslirp.git -# Jul 12, 2019 -PARSON_COMMIT=c5bb9557fe98367aa8e041c65863909f12ee76b2 +# Feb 21, 2020 +PARSON_COMMIT=70dc239f8f54c80bf58477b25435fd3dd3102804 PARSON_REPO=https://github.com/kgabis/parson.git # prepare
