From 6bb30c2cbaed955383758c64cf51382dd1978cb9 Mon Sep 17 00:00:00 2001 From: David Lamparter Date: Fri, 10 Aug 2018 18:46:07 +0200 Subject: [PATCH] *: use frr_elevate_privs() (2/2: manual) Signed-off-by: David Lamparter --- bgpd/bgp_network.c | 41 ++++++-------------- eigrpd/eigrp_network.c | 77 +++++++++++++------------------------ ldpd/socket.c | 40 +++++++------------- lib/sockunion.c | 14 ++----- lib/vrf.c | 14 ++----- lib/zclient.c | 6 +-- ospfd/ospf_network.c | 82 ++++++++++++++++------------------------ ospfd/ospfd.c | 25 +++++------- pimd/pim_msdp_socket.c | 16 ++------ tests/lib/test_privs.c | 14 +++---- zebra/if_ioctl_solaris.c | 37 ++++++++---------- zebra/kernel_netlink.c | 68 +++++++++++++-------------------- zebra/kernel_socket.c | 16 ++------ zebra/zapi_msg.c | 7 ++-- zebra/zserv.c | 17 ++++----- 15 files changed, 170 insertions(+), 304 deletions(-) diff --git a/bgpd/bgp_network.c b/bgpd/bgp_network.c index f0d4305ba2..2bdd43c140 100644 --- a/bgpd/bgp_network.c +++ b/bgpd/bgp_network.c @@ -97,17 +97,9 @@ static int bgp_md5_set_connect(int socket, union sockunion *su, int ret = -1; #if HAVE_DECL_TCP_MD5SIG - if (bgpd_privs.change(ZPRIVS_RAISE)) { - flog_err(LIB_ERR_PRIVILEGES, "%s: could not raise privs", - __func__); - return ret; + frr_elevate_privs(&bgpd_privs) { + ret = bgp_md5_set_socket(socket, su, password); } - - ret = bgp_md5_set_socket(socket, su, password); - - if (bgpd_privs.change(ZPRIVS_LOWER)) - flog_err(LIB_ERR_PRIVILEGES, "%s: could not lower privs", - __func__); #endif /* HAVE_TCP_MD5SIG */ return ret; @@ -119,27 +111,18 @@ static int bgp_md5_set_password(struct peer *peer, const char *password) int ret = 0; struct bgp_listener *listener; - if (bgpd_privs.change(ZPRIVS_RAISE)) { - flog_err(LIB_ERR_PRIVILEGES, "%s: could not raise privs", - __func__); - return -1; - } - + frr_elevate_privs(&bgpd_privs) { /* Set or unset the password on the listen socket(s). Outbound - * connections - * are taken care of in bgp_connect() below. + * connections are taken care of in bgp_connect() below. */ - for (ALL_LIST_ELEMENTS_RO(bm->listen_sockets, node, listener)) - if (listener->su.sa.sa_family == peer->su.sa.sa_family) { - ret = bgp_md5_set_socket(listener->fd, &peer->su, - password); - break; - } - - if (bgpd_privs.change(ZPRIVS_LOWER)) - flog_err(LIB_ERR_PRIVILEGES, "%s: could not lower privs", - __func__); - + for (ALL_LIST_ELEMENTS_RO(bm->listen_sockets, node, listener)) + if (listener->su.sa.sa_family + == peer->su.sa.sa_family) { + ret = bgp_md5_set_socket(listener->fd, + &peer->su, password); + break; + } + } return ret; } diff --git a/eigrpd/eigrp_network.c b/eigrpd/eigrp_network.c index d778578d80..8eaf1e82a3 100644 --- a/eigrpd/eigrp_network.c +++ b/eigrpd/eigrp_network.c @@ -61,65 +61,42 @@ int eigrp_sock_init(void) int hincl = 1; #endif - if (eigrpd_privs.change(ZPRIVS_RAISE)) - flog_err(LIB_ERR_PRIVILEGES, - "eigrp_sock_init: could not raise privs, %s", - safe_strerror(errno)); - - eigrp_sock = socket(AF_INET, SOCK_RAW, IPPROTO_EIGRPIGP); - if (eigrp_sock < 0) { - int save_errno = errno; - if (eigrpd_privs.change(ZPRIVS_LOWER)) - flog_err(LIB_ERR_PRIVILEGES, - "eigrp_sock_init: could not lower privs, %s", - safe_strerror(errno)); - flog_err_sys(LIB_ERR_SOCKET, "eigrp_read_sock_init: socket: %s", - safe_strerror(save_errno)); - exit(1); - } + frr_elevate_privs(&eigrpd_privs) { + eigrp_sock = socket(AF_INET, SOCK_RAW, IPPROTO_EIGRPIGP); + if (eigrp_sock < 0) { + zlog_err("eigrp_read_sock_init: socket: %s", + safe_strerror(errno)); + exit(1); + } #ifdef IP_HDRINCL - /* we will include IP header with packet */ - ret = setsockopt(eigrp_sock, IPPROTO_IP, IP_HDRINCL, &hincl, - sizeof(hincl)); - if (ret < 0) { - int save_errno = errno; - if (eigrpd_privs.change(ZPRIVS_LOWER)) - flog_err(LIB_ERR_PRIVILEGES, - "eigrp_sock_init: could not lower privs, %s", - safe_strerror(errno)); - zlog_warn("Can't set IP_HDRINCL option for fd %d: %s", - eigrp_sock, safe_strerror(save_errno)); - } + /* we will include IP header with packet */ + ret = setsockopt(eigrp_sock, IPPROTO_IP, IP_HDRINCL, &hincl, + sizeof(hincl)); + if (ret < 0) { + zlog_warn("Can't set IP_HDRINCL option for fd %d: %s", + eigrp_sock, safe_strerror(errno)); + } #elif defined(IPTOS_PREC_INTERNETCONTROL) #warning "IP_HDRINCL not available on this system" #warning "using IPTOS_PREC_INTERNETCONTROL" - ret = setsockopt_ipv4_tos(eigrp_sock, IPTOS_PREC_INTERNETCONTROL); - if (ret < 0) { - int save_errno = errno; - if (eigrpd_privs.change(ZPRIVS_LOWER)) - flog_err(LIB_ERR_PRIVILEGES, - "eigrpd_sock_init: could not lower privs, %s", - safe_strerror(errno)); - zlog_warn("can't set sockopt IP_TOS %d to socket %d: %s", tos, - eigrp_sock, safe_strerror(save_errno)); - close(eigrp_sock); /* Prevent sd leak. */ - return ret; - } + ret = setsockopt_ipv4_tos(eigrp_sock, + IPTOS_PREC_INTERNETCONTROL); + if (ret < 0) { + zlog_warn("can't set sockopt IP_TOS %d to socket %d: %s", + tos, eigrp_sock, safe_strerror(errno)); + close(eigrp_sock); /* Prevent sd leak. */ + return ret; + } #else /* !IPTOS_PREC_INTERNETCONTROL */ #warning "IP_HDRINCL not available, nor is IPTOS_PREC_INTERNETCONTROL" - zlog_warn("IP_HDRINCL option not available"); + zlog_warn("IP_HDRINCL option not available"); #endif /* IP_HDRINCL */ - ret = setsockopt_ifindex(AF_INET, eigrp_sock, 1); - - if (ret < 0) - zlog_warn("Can't set pktinfo option for fd %d", eigrp_sock); - - if (eigrpd_privs.change(ZPRIVS_LOWER)) { - flog_err(LIB_ERR_PRIVILEGES, - "eigrp_sock_init: could not lower privs, %s", - safe_strerror(errno)); + ret = setsockopt_ifindex(AF_INET, eigrp_sock, 1); + if (ret < 0) + zlog_warn("Can't set pktinfo option for fd %d", + eigrp_sock); } return eigrp_sock; diff --git a/ldpd/socket.c b/ldpd/socket.c index 1cdef83729..bebd7a7d61 100644 --- a/ldpd/socket.c +++ b/ldpd/socket.c @@ -41,7 +41,6 @@ ldp_create_socket(int af, enum socket_type type) #ifdef __OpenBSD__ int opt; #endif - int save_errno; /* create socket */ switch (type) { @@ -80,25 +79,18 @@ ldp_create_socket(int af, enum socket_type type) sock_set_bindany(fd, 1); break; } - if (ldpd_privs.change(ZPRIVS_RAISE)) - log_warn("%s: could not raise privs", __func__); - if (sock_set_reuse(fd, 1) == -1) { - if (ldpd_privs.change(ZPRIVS_LOWER)) - log_warn("%s: could not lower privs", __func__); - close(fd); - return (-1); - } - if (bind(fd, &local_su.sa, sockaddr_len(&local_su.sa)) == -1) { - save_errno = errno; - if (ldpd_privs.change(ZPRIVS_LOWER)) - log_warn("%s: could not lower privs", __func__); - log_warnx("%s: error binding socket: %s", __func__, - safe_strerror(save_errno)); - close(fd); - return (-1); + frr_elevate_privs(&ldpd_privs) { + if (sock_set_reuse(fd, 1) == -1) { + close(fd); + return (-1); + } + if (bind(fd, &local_su.sa, sockaddr_len(&local_su.sa)) == -1) { + log_warnx("%s: error binding socket: %s", __func__, + safe_strerror(errno)); + close(fd); + return (-1); + } } - if (ldpd_privs.change(ZPRIVS_LOWER)) - log_warn("%s: could not lower privs", __func__); /* set options */ switch (af) { @@ -302,14 +294,10 @@ sock_set_md5sig(int fd, int af, union ldpd_addr *addr, const char *password) #if HAVE_DECL_TCP_MD5SIG addr2sa(af, addr, 0, &su); - if (ldpe_privs.change(ZPRIVS_RAISE)) { - log_warn("%s: could not raise privs", __func__); - return (-1); + frr_elevate_privs(&ldpe_privs) { + ret = sockopt_tcp_signature(fd, &su, password); + save_errno = errno; } - ret = sockopt_tcp_signature(fd, &su, password); - save_errno = errno; - if (ldpe_privs.change(ZPRIVS_LOWER)) - log_warn("%s: could not lower privs", __func__); #endif /* HAVE_TCP_MD5SIG */ if (ret < 0) log_warnx("%s: can't set TCP_MD5SIG option on fd %d: %s", diff --git a/lib/sockunion.c b/lib/sockunion.c index 60597b5881..bbbfbfc424 100644 --- a/lib/sockunion.c +++ b/lib/sockunion.c @@ -366,16 +366,10 @@ int sockopt_mark_default(int sock, int mark, struct zebra_privs_t *cap) #ifdef SO_MARK int ret; - if (cap->change(ZPRIVS_RAISE)) - flog_err(LIB_ERR_PRIVILEGES, - "routing_socket: Can't raise privileges"); - - ret = setsockopt(sock, SOL_SOCKET, SO_MARK, &mark, sizeof(mark)); - - if (cap->change(ZPRIVS_LOWER)) - flog_err(LIB_ERR_PRIVILEGES, - "routing_socket: Can't lower privileges"); - + frr_elevate_privs(cap) { + ret = setsockopt(sock, SOL_SOCKET, SO_MARK, &mark, + sizeof(mark)); + } return ret; #else return 0; diff --git a/lib/vrf.c b/lib/vrf.c index 9a5414a44c..36111dfeae 100644 --- a/lib/vrf.c +++ b/lib/vrf.c @@ -764,16 +764,10 @@ DEFUN_NOSH (vrf_netns, if (!pathname) return CMD_WARNING_CONFIG_FAILED; - if (vrf_daemon_privs && vrf_daemon_privs->change(ZPRIVS_RAISE)) - flog_err(LIB_ERR_PRIVILEGES, "%s: Can't raise privileges", - __func__); - - ret = vrf_netns_handler_create(vty, vrf, pathname, - NS_UNKNOWN, NS_UNKNOWN); - - if (vrf_daemon_privs && vrf_daemon_privs->change(ZPRIVS_LOWER)) - flog_err(LIB_ERR_PRIVILEGES, "%s: Can't lower privileges", - __func__); + frr_elevate_privs(vrf_daemon_privs) { + ret = vrf_netns_handler_create(vty, vrf, pathname, + NS_UNKNOWN, NS_UNKNOWN); + } return ret; } diff --git a/lib/zclient.c b/lib/zclient.c index c501ac49c7..cc91705ee2 100644 --- a/lib/zclient.c +++ b/lib/zclient.c @@ -213,9 +213,9 @@ int zclient_socket_connect(struct zclient *zclient) set_cloexec(sock); - zclient->privs->change(ZPRIVS_RAISE); - setsockopt_so_sendbuf(sock, 1048576); - zclient->privs->change(ZPRIVS_LOWER); + frr_elevate_privs(zclient->privs) { + setsockopt_so_sendbuf(sock, 1048576); + } /* Connect to zebra. */ ret = connect(sock, (struct sockaddr *)&zclient_addr, zclient_addr_len); diff --git a/ospfd/ospf_network.c b/ospfd/ospf_network.c index eac4453ed5..1fb930659e 100644 --- a/ospfd/ospf_network.c +++ b/ospfd/ospf_network.c @@ -186,67 +186,51 @@ int ospf_sock_init(struct ospf *ospf) /* silently return since VRF is not ready */ return -1; } - if (ospfd_privs.change(ZPRIVS_RAISE)) - flog_err(LIB_ERR_PRIVILEGES, - "ospf_sock_init: could not raise privs, %s", - safe_strerror(errno)); - - ospf_sock = vrf_socket(AF_INET, SOCK_RAW, IPPROTO_OSPFIGP, ospf->vrf_id, - ospf->name); - if (ospf_sock < 0) { - int save_errno = errno; - - if (ospfd_privs.change(ZPRIVS_LOWER)) - flog_err(LIB_ERR_PRIVILEGES, - "ospf_sock_init: could not lower privs, %s", - safe_strerror(save_errno)); - - exit(1); - } + frr_elevate_privs(&ospfd_privs) { + ospf_sock = vrf_socket(AF_INET, SOCK_RAW, IPPROTO_OSPFIGP, + ospf->vrf_id, ospf->name); + if (ospf_sock < 0) { + zlog_err("ospf_read_sock_init: socket: %s", + safe_strerror(errno)); + exit(1); + } #ifdef IP_HDRINCL - /* we will include IP header with packet */ - ret = setsockopt(ospf_sock, IPPROTO_IP, IP_HDRINCL, &hincl, - sizeof(hincl)); - if (ret < 0) { - int save_errno = errno; - - zlog_warn("Can't set IP_HDRINCL option for fd %d: %s", - ospf_sock, safe_strerror(save_errno)); - close(ospf_sock); - goto out; - } + /* we will include IP header with packet */ + ret = setsockopt(ospf_sock, IPPROTO_IP, IP_HDRINCL, &hincl, + sizeof(hincl)); + if (ret < 0) { + zlog_warn("Can't set IP_HDRINCL option for fd %d: %s", + ospf_sock, safe_strerror(errno)); + close(ospf_sock); + break; + } #elif defined(IPTOS_PREC_INTERNETCONTROL) #warning "IP_HDRINCL not available on this system" #warning "using IPTOS_PREC_INTERNETCONTROL" - ret = setsockopt_ipv4_tos(ospf_sock, IPTOS_PREC_INTERNETCONTROL); - if (ret < 0) { - int save_errno = errno; - - zlog_warn("can't set sockopt IP_TOS %d to socket %d: %s", tos, - ospf_sock, safe_strerror(save_errno)); - close(ospf_sock); /* Prevent sd leak. */ - goto out; - } + ret = setsockopt_ipv4_tos(ospf_sock, + IPTOS_PREC_INTERNETCONTROL); + if (ret < 0) { + zlog_warn("can't set sockopt IP_TOS %d to socket %d: %s", + tos, ospf_sock, safe_strerror(errno)); + close(ospf_sock); /* Prevent sd leak. */ + break; + } #else /* !IPTOS_PREC_INTERNETCONTROL */ #warning "IP_HDRINCL not available, nor is IPTOS_PREC_INTERNETCONTROL" - zlog_warn("IP_HDRINCL option not available"); + zlog_warn("IP_HDRINCL option not available"); #endif /* IP_HDRINCL */ - ret = setsockopt_ifindex(AF_INET, ospf_sock, 1); + ret = setsockopt_ifindex(AF_INET, ospf_sock, 1); - if (ret < 0) - zlog_warn("Can't set pktinfo option for fd %d", ospf_sock); + if (ret < 0) + zlog_warn("Can't set pktinfo option for fd %d", + ospf_sock); - setsockopt_so_sendbuf(ospf_sock, bufsize); - setsockopt_so_recvbuf(ospf_sock, bufsize); + setsockopt_so_sendbuf(ospf_sock, bufsize); + setsockopt_so_recvbuf(ospf_sock, bufsize); + } ospf->fd = ospf_sock; -out: - if (ospfd_privs.change(ZPRIVS_LOWER)) - flog_err(LIB_ERR_PRIVILEGES, - "ospf_sock_init: could not lower privs, %s", - safe_strerror(errno)); - return ret; } diff --git a/ospfd/ospfd.c b/ospfd/ospfd.c index bee68622f2..ac8f0d92c3 100644 --- a/ospfd/ospfd.c +++ b/ospfd/ospfd.c @@ -2088,25 +2088,18 @@ static int ospf_vrf_enable(struct vrf *vrf) old_vrf_id); if (old_vrf_id != ospf->vrf_id) { - if (ospfd_privs.change(ZPRIVS_RAISE)) - flog_err( - LIB_ERR_PRIVILEGES, - "ospf_vrf_link: could not raise privs"); + frr_elevate_privs(&ospfd_privs) { + /* stop zebra redist to us for old vrf */ + zclient_send_dereg_requests(zclient, + old_vrf_id); - /* stop zebra redist to us for old vrf */ - zclient_send_dereg_requests(zclient, old_vrf_id); + ospf_set_redist_vrf_bitmaps(ospf); - ospf_set_redist_vrf_bitmaps(ospf); - - /* start zebra redist to us for new vrf */ - ospf_zebra_vrf_register(ospf); - - ret = ospf_sock_init(ospf); - if (ospfd_privs.change(ZPRIVS_LOWER)) - flog_err( - LIB_ERR_PRIVILEGES, - "ospf_sock_init: could not lower privs"); + /* start zebra redist to us for new vrf */ + ospf_zebra_vrf_register(ospf); + ret = ospf_sock_init(ospf); + } if (ret < 0 || ospf->fd <= 0) return 0; thread_add_read(master, ospf_read, ospf, ospf->fd, diff --git a/pimd/pim_msdp_socket.c b/pimd/pim_msdp_socket.c index b0e7b39d7b..feac42cf53 100644 --- a/pimd/pim_msdp_socket.c +++ b/pimd/pim_msdp_socket.c @@ -176,19 +176,9 @@ int pim_msdp_sock_listen(struct pim_instance *pim) } } - if (pimd_privs.change(ZPRIVS_RAISE)) { - flog_err(LIB_ERR_PRIVILEGES, - "pim_msdp_socket: could not raise privs, %s", - safe_strerror(errno)); - } - - /* bind to well known TCP port */ - rc = bind(sock, (struct sockaddr *)&sin, socklen); - - if (pimd_privs.change(ZPRIVS_LOWER)) { - flog_err(LIB_ERR_PRIVILEGES, - "pim_msdp_socket: could not lower privs, %s", - safe_strerror(errno)); + frr_elevate_privs(&pimd_privs) { + /* bind to well known TCP port */ + rc = bind(sock, (struct sockaddr *)&sin, socklen); } if (rc < 0) { diff --git a/tests/lib/test_privs.c b/tests/lib/test_privs.c index 421c345436..e203da8f6e 100644 --- a/tests/lib/test_privs.c +++ b/tests/lib/test_privs.c @@ -113,10 +113,9 @@ int main(int argc, char **argv) ((test_privs.current_state() == ZPRIVS_RAISED) ? "Raised" : "Lowered") printf("%s\n", PRIV_STATE()); - test_privs.change(ZPRIVS_RAISE); - - printf("%s\n", PRIV_STATE()); - test_privs.change(ZPRIVS_LOWER); + frr_elevate_privs(&test_privs) { + printf("%s\n", PRIV_STATE()); + } printf("%s\n", PRIV_STATE()); zprivs_get_ids(&ids); @@ -126,10 +125,9 @@ int main(int argc, char **argv) /* but these should continue to work... */ printf("%s\n", PRIV_STATE()); - test_privs.change(ZPRIVS_RAISE); - - printf("%s\n", PRIV_STATE()); - test_privs.change(ZPRIVS_LOWER); + frr_elevate_privs(&test_privs) { + printf("%s\n", PRIV_STATE()); + } printf("%s\n", PRIV_STATE()); zprivs_get_ids(&ids); diff --git a/zebra/if_ioctl_solaris.c b/zebra/if_ioctl_solaris.c index ee7f22e780..5a58fe1751 100644 --- a/zebra/if_ioctl_solaris.c +++ b/zebra/if_ioctl_solaris.c @@ -60,19 +60,21 @@ static int interface_list_ioctl(int af) char *buf = NULL; frr_elevate_privs(&zserv_privs) { - sock = socket(af, SOCK_DGRAM, 0); - if (sock < 0) { - zlog_warn("Can't make %s socket stream: %s", - (af == AF_INET ? "AF_INET" : "AF_INET6"), - safe_strerror(errno)); + } - return -1; - } + if (sock < 0) { + zlog_warn("Can't make %s socket stream: %s", + (af == AF_INET ? "AF_INET" : "AF_INET6"), + safe_strerror(errno)); + return -1; + } -calculate_lifc_len: /* must hold privileges to enter here */ +calculate_lifc_len: + frr_elevate_privs(&zserv_privs) { lifn.lifn_family = af; - lifn.lifn_flags = LIFC_NOXMIT; /* we want NOXMIT interfaces too */ + lifn.lifn_flags = LIFC_NOXMIT; + /* we want NOXMIT interfaces too */ ret = ioctl(sock, SIOCGLIFNUM, &lifn); save_errno = errno; @@ -105,27 +107,18 @@ calculate_lifc_len: /* must hold privileges to enter here */ lifconf.lifc_len = needed; lifconf.lifc_buf = buf; - if (zserv_privs.change(ZPRIVS_RAISE)) - flog_err(LIB_ERR_PRIVILEGES, "Can't raise privileges"); - - ret = ioctl(sock, SIOCGLIFCONF, &lifconf); + frr_elevate_privs(&zserv_privs) { + ret = ioctl(sock, SIOCGLIFCONF, &lifconf); + } if (ret < 0) { if (errno == EINVAL) - goto calculate_lifc_len; /* deliberately hold privileges - */ + goto calculate_lifc_len; zlog_warn("SIOCGLIFCONF: %s", safe_strerror(errno)); - - if (zserv_privs.change(ZPRIVS_LOWER)) - flog_err(LIB_ERR_PRIVILEGES, "Can't lower privileges"); - goto end; } - if (zserv_privs.change(ZPRIVS_LOWER)) - flog_err(LIB_ERR_PRIVILEGES, "Can't lower privileges"); - /* Allocate interface. */ lifreq = lifconf.lifc_req; diff --git a/zebra/kernel_netlink.c b/zebra/kernel_netlink.c index b397e95955..176ee93cdc 100644 --- a/zebra/kernel_netlink.c +++ b/zebra/kernel_netlink.c @@ -206,34 +206,26 @@ static int netlink_socket(struct nlsock *nl, unsigned long groups, struct sockaddr_nl snl; int sock; int namelen; - int save_errno; - - if (zserv_privs.change(ZPRIVS_RAISE)) { - flog_err(LIB_ERR_PRIVILEGES, "Can't raise privileges"); - return -1; - } - sock = ns_socket(AF_NETLINK, SOCK_RAW, NETLINK_ROUTE, ns_id); - if (sock < 0) { - flog_err_sys(LIB_ERR_SOCKET, "Can't open %s socket: %s", - nl->name, safe_strerror(errno)); - return -1; - } + frr_elevate_privs(&zserv_privs) { + sock = ns_socket(AF_NETLINK, SOCK_RAW, NETLINK_ROUTE, ns_id); + if (sock < 0) { + zlog_err("Can't open %s socket: %s", nl->name, + safe_strerror(errno)); + return -1; + } - memset(&snl, 0, sizeof snl); - snl.nl_family = AF_NETLINK; - snl.nl_groups = groups; + memset(&snl, 0, sizeof snl); + snl.nl_family = AF_NETLINK; + snl.nl_groups = groups; - /* Bind the socket to the netlink structure for anything. */ - ret = bind(sock, (struct sockaddr *)&snl, sizeof snl); - save_errno = errno; - if (zserv_privs.change(ZPRIVS_LOWER)) - flog_err(LIB_ERR_PRIVILEGES, "Can't lower privileges"); + /* Bind the socket to the netlink structure for anything. */ + ret = bind(sock, (struct sockaddr *)&snl, sizeof snl); + } if (ret < 0) { - flog_err_sys(LIB_ERR_SOCKET, - "Can't bind %s socket to group 0x%x: %s", nl->name, - snl.nl_groups, safe_strerror(save_errno)); + zlog_err("Can't bind %s socket to group 0x%x: %s", nl->name, + snl.nl_groups, safe_strerror(errno)); close(sock); return -1; } @@ -340,15 +332,15 @@ static void netlink_write_incoming(const char *buf, const unsigned int size, char fname[MAXPATHLEN]; FILE *f; - zserv_privs.change(ZPRIVS_RAISE); snprintf(fname, MAXPATHLEN, "%s/%s_%u", DAEMON_VTY_DIR, "netlink", counter); - f = fopen(fname, "w"); + frr_elevate_privs(&zserv_privs) { + f = fopen(fname, "w"); + } if (f) { fwrite(buf, 1, size, f); fclose(f); } - zserv_privs.change(ZPRIVS_LOWER); } /** @@ -363,8 +355,9 @@ static long netlink_read_file(char *buf, const char *fname) FILE *f; long file_bytes = -1; - zserv_privs.change(ZPRIVS_RAISE); - f = fopen(fname, "r"); + frr_elevate_privs(&zserv_privs) { + f = fopen(fname, "r"); + } if (f) { fseek(f, 0, SEEK_END); file_bytes = ftell(f); @@ -372,7 +365,6 @@ static long netlink_read_file(char *buf, const char *fname) fread(buf, NL_RCV_PKT_BUF_SIZE, 1, f); fclose(f); } - zserv_privs.change(ZPRIVS_LOWER); return file_bytes; } @@ -985,7 +977,6 @@ int netlink_request(struct nlsock *nl, struct nlmsghdr *n) { int ret; struct sockaddr_nl snl; - int save_errno; /* Check netlink socket. */ if (nl->sock < 0) { @@ -1003,21 +994,14 @@ int netlink_request(struct nlsock *nl, struct nlmsghdr *n) snl.nl_family = AF_NETLINK; /* Raise capabilities and send message, then lower capabilities. */ - if (zserv_privs.change(ZPRIVS_RAISE)) { - flog_err(LIB_ERR_PRIVILEGES, "Can't raise privileges"); - return -1; + frr_elevate_privs(&zserv_privs) { + ret = sendto(nl->sock, (void *)n, n->nlmsg_len, 0, + (struct sockaddr *)&snl, sizeof snl); } - ret = sendto(nl->sock, (void *)n, n->nlmsg_len, 0, - (struct sockaddr *)&snl, sizeof snl); - save_errno = errno; - - if (zserv_privs.change(ZPRIVS_LOWER)) - flog_err(LIB_ERR_PRIVILEGES, "Can't lower privileges"); - if (ret < 0) { - flog_err_sys(LIB_ERR_SOCKET, "%s sendto failed: %s", nl->name, - safe_strerror(save_errno)); + zlog_err("%s sendto failed: %s", nl->name, + safe_strerror(errno)); return -1; } diff --git a/zebra/kernel_socket.c b/zebra/kernel_socket.c index 79721cf87a..78e25e7626 100644 --- a/zebra/kernel_socket.c +++ b/zebra/kernel_socket.c @@ -1385,17 +1385,11 @@ static int kernel_read(struct thread *thread) /* Make routing socket. */ static void routing_socket(struct zebra_ns *zns) { - if (zserv_privs.change(ZPRIVS_RAISE)) - flog_err(LIB_ERR_PRIVILEGES, - "routing_socket: Can't raise privileges"); - - routing_sock = - ns_socket(AF_ROUTE, SOCK_RAW, 0, zns->ns_id); + frr_elevate_privs(&zserv_privs) { + routing_sock = ns_socket(AF_ROUTE, SOCK_RAW, 0, zns->ns_id); + } if (routing_sock < 0) { - if (zserv_privs.change(ZPRIVS_LOWER)) - flog_err(LIB_ERR_PRIVILEGES, - "routing_socket: Can't lower privileges"); zlog_warn("Can't init kernel routing socket"); return; } @@ -1407,10 +1401,6 @@ static void routing_socket(struct zebra_ns *zns) /*if (fcntl (routing_sock, F_SETFL, O_NONBLOCK) < 0) zlog_warn ("Can't set O_NONBLOCK to routing socket");*/ - if (zserv_privs.change(ZPRIVS_LOWER)) - flog_err(LIB_ERR_PRIVILEGES, - "routing_socket: Can't lower privileges"); - /* kernel_read needs rewrite. */ thread_add_read(zebrad.master, kernel_read, NULL, routing_sock, NULL); } diff --git a/zebra/zapi_msg.c b/zebra/zapi_msg.c index a74c6bc4bf..008fc8f066 100644 --- a/zebra/zapi_msg.c +++ b/zebra/zapi_msg.c @@ -3087,12 +3087,13 @@ static void zserv_write_incoming(struct stream *orig, uint16_t command) copy = stream_dup(orig); stream_set_getp(copy, 0); - zserv_privs.change(ZPRIVS_RAISE); snprintf(fname, MAXPATHLEN, "%s/%u", DAEMON_VTY_DIR, command); - fd = open(fname, O_CREAT | O_WRONLY | O_EXCL, 0644); + + frr_elevate_privs(&zserv_privs) { + fd = open(fname, O_CREAT | O_WRONLY | O_EXCL, 0644); + } stream_flush(copy, fd); close(fd); - zserv_privs.change(ZPRIVS_LOWER); stream_free(copy); } #endif diff --git a/zebra/zserv.c b/zebra/zserv.c index 553331867c..174e010743 100644 --- a/zebra/zserv.c +++ b/zebra/zserv.c @@ -787,15 +787,14 @@ void zserv_start(char *path) unlink(suna->sun_path); } - zserv_privs.change(ZPRIVS_RAISE); - setsockopt_so_recvbuf(zebrad.sock, 1048576); - setsockopt_so_sendbuf(zebrad.sock, 1048576); - zserv_privs.change(ZPRIVS_LOWER); - - if (sa.ss_family != AF_UNIX && zserv_privs.change(ZPRIVS_RAISE)) - flog_err(LIB_ERR_PRIVILEGES, "Can't raise privileges"); + frr_elevate_privs(&zserv_privs) { + setsockopt_so_recvbuf(zebrad.sock, 1048576); + setsockopt_so_sendbuf(zebrad.sock, 1048576); + } - ret = bind(zebrad.sock, (struct sockaddr *)&sa, sa_len); + frr_elevate_privs((sa.ss_family != AF_UNIX) ? &zserv_privs : NULL) { + ret = bind(zebrad.sock, (struct sockaddr *)&sa, sa_len); + } if (ret < 0) { zlog_warn("Can't bind zserv socket on %s: %s", path, safe_strerror(errno)); @@ -805,8 +804,6 @@ void zserv_start(char *path) zebrad.sock = -1; return; } - if (sa.ss_family != AF_UNIX && zserv_privs.change(ZPRIVS_LOWER)) - flog_err(LIB_ERR_PRIVILEGES, "Can't lower privileges"); ret = listen(zebrad.sock, 5); if (ret < 0) { -- 2.39.5