Date: Fri, 11 Sep 2020 12:36:06 +0000 (UTC) From: "Bjoern A. Zeeb" <bz@FreeBSD.org> To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-12@freebsd.org Subject: svn commit: r365630 - in stable/12: sbin/rtsol usr.sbin/rtsold Message-ID: <202009111236.08BCa6VP030719@repo.freebsd.org>
next in thread | raw e-mail | index | archive | help
Author: bz Date: Fri Sep 11 12:36:05 2020 New Revision: 365630 URL: https://svnweb.freebsd.org/changeset/base/365630 Log: MFC r342788,354926,364771 (markj, bz) - Capsicumize rtsol(8) and rtsold(8). - Avoid relying on pollution from libcasper.h. - Add script for "M bit". Added: stable/12/usr.sbin/rtsold/cap_llflags.c - copied, changed from r342788, head/usr.sbin/rtsold/cap_llflags.c stable/12/usr.sbin/rtsold/cap_script.c - copied unchanged from r342788, head/usr.sbin/rtsold/cap_script.c stable/12/usr.sbin/rtsold/cap_sendmsg.c - copied unchanged from r342788, head/usr.sbin/rtsold/cap_sendmsg.c Deleted: stable/12/usr.sbin/rtsold/probe.c Modified: stable/12/sbin/rtsol/Makefile stable/12/usr.sbin/rtsold/Makefile stable/12/usr.sbin/rtsold/dump.c stable/12/usr.sbin/rtsold/if.c stable/12/usr.sbin/rtsold/rtsock.c stable/12/usr.sbin/rtsold/rtsol.c stable/12/usr.sbin/rtsold/rtsold.8 stable/12/usr.sbin/rtsold/rtsold.c stable/12/usr.sbin/rtsold/rtsold.h Directory Properties: stable/12/ (props changed) Modified: stable/12/sbin/rtsol/Makefile ============================================================================== --- stable/12/sbin/rtsol/Makefile Fri Sep 11 10:11:04 2020 (r365629) +++ stable/12/sbin/rtsol/Makefile Fri Sep 11 12:36:05 2020 (r365630) @@ -18,10 +18,24 @@ PACKAGE=runtime PROG= rtsol -SRCS= rtsold.c rtsol.c if.c probe.c dump.c rtsock.c +SRCS= cap_llflags.c \ + cap_script.c \ + cap_sendmsg.c \ + dump.c \ + if.c \ + rtsol.c \ + rtsold.c \ + rtsock.c MAN= +LIBADD= util -WARNS?= 3 -CFLAGS+= -DSMALL +.include <src.opts.mk> + +.if ${MK_DYNAMICROOT} == "no" +.warning ${PROG} built without libcasper support +.elif ${MK_CASPER} != "no" && !defined(RESCUE) +CFLAGS+= -DWITH_CASPER +LIBADD+= cap_syslog casper nv +.endif .include <bsd.prog.mk> Modified: stable/12/usr.sbin/rtsold/Makefile ============================================================================== --- stable/12/usr.sbin/rtsold/Makefile Fri Sep 11 10:11:04 2020 (r365629) +++ stable/12/usr.sbin/rtsold/Makefile Fri Sep 11 12:36:05 2020 (r365630) @@ -17,8 +17,22 @@ PROG= rtsold MAN= rtsold.8 MLINKS= rtsold.8 rtsol.8 -SRCS= rtsold.c rtsol.c if.c probe.c dump.c rtsock.c +SRCS= cap_llflags.c \ + cap_script.c \ + cap_sendmsg.c \ + dump.c \ + if.c \ + rtsock.c \ + rtsol.c \ + rtsold.c -WARNS?= 3 +LIBADD= util + +.include <src.opts.mk> + +.if ${MK_CASPER} != "no" +CFLAGS+= -DWITH_CASPER +LIBADD+= casper cap_syslog nv +.endif .include <bsd.prog.mk> Copied and modified: stable/12/usr.sbin/rtsold/cap_llflags.c (from r342788, head/usr.sbin/rtsold/cap_llflags.c) ============================================================================== --- head/usr.sbin/rtsold/cap_llflags.c Sat Jan 5 16:05:39 2019 (r342788, copy source) +++ stable/12/usr.sbin/rtsold/cap_llflags.c Fri Sep 11 12:36:05 2020 (r365630) @@ -44,6 +44,7 @@ __FBSDID("$FreeBSD$"); #include <errno.h> #include <ifaddrs.h> #include <string.h> +#include <unistd.h> #include <libcasper.h> #include <libcasper_service.h> Copied: stable/12/usr.sbin/rtsold/cap_script.c (from r342788, head/usr.sbin/rtsold/cap_script.c) ============================================================================== --- /dev/null 00:00:00 1970 (empty, because file is newly added) +++ stable/12/usr.sbin/rtsold/cap_script.c Fri Sep 11 12:36:05 2020 (r365630, copy of r342788, head/usr.sbin/rtsold/cap_script.c) @@ -0,0 +1,236 @@ +/*- + * SPDX-License-Identifier: BSD-2-Clause + * + * Copyright (c) 2018 The FreeBSD Foundation + * + * This software was developed by Mark Johnston under sponsorship from + * the FreeBSD Foundation. + * + * 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 AUTHOR 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 AUTHOR 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/cdefs.h> +__FBSDID("$FreeBSD$"); + +#include <sys/types.h> +#include <sys/capsicum.h> +#include <sys/dnv.h> +#include <sys/nv.h> +#include <sys/queue.h> +#include <sys/wait.h> + +#include <net/if.h> +#include <netinet/in.h> + +#include <capsicum_helpers.h> +#include <errno.h> +#include <stdlib.h> +#include <string.h> +#include <unistd.h> + +#include <libcasper.h> +#include <libcasper_service.h> + +#include "rtsold.h" + +/* + * Run the script and return the write end of a pipe to the main process. + * Return -1 and set errno on error. + */ +static int +script_run(char **argv) +{ + pid_t pid; + int fd[2], null; + + if (pipe(fd) != 0) + return (-1); + if ((pid = fork()) < 0) + return (-1); + if (pid == 0) { + (void)close(fd[1]); + null = open("/dev/null", O_RDWR); + if (null < 0) + _exit(1); + if (dup2(fd[0], STDIN_FILENO) != STDIN_FILENO) + _exit(1); + + closefrom(3); + (void)execve(argv[0], argv, NULL); + _exit(1); + } else + (void)close(fd[0]); + + return (fd[1]); +} + +int +cap_script_run(cap_channel_t *cap, const char *const *argv) +{ +#ifdef WITH_CASPER + nvlist_t *nvl; + size_t argc; + int error, wfd; + + for (argc = 0; argv[argc] != NULL; argc++) + ; + + nvl = nvlist_create(0); + nvlist_add_string(nvl, "cmd", "script_run"); + nvlist_add_string_array(nvl, "argv", argv, argc); + nvl = cap_xfer_nvlist(cap, nvl); + if (nvl == NULL) + return (-1); + + error = (int)dnvlist_get_number(nvl, "error", 0); + if (error == 0) + wfd = nvlist_take_descriptor(nvl, "fd"); + nvlist_destroy(nvl); + if (error != 0) + errno = error; + return (error == 0 ? wfd : -1); +#else + (void)cap; + return (script_run(__DECONST(char **, argv))); +#endif +} + +/* + * Wait for a child process to exit, and return its status. + * Return -1 and set errno upon error. + */ +static int +script_wait(int *statusp) +{ + int error; + + error = wait(statusp); + return (error >= 0 ? 0 : -1); +} + +int +cap_script_wait(cap_channel_t *cap, int *statusp) +{ +#ifdef WITH_CASPER + nvlist_t *nvl; + int error; + + nvl = nvlist_create(0); + nvlist_add_string(nvl, "cmd", "script_wait"); + nvl = cap_xfer_nvlist(cap, nvl); + if (nvl == NULL) + return (-1); + + error = (int)dnvlist_get_number(nvl, "error", 0); + if (error == 0) + *statusp = (int)nvlist_get_number(nvl, "status"); + nvlist_destroy(nvl); + if (error != 0) + errno = error; + return (error == 0 ? 0 : -1); +#else + (void)cap; + return (script_wait(statusp)); +#endif +} + +#ifdef WITH_CASPER +static int +script_command(const char *cmd, const nvlist_t *limits, nvlist_t *nvlin, + nvlist_t *nvlout) +{ + cap_rights_t rights; + const char *const *iargv, *const *scripts; + char **argv; + size_t argc, i, nscripts; + int fd, status; + + if (strcmp(cmd, "script_wait") == 0) { + /* Wait for the result of a previous "script_run" command. */ + if (script_wait(&status) == -1) + return (errno); + nvlist_add_number(nvlout, "status", status); + return (0); + } + if (strcmp(cmd, "script_run") != 0) + return (EINVAL); + + /* + * Validate the argv against the limits specified at initialization + * time. + */ + iargv = nvlist_get_string_array(nvlin, "argv", &argc); + if (argc == 0) + return (EINVAL); + scripts = nvlist_get_string_array(limits, "scripts", &nscripts); + for (i = 0; i < nscripts; i++) + if (strcmp(iargv[0], scripts[i]) == 0) + break; + if (i == nscripts) + return (EINVAL); + + /* + * The nvlist API does not permit NULL pointers in an array, so we have + * to add the nul terminator ourselves. Yuck. + */ + argv = calloc(argc + 1, sizeof(*argv)); + if (argv == NULL) + return (errno); + memcpy(argv, iargv, sizeof(*argv) * argc); + + fd = script_run(argv); + if (fd < 0) + return (errno); + + (void)caph_rights_limit(fd, cap_rights_init(&rights, CAP_WRITE)); + nvlist_move_descriptor(nvlout, "fd", fd); + return (0); +} + +static int +script_limit(const nvlist_t *oldlimits, const nvlist_t *newlimits __unused) +{ + const char *name; + void *cookie; + int nvtype; + bool hasscripts; + + /* Limits may only be set once. */ + if (oldlimits != NULL) + return (ENOTCAPABLE); + + cookie = NULL; + hasscripts = false; + while ((name = nvlist_next(newlimits, &nvtype, &cookie)) != NULL) { + if (nvtype == NV_TYPE_STRING_ARRAY && + strcmp(name, "scripts") == 0) + hasscripts = true; + else + return (EINVAL); + } + if (!hasscripts) + return (EINVAL); + return (0); +} + +CREATE_SERVICE("rtsold.script", script_limit, script_command, 0); +#endif /* WITH_CASPER */ Copied: stable/12/usr.sbin/rtsold/cap_sendmsg.c (from r342788, head/usr.sbin/rtsold/cap_sendmsg.c) ============================================================================== --- /dev/null 00:00:00 1970 (empty, because file is newly added) +++ stable/12/usr.sbin/rtsold/cap_sendmsg.c Fri Sep 11 12:36:05 2020 (r365630, copy of r342788, head/usr.sbin/rtsold/cap_sendmsg.c) @@ -0,0 +1,282 @@ +/* $KAME: probe.c,v 1.17 2003/10/05 00:09:36 itojun Exp $ */ + +/*- + * SPDX-License-Identifier: BSD-3-Clause + * + * Copyright (C) 1998 WIDE Project. + * All rights reserved. + * + * 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. + * 3. Neither the name of the project nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE PROJECT 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 PROJECT 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. + * + * $FreeBSD$ + */ + +#include <sys/param.h> +#include <sys/capsicum.h> +#include <sys/dnv.h> +#include <sys/nv.h> +#include <sys/socket.h> +#include <sys/sysctl.h> + +#include <net/if.h> +#include <net/if_dl.h> + +#include <netinet/in.h> +#include <netinet6/in6_var.h> +#include <netinet/icmp6.h> +#include <netinet6/nd6.h> + +#include <arpa/inet.h> + +#include <capsicum_helpers.h> +#include <errno.h> +#include <stdlib.h> +#include <string.h> +#include <syslog.h> +#include <unistd.h> + +#include <libcasper.h> +#include <libcasper_service.h> + +#include "rtsold.h" + +static int +getsocket(int *sockp, int proto) +{ + cap_rights_t rights; + int sock; + + if (*sockp >= 0) + return (0); + + if ((sock = socket(AF_INET6, SOCK_RAW, proto)) < 0) + return (-1); + cap_rights_init(&rights, CAP_CONNECT, CAP_SEND); + if (caph_rights_limit(sock, &rights) != 0) + return (-1); + *sockp = sock; + + return (0); +} + +static ssize_t +sendpacket(int sock, struct sockaddr_in6 *dst, uint32_t ifindex, int hoplimit, + const void *data, size_t len) +{ + uint8_t cmsg[CMSG_SPACE(sizeof(struct in6_pktinfo)) + + CMSG_SPACE(sizeof(int))]; + struct msghdr hdr; + struct iovec iov; + struct in6_pktinfo *pi; + struct cmsghdr *cm; + + memset(&hdr, 0, sizeof(hdr)); + hdr.msg_name = dst; + hdr.msg_namelen = sizeof(*dst); + hdr.msg_iov = &iov; + hdr.msg_iovlen = 1; + hdr.msg_control = cmsg; + hdr.msg_controllen = sizeof(cmsg); + + iov.iov_base = __DECONST(void *, data); + iov.iov_len = len; + + /* Specify the outbound interface. */ + cm = CMSG_FIRSTHDR(&hdr); + cm->cmsg_level = IPPROTO_IPV6; + cm->cmsg_type = IPV6_PKTINFO; + cm->cmsg_len = CMSG_LEN(sizeof(struct in6_pktinfo)); + pi = (struct in6_pktinfo *)(void *)CMSG_DATA(cm); + memset(&pi->ipi6_addr, 0, sizeof(pi->ipi6_addr)); /*XXX*/ + pi->ipi6_ifindex = ifindex; + + /* Specify the hop limit of the packet for safety. */ + cm = CMSG_NXTHDR(&hdr, cm); + cm->cmsg_level = IPPROTO_IPV6; + cm->cmsg_type = IPV6_HOPLIMIT; + cm->cmsg_len = CMSG_LEN(sizeof(int)); + memcpy(CMSG_DATA(cm), &hoplimit, sizeof(int)); + + return (sendmsg(sock, &hdr, 0)); +} + +static int +probe_defrouters(uint32_t ifindex, uint32_t linkid) +{ + static int probesock = -1; + struct sockaddr_in6 dst; + struct in6_defrouter *p, *ep; + char *buf; + size_t len; + int mib[4]; + + if (ifindex == 0) + return (0); + if (getsocket(&probesock, IPPROTO_NONE) != 0) + return (-1); + + mib[0] = CTL_NET; + mib[1] = PF_INET6; + mib[2] = IPPROTO_ICMPV6; + mib[3] = ICMPV6CTL_ND6_DRLIST; + if (sysctl(mib, nitems(mib), NULL, &len, NULL, 0) < 0) + return (-1); + if (len == 0) + return (0); + + memset(&dst, 0, sizeof(dst)); + dst.sin6_family = AF_INET6; + dst.sin6_len = sizeof(dst); + + buf = malloc(len); + if (buf == NULL) + return (-1); + if (sysctl(mib, nitems(mib), buf, &len, NULL, 0) < 0) + return (-1); + ep = (struct in6_defrouter *)(void *)(buf + len); + for (p = (struct in6_defrouter *)(void *)buf; p < ep; p++) { + if (ifindex != p->if_index) + continue; + if (!IN6_IS_ADDR_LINKLOCAL(&p->rtaddr.sin6_addr)) + continue; + dst.sin6_addr = p->rtaddr.sin6_addr; + dst.sin6_scope_id = linkid; + (void)sendpacket(probesock, &dst, ifindex, 1, NULL, 0); + } + free(buf); + + return (0); +} + +static int +rssend(uint32_t ifindex, uint32_t linkid, const void *data, size_t len) +{ + static int rssock = -1; + struct sockaddr_in6 dst; + ssize_t n; + + if (getsocket(&rssock, IPPROTO_ICMPV6) != 0) + return (-1); + + memset(&dst, 0, sizeof(dst)); + dst.sin6_family = AF_INET6; + dst.sin6_len = sizeof(dst); + dst.sin6_addr = (struct in6_addr)IN6ADDR_LINKLOCAL_ALLROUTERS_INIT; + dst.sin6_scope_id = linkid; + + n = sendpacket(rssock, &dst, ifindex, 255, data, len); + if (n < 0 || (size_t)n != len) + return (-1); + return (0); +} + +int +cap_probe_defrouters(cap_channel_t *cap, struct ifinfo *ifinfo) +{ +#ifdef WITH_CASPER + nvlist_t *nvl; + int error; + + nvl = nvlist_create(0); + nvlist_add_string(nvl, "cmd", "probe_defrouters"); + nvlist_add_number(nvl, "ifindex", ifinfo->sdl->sdl_index); + nvlist_add_number(nvl, "linkid", ifinfo->linkid); + + nvl = cap_xfer_nvlist(cap, nvl); + if (nvl == NULL) + return (errno); + error = (int)dnvlist_get_number(nvl, "error", 0); + nvlist_destroy(nvl); + errno = error; + return (error == 0 ? 0 : -1); +#else + (void)cap; + return (probe_defrouters(ifinfo->sdl->sdl_index, ifinfo->linkid)); +#endif +} + +int +cap_rssend(cap_channel_t *cap, struct ifinfo *ifinfo) +{ + int error; + +#ifdef WITH_CASPER + nvlist_t *nvl = nvlist_create(0); + nvlist_add_string(nvl, "cmd", "rssend"); + nvlist_add_number(nvl, "ifindex", ifinfo->sdl->sdl_index); + nvlist_add_number(nvl, "linkid", ifinfo->linkid); + nvlist_add_binary(nvl, "data", ifinfo->rs_data, ifinfo->rs_datalen); + + nvl = cap_xfer_nvlist(cap, nvl); + if (nvl == NULL) + return (errno); + error = (int)dnvlist_get_number(nvl, "error", 0); + nvlist_destroy(nvl); + errno = error; +#else + (void)cap; + error = rssend(ifinfo->sdl->sdl_index, ifinfo->linkid, ifinfo->rs_data, + ifinfo->rs_datalen); +#endif + + ifinfo->probes++; + if (error != 0 && (errno != ENETDOWN || dflag > 0)) { + error = errno; + warnmsg(LOG_ERR, __func__, "sendmsg on %s: %s", + ifinfo->ifname, strerror(errno)); + errno = error; + } + return (error == 0 ? 0 : -1); +} + +#ifdef WITH_CASPER +static int +sendmsg_command(const char *cmd, const nvlist_t *limits __unused, nvlist_t *nvlin, + nvlist_t *nvlout __unused) +{ + const void *data; + size_t len; + uint32_t ifindex, linkid; + int error; + + if (strcmp(cmd, "probe_defrouters") != 0 && + strcmp(cmd, "rssend") != 0) + return (EINVAL); + + ifindex = (uint32_t)nvlist_get_number(nvlin, "ifindex"); + linkid = (uint32_t)nvlist_get_number(nvlin, "linkid"); + if (strcmp(cmd, "probe_defrouters") == 0) { + error = probe_defrouters(ifindex, linkid); + } else { + data = nvlist_get_binary(nvlin, "data", &len); + error = rssend(ifindex, linkid, data, len); + } + if (error != 0) + return (errno); + return (0); +} + +CREATE_SERVICE("rtsold.sendmsg", NULL, sendmsg_command, 0); +#endif /* WITH_CASPER */ Modified: stable/12/usr.sbin/rtsold/dump.c ============================================================================== --- stable/12/usr.sbin/rtsold/dump.c Fri Sep 11 10:11:04 2020 (r365629) +++ stable/12/usr.sbin/rtsold/dump.c Fri Sep 11 12:36:05 2020 (r365630) @@ -34,6 +34,7 @@ */ #include <sys/types.h> +#include <sys/capsicum.h> #include <sys/socket.h> #include <sys/queue.h> @@ -42,21 +43,20 @@ #include <netinet/icmp6.h> #include <arpa/inet.h> -#include <syslog.h> -#include <time.h> +#include <capsicum_helpers.h> +#include <errno.h> #include <stdio.h> #include <string.h> -#include <errno.h> +#include <syslog.h> +#include <time.h> #include "rtsold.h" -static FILE *fp; +static const char * const ifstatstr[] = + { "IDLE", "DELAY", "PROBE", "DOWN", "TENTATIVE" }; -static void dump_interface_status(void); -static const char * const ifstatstr[] = {"IDLE", "DELAY", "PROBE", "DOWN", "TENTATIVE"}; - -static void -dump_interface_status(void) +void +rtsold_dump(FILE *fp) { struct ifinfo *ifi; struct rainfo *rai; @@ -64,8 +64,14 @@ dump_interface_status(void) struct timespec now; char ntopbuf[INET6_ADDRSTRLEN]; - clock_gettime(CLOCK_MONOTONIC_FAST, &now); + if (fseek(fp, 0, SEEK_SET) != 0) { + warnmsg(LOG_ERR, __func__, "fseek(): %s", strerror(errno)); + return; + } + (void)ftruncate(fileno(fp), 0); + (void)clock_gettime(CLOCK_MONOTONIC_FAST, &now); + TAILQ_FOREACH(ifi, &ifinfo_head, ifi_next) { fprintf(fp, "Interface %s\n", ifi->ifname); fprintf(fp, " probe interval: "); @@ -78,6 +84,8 @@ dump_interface_status(void) } fprintf(fp, " interface status: %s\n", ifi->active > 0 ? "active" : "inactive"); + fprintf(fp, " managed config: %s\n", + ifi->managedconfig ? "on" : "off"); fprintf(fp, " other config: %s\n", ifi->otherconfig ? "on" : "off"); fprintf(fp, " rtsold status: %s\n", ifstatstr[ifi->state]); @@ -121,18 +129,28 @@ dump_interface_status(void) fprintf(fp, "\n"); } } + fflush(fp); } -void -rtsold_dump_file(const char *dumpfile) +FILE * +rtsold_init_dumpfile(const char *dumpfile) { + cap_rights_t rights; + FILE *fp; + if ((fp = fopen(dumpfile, "w")) == NULL) { - warnmsg(LOG_WARNING, __func__, "open a dump file(%s): %s", + warnmsg(LOG_WARNING, __func__, "opening a dump file(%s): %s", dumpfile, strerror(errno)); - return; + return (NULL); } - dump_interface_status(); - fclose(fp); + + cap_rights_init(&rights, CAP_FSTAT, CAP_FTRUNCATE, CAP_SEEK, CAP_WRITE); + if (caph_rights_limit(fileno(fp), &rights) != 0) { + warnmsg(LOG_WARNING, __func__, "caph_rights_limit(%s): %s", + dumpfile, strerror(errno)); + return (NULL); + } + return (fp); } const char * Modified: stable/12/usr.sbin/rtsold/if.c ============================================================================== --- stable/12/usr.sbin/rtsold/if.c Fri Sep 11 10:11:04 2020 (r365629) +++ stable/12/usr.sbin/rtsold/if.c Fri Sep 11 12:36:05 2020 (r365630) @@ -34,10 +34,11 @@ */ #include <sys/param.h> -#include <sys/socket.h> -#include <sys/sysctl.h> +#include <sys/capsicum.h> #include <sys/ioctl.h> #include <sys/queue.h> +#include <sys/socket.h> +#include <sys/sysctl.h> #include <net/if.h> #include <net/if_types.h> @@ -51,6 +52,7 @@ #include <netinet6/in6_var.h> #include <netinet6/nd6.h> +#include <capsicum_helpers.h> #include <stdio.h> #include <unistd.h> #include <stdlib.h> @@ -63,16 +65,28 @@ #include "rtsold.h" static int ifsock; - -static int get_llflag(const char *); static void get_rtaddrs(int, struct sockaddr *, struct sockaddr **); int ifinit(void) { - ifsock = rssock; + cap_rights_t rights; + int sock; - return(0); + sock = socket(AF_INET6, SOCK_RAW, IPPROTO_ICMPV6); + if (sock < 0) { + warnmsg(LOG_ERR, __func__, "socket(): %s", + strerror(errno)); + return (-1); + } + if (caph_rights_limit(sock, cap_rights_init(&rights, CAP_IOCTL)) < 0) { + warnmsg(LOG_ERR, __func__, "caph_rights_limit(): %s", + strerror(errno)); + (void)close(sock); + return (-1); + } + ifsock = sock; + return (0); } int @@ -150,10 +164,9 @@ interface_up(char *name) } close(s); - llflag = get_llflag(name); - if (llflag < 0) { + if (cap_llflags_get(capllflags, name, &llflag) != 0) { warnmsg(LOG_WARNING, __func__, - "get_llflag() failed, anyway I'll try"); + "cap_llflags_get() failed, anyway I'll try"); return (0); } @@ -273,8 +286,6 @@ lladdropt_fill(struct sockaddr_dl *sdl, struct nd_opt_ "unsupported link type(%d)", sdl->sdl_type); exit(1); } - - return; } struct sockaddr_dl * @@ -331,58 +342,6 @@ if_nametosdl(char *name) free(buf); return (ret_sdl); } - -/*------------------------------------------------------------*/ - -/* get ia6_flags for link-local addr on if. returns -1 on error. */ -static int -get_llflag(const char *name) -{ - struct ifaddrs *ifap, *ifa; - struct in6_ifreq ifr6; - struct sockaddr_in6 *sin6; - int s; - - if ((s = socket(PF_INET6, SOCK_DGRAM, 0)) < 0) { - warnmsg(LOG_ERR, __func__, "socket(SOCK_DGRAM): %s", - strerror(errno)); - exit(1); - } - if (getifaddrs(&ifap) != 0) { - warnmsg(LOG_ERR, __func__, "getifaddrs: %s", - strerror(errno)); - exit(1); - } - - for (ifa = ifap; ifa; ifa = ifa->ifa_next) { - if (strlen(ifa->ifa_name) != strlen(name) || - strncmp(ifa->ifa_name, name, strlen(name)) != 0) - continue; - if (ifa->ifa_addr->sa_family != AF_INET6) - continue; - sin6 = (struct sockaddr_in6 *)(void *)ifa->ifa_addr; - if (!IN6_IS_ADDR_LINKLOCAL(&sin6->sin6_addr)) - continue; - - memset(&ifr6, 0, sizeof(ifr6)); - strlcpy(ifr6.ifr_name, name, sizeof(ifr6.ifr_name)); - memcpy(&ifr6.ifr_ifru.ifru_addr, sin6, sin6->sin6_len); - if (ioctl(s, SIOCGIFAFLAG_IN6, &ifr6) < 0) { - warnmsg(LOG_ERR, __func__, - "ioctl(SIOCGIFAFLAG_IN6): %s", strerror(errno)); - exit(1); - } - - freeifaddrs(ifap); - close(s); - return (ifr6.ifr_ifru.ifru_flags6); - } - - freeifaddrs(ifap); - close(s); - return (-1); -} - static void get_rtaddrs(int addrs, struct sockaddr *sa, struct sockaddr **rti_info) Modified: stable/12/usr.sbin/rtsold/rtsock.c ============================================================================== --- stable/12/usr.sbin/rtsold/rtsock.c Fri Sep 11 10:11:04 2020 (r365629) +++ stable/12/usr.sbin/rtsold/rtsock.c Fri Sep 11 12:36:05 2020 (r365630) @@ -33,10 +33,11 @@ */ #include <sys/param.h> +#include <sys/capsicum.h> +#include <sys/queue.h> #include <sys/socket.h> -#include <sys/uio.h> #include <sys/time.h> -#include <sys/queue.h> +#include <sys/uio.h> #include <net/if.h> #include <net/route.h> @@ -46,6 +47,7 @@ #include <netinet/ip6.h> #include <netinet/icmp6.h> +#include <capsicum_helpers.h> #include <time.h> #include <unistd.h> #include <stdio.h> @@ -72,8 +74,20 @@ static struct { int rtsock_open(void) { + cap_rights_t rights; + int error, s; - return (socket(PF_ROUTE, SOCK_RAW, 0)); + s = socket(PF_ROUTE, SOCK_RAW, 0); + if (s < 0) + return (s); + cap_rights_init(&rights, CAP_EVENT, CAP_READ); + if (caph_rights_limit(s, &rights) != 0) { + error = errno; + (void)close(s); + errno = errno; + return (-1); + } + return (s); } int Modified: stable/12/usr.sbin/rtsold/rtsol.c ============================================================================== --- stable/12/usr.sbin/rtsold/rtsol.c Fri Sep 11 10:11:04 2020 (r365629) +++ stable/12/usr.sbin/rtsold/rtsol.c Fri Sep 11 12:36:05 2020 (r365630) @@ -35,11 +35,12 @@ */ #include <sys/param.h> +#include <sys/capsicum.h> +#include <sys/queue.h> #include <sys/socket.h> +#include <sys/stat.h> #include <sys/uio.h> -#include <sys/queue.h> #include <sys/wait.h> -#include <sys/stat.h> #include <net/if.h> #include <net/route.h> @@ -54,6 +55,7 @@ #include <arpa/inet.h> +#include <capsicum_helpers.h> #include <netdb.h> #include <time.h> #include <fcntl.h> @@ -67,40 +69,24 @@ #include <syslog.h> #include "rtsold.h" -static struct msghdr rcvmhdr; -static struct msghdr sndmhdr; -static struct iovec rcviov[2]; -static struct iovec sndiov[2]; -static struct sockaddr_in6 from; -static int rcvcmsglen; - -int rssock; static char rsid[IFNAMSIZ + 1 + sizeof(DNSINFO_ORIGIN_LABEL) + 1 + NI_MAXHOST]; -struct ifinfo_head_t ifinfo_head = - TAILQ_HEAD_INITIALIZER(ifinfo_head); +struct ifinfo_head_t ifinfo_head = TAILQ_HEAD_INITIALIZER(ifinfo_head); -static const struct sockaddr_in6 sin6_allrouters = { - .sin6_len = sizeof(sin6_allrouters), - .sin6_family = AF_INET6, - .sin6_addr = IN6ADDR_LINKLOCAL_ALLROUTERS_INIT, -}; - -static void call_script(const int, const char *const *, - struct script_msg_head_t *); +static void call_script(const char *const *, struct script_msg_head_t *); static size_t dname_labeldec(char *, size_t, const char *); -static int safefile(const char *); static struct ra_opt *find_raopt(struct rainfo *, int, void *, size_t); static int ra_opt_rdnss_dispatch(struct ifinfo *, struct rainfo *, struct script_msg_head_t *, struct script_msg_head_t *); static char *make_rsid(const char *, const char *, struct rainfo *); +#define _ARGS_MANAGED managedconf_script, ifi->ifname #define _ARGS_OTHER otherconf_script, ifi->ifname #define _ARGS_RESADD resolvconf_script, "-a", rsid #define _ARGS_RESDEL resolvconf_script, "-d", rsid #define CALL_SCRIPT(name, sm_head) do { \ const char *const sarg[] = { _ARGS_##name, NULL }; \ - call_script(sizeof(sarg), sarg, sm_head); \ + call_script(sarg, sm_head); \ } while (0) #define ELM_MALLOC(p, error_action) do { \ @@ -114,130 +100,69 @@ static char *make_rsid(const char *, const char *, str } while (0) int -sockopen(void) +recvsockopen(void) { - static u_char *rcvcmsgbuf = NULL, *sndcmsgbuf = NULL; - int sndcmsglen, on; - static u_char answer[1500]; struct icmp6_filter filt; + cap_rights_t rights; + int on, sock; - sndcmsglen = rcvcmsglen = CMSG_SPACE(sizeof(struct in6_pktinfo)) + - CMSG_SPACE(sizeof(int)); - if (rcvcmsgbuf == NULL && (rcvcmsgbuf = malloc(rcvcmsglen)) == NULL) { - warnmsg(LOG_ERR, __func__, - "malloc for receive msghdr failed"); - return (-1); - } - if (sndcmsgbuf == NULL && (sndcmsgbuf = malloc(sndcmsglen)) == NULL) { - warnmsg(LOG_ERR, __func__, - "malloc for send msghdr failed"); - return (-1); - } - if ((rssock = socket(AF_INET6, SOCK_RAW, IPPROTO_ICMPV6)) < 0) { + if ((sock = socket(AF_INET6, SOCK_RAW, IPPROTO_ICMPV6)) < 0) { warnmsg(LOG_ERR, __func__, "socket: %s", strerror(errno)); - return (-1); + goto fail; } - /* specify to tell receiving interface */ + /* Provide info about the receiving interface. */ on = 1; - if (setsockopt(rssock, IPPROTO_IPV6, IPV6_RECVPKTINFO, &on, + if (setsockopt(sock, IPPROTO_IPV6, IPV6_RECVPKTINFO, &on, sizeof(on)) < 0) { - warnmsg(LOG_ERR, __func__, "IPV6_RECVPKTINFO: %s", + warnmsg(LOG_ERR, __func__, "setsockopt(IPV6_RECVPKTINFO): %s", strerror(errno)); - exit(1); + goto fail; } - /* specify to tell value of hoplimit field of received IP6 hdr */ + /* Include the hop limit from the received header. */ on = 1; - if (setsockopt(rssock, IPPROTO_IPV6, IPV6_RECVHOPLIMIT, &on, + if (setsockopt(sock, IPPROTO_IPV6, IPV6_RECVHOPLIMIT, &on, sizeof(on)) < 0) { - warnmsg(LOG_ERR, __func__, "IPV6_RECVHOPLIMIT: %s", + warnmsg(LOG_ERR, __func__, "setsockopt(IPV6_RECVHOPLIMIT): %s", strerror(errno)); *** DIFF OUTPUT TRUNCATED AT 1000 LINES ***
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?202009111236.08BCa6VP030719>