*: use frr_elevate_privs() (2/2: manual)

Signed-off-by: David Lamparter <equinox@diac24.net>
This commit is contained in:
David Lamparter 2018-08-10 18:46:07 +02:00 committed by Quentin Young
parent 01b9e3fd0d
commit 6bb30c2cba
15 changed files with 171 additions and 305 deletions

View File

@ -97,17 +97,9 @@ static int bgp_md5_set_connect(int socket, union sockunion *su,
int ret = -1; int ret = -1;
#if HAVE_DECL_TCP_MD5SIG #if HAVE_DECL_TCP_MD5SIG
if (bgpd_privs.change(ZPRIVS_RAISE)) { frr_elevate_privs(&bgpd_privs) {
flog_err(LIB_ERR_PRIVILEGES, "%s: could not raise privs",
__func__);
return ret;
}
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 */ #endif /* HAVE_TCP_MD5SIG */
return ret; return ret;
@ -119,27 +111,18 @@ static int bgp_md5_set_password(struct peer *peer, const char *password)
int ret = 0; int ret = 0;
struct bgp_listener *listener; struct bgp_listener *listener;
if (bgpd_privs.change(ZPRIVS_RAISE)) { frr_elevate_privs(&bgpd_privs) {
flog_err(LIB_ERR_PRIVILEGES, "%s: could not raise privs",
__func__);
return -1;
}
/* Set or unset the password on the listen socket(s). Outbound /* Set or unset the password on the listen socket(s). Outbound
* connections * connections are taken care of in bgp_connect() below.
* are taken care of in bgp_connect() below.
*/ */
for (ALL_LIST_ELEMENTS_RO(bm->listen_sockets, node, listener)) for (ALL_LIST_ELEMENTS_RO(bm->listen_sockets, node, listener))
if (listener->su.sa.sa_family == peer->su.sa.sa_family) { if (listener->su.sa.sa_family
ret = bgp_md5_set_socket(listener->fd, &peer->su, == peer->su.sa.sa_family) {
password); ret = bgp_md5_set_socket(listener->fd,
&peer->su, password);
break; break;
} }
}
if (bgpd_privs.change(ZPRIVS_LOWER))
flog_err(LIB_ERR_PRIVILEGES, "%s: could not lower privs",
__func__);
return ret; return ret;
} }

View File

@ -61,20 +61,11 @@ int eigrp_sock_init(void)
int hincl = 1; int hincl = 1;
#endif #endif
if (eigrpd_privs.change(ZPRIVS_RAISE)) frr_elevate_privs(&eigrpd_privs) {
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); eigrp_sock = socket(AF_INET, SOCK_RAW, IPPROTO_EIGRPIGP);
if (eigrp_sock < 0) { if (eigrp_sock < 0) {
int save_errno = errno; zlog_err("eigrp_read_sock_init: socket: %s",
if (eigrpd_privs.change(ZPRIVS_LOWER))
flog_err(LIB_ERR_PRIVILEGES,
"eigrp_sock_init: could not lower privs, %s",
safe_strerror(errno)); safe_strerror(errno));
flog_err_sys(LIB_ERR_SOCKET, "eigrp_read_sock_init: socket: %s",
safe_strerror(save_errno));
exit(1); exit(1);
} }
@ -83,26 +74,17 @@ int eigrp_sock_init(void)
ret = setsockopt(eigrp_sock, IPPROTO_IP, IP_HDRINCL, &hincl, ret = setsockopt(eigrp_sock, IPPROTO_IP, IP_HDRINCL, &hincl,
sizeof(hincl)); sizeof(hincl));
if (ret < 0) { 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", zlog_warn("Can't set IP_HDRINCL option for fd %d: %s",
eigrp_sock, safe_strerror(save_errno)); eigrp_sock, safe_strerror(errno));
} }
#elif defined(IPTOS_PREC_INTERNETCONTROL) #elif defined(IPTOS_PREC_INTERNETCONTROL)
#warning "IP_HDRINCL not available on this system" #warning "IP_HDRINCL not available on this system"
#warning "using IPTOS_PREC_INTERNETCONTROL" #warning "using IPTOS_PREC_INTERNETCONTROL"
ret = setsockopt_ipv4_tos(eigrp_sock, IPTOS_PREC_INTERNETCONTROL); ret = setsockopt_ipv4_tos(eigrp_sock,
IPTOS_PREC_INTERNETCONTROL);
if (ret < 0) { if (ret < 0) {
int save_errno = errno; zlog_warn("can't set sockopt IP_TOS %d to socket %d: %s",
if (eigrpd_privs.change(ZPRIVS_LOWER)) tos, eigrp_sock, safe_strerror(errno));
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. */ close(eigrp_sock); /* Prevent sd leak. */
return ret; return ret;
} }
@ -112,14 +94,9 @@ int eigrp_sock_init(void)
#endif /* IP_HDRINCL */ #endif /* IP_HDRINCL */
ret = setsockopt_ifindex(AF_INET, eigrp_sock, 1); ret = setsockopt_ifindex(AF_INET, eigrp_sock, 1);
if (ret < 0) if (ret < 0)
zlog_warn("Can't set pktinfo option for fd %d", eigrp_sock); 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));
} }
return eigrp_sock; return eigrp_sock;

View File

@ -41,7 +41,6 @@ ldp_create_socket(int af, enum socket_type type)
#ifdef __OpenBSD__ #ifdef __OpenBSD__
int opt; int opt;
#endif #endif
int save_errno;
/* create socket */ /* create socket */
switch (type) { switch (type) {
@ -80,25 +79,18 @@ ldp_create_socket(int af, enum socket_type type)
sock_set_bindany(fd, 1); sock_set_bindany(fd, 1);
break; break;
} }
if (ldpd_privs.change(ZPRIVS_RAISE)) frr_elevate_privs(&ldpd_privs) {
log_warn("%s: could not raise privs", __func__);
if (sock_set_reuse(fd, 1) == -1) { if (sock_set_reuse(fd, 1) == -1) {
if (ldpd_privs.change(ZPRIVS_LOWER))
log_warn("%s: could not lower privs", __func__);
close(fd); close(fd);
return (-1); return (-1);
} }
if (bind(fd, &local_su.sa, sockaddr_len(&local_su.sa)) == -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__, log_warnx("%s: error binding socket: %s", __func__,
safe_strerror(save_errno)); safe_strerror(errno));
close(fd); close(fd);
return (-1); return (-1);
} }
if (ldpd_privs.change(ZPRIVS_LOWER)) }
log_warn("%s: could not lower privs", __func__);
/* set options */ /* set options */
switch (af) { 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 #if HAVE_DECL_TCP_MD5SIG
addr2sa(af, addr, 0, &su); addr2sa(af, addr, 0, &su);
if (ldpe_privs.change(ZPRIVS_RAISE)) { frr_elevate_privs(&ldpe_privs) {
log_warn("%s: could not raise privs", __func__);
return (-1);
}
ret = sockopt_tcp_signature(fd, &su, password); ret = sockopt_tcp_signature(fd, &su, password);
save_errno = errno; save_errno = errno;
if (ldpe_privs.change(ZPRIVS_LOWER)) }
log_warn("%s: could not lower privs", __func__);
#endif /* HAVE_TCP_MD5SIG */ #endif /* HAVE_TCP_MD5SIG */
if (ret < 0) if (ret < 0)
log_warnx("%s: can't set TCP_MD5SIG option on fd %d: %s", log_warnx("%s: can't set TCP_MD5SIG option on fd %d: %s",

View File

@ -366,16 +366,10 @@ int sockopt_mark_default(int sock, int mark, struct zebra_privs_t *cap)
#ifdef SO_MARK #ifdef SO_MARK
int ret; int ret;
if (cap->change(ZPRIVS_RAISE)) frr_elevate_privs(cap) {
flog_err(LIB_ERR_PRIVILEGES, ret = setsockopt(sock, SOL_SOCKET, SO_MARK, &mark,
"routing_socket: Can't raise privileges"); sizeof(mark));
}
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");
return ret; return ret;
#else #else
return 0; return 0;

View File

@ -764,16 +764,10 @@ DEFUN_NOSH (vrf_netns,
if (!pathname) if (!pathname)
return CMD_WARNING_CONFIG_FAILED; return CMD_WARNING_CONFIG_FAILED;
if (vrf_daemon_privs && vrf_daemon_privs->change(ZPRIVS_RAISE)) frr_elevate_privs(vrf_daemon_privs) {
flog_err(LIB_ERR_PRIVILEGES, "%s: Can't raise privileges",
__func__);
ret = vrf_netns_handler_create(vty, vrf, pathname, ret = vrf_netns_handler_create(vty, vrf, pathname,
NS_UNKNOWN, NS_UNKNOWN); 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__);
return ret; return ret;
} }

View File

@ -213,9 +213,9 @@ int zclient_socket_connect(struct zclient *zclient)
set_cloexec(sock); set_cloexec(sock);
zclient->privs->change(ZPRIVS_RAISE); frr_elevate_privs(zclient->privs) {
setsockopt_so_sendbuf(sock, 1048576); setsockopt_so_sendbuf(sock, 1048576);
zclient->privs->change(ZPRIVS_LOWER); }
/* Connect to zebra. */ /* Connect to zebra. */
ret = connect(sock, (struct sockaddr *)&zclient_addr, zclient_addr_len); ret = connect(sock, (struct sockaddr *)&zclient_addr, zclient_addr_len);

View File

@ -186,21 +186,12 @@ int ospf_sock_init(struct ospf *ospf)
/* silently return since VRF is not ready */ /* silently return since VRF is not ready */
return -1; return -1;
} }
if (ospfd_privs.change(ZPRIVS_RAISE)) frr_elevate_privs(&ospfd_privs) {
flog_err(LIB_ERR_PRIVILEGES, ospf_sock = vrf_socket(AF_INET, SOCK_RAW, IPPROTO_OSPFIGP,
"ospf_sock_init: could not raise privs, %s", ospf->vrf_id, ospf->name);
safe_strerror(errno));
ospf_sock = vrf_socket(AF_INET, SOCK_RAW, IPPROTO_OSPFIGP, ospf->vrf_id,
ospf->name);
if (ospf_sock < 0) { if (ospf_sock < 0) {
int save_errno = errno; zlog_err("ospf_read_sock_init: socket: %s",
safe_strerror(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); exit(1);
} }
@ -209,24 +200,21 @@ int ospf_sock_init(struct ospf *ospf)
ret = setsockopt(ospf_sock, IPPROTO_IP, IP_HDRINCL, &hincl, ret = setsockopt(ospf_sock, IPPROTO_IP, IP_HDRINCL, &hincl,
sizeof(hincl)); sizeof(hincl));
if (ret < 0) { if (ret < 0) {
int save_errno = errno;
zlog_warn("Can't set IP_HDRINCL option for fd %d: %s", zlog_warn("Can't set IP_HDRINCL option for fd %d: %s",
ospf_sock, safe_strerror(save_errno)); ospf_sock, safe_strerror(errno));
close(ospf_sock); close(ospf_sock);
goto out; break;
} }
#elif defined(IPTOS_PREC_INTERNETCONTROL) #elif defined(IPTOS_PREC_INTERNETCONTROL)
#warning "IP_HDRINCL not available on this system" #warning "IP_HDRINCL not available on this system"
#warning "using IPTOS_PREC_INTERNETCONTROL" #warning "using IPTOS_PREC_INTERNETCONTROL"
ret = setsockopt_ipv4_tos(ospf_sock, IPTOS_PREC_INTERNETCONTROL); ret = setsockopt_ipv4_tos(ospf_sock,
IPTOS_PREC_INTERNETCONTROL);
if (ret < 0) { 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(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. */ close(ospf_sock); /* Prevent sd leak. */
goto out; break;
} }
#else /* !IPTOS_PREC_INTERNETCONTROL */ #else /* !IPTOS_PREC_INTERNETCONTROL */
#warning "IP_HDRINCL not available, nor is IPTOS_PREC_INTERNETCONTROL" #warning "IP_HDRINCL not available, nor is IPTOS_PREC_INTERNETCONTROL"
@ -236,17 +224,13 @@ int ospf_sock_init(struct ospf *ospf)
ret = setsockopt_ifindex(AF_INET, ospf_sock, 1); ret = setsockopt_ifindex(AF_INET, ospf_sock, 1);
if (ret < 0) if (ret < 0)
zlog_warn("Can't set pktinfo option for fd %d", ospf_sock); zlog_warn("Can't set pktinfo option for fd %d",
ospf_sock);
setsockopt_so_sendbuf(ospf_sock, bufsize); setsockopt_so_sendbuf(ospf_sock, bufsize);
setsockopt_so_recvbuf(ospf_sock, bufsize); setsockopt_so_recvbuf(ospf_sock, bufsize);
}
ospf->fd = ospf_sock; 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; return ret;
} }

View File

@ -2088,13 +2088,10 @@ static int ospf_vrf_enable(struct vrf *vrf)
old_vrf_id); old_vrf_id);
if (old_vrf_id != ospf->vrf_id) { if (old_vrf_id != ospf->vrf_id) {
if (ospfd_privs.change(ZPRIVS_RAISE)) frr_elevate_privs(&ospfd_privs) {
flog_err(
LIB_ERR_PRIVILEGES,
"ospf_vrf_link: could not raise privs");
/* stop zebra redist to us for old vrf */ /* stop zebra redist to us for old vrf */
zclient_send_dereg_requests(zclient, old_vrf_id); zclient_send_dereg_requests(zclient,
old_vrf_id);
ospf_set_redist_vrf_bitmaps(ospf); ospf_set_redist_vrf_bitmaps(ospf);
@ -2102,11 +2099,7 @@ static int ospf_vrf_enable(struct vrf *vrf)
ospf_zebra_vrf_register(ospf); ospf_zebra_vrf_register(ospf);
ret = ospf_sock_init(ospf); ret = ospf_sock_init(ospf);
if (ospfd_privs.change(ZPRIVS_LOWER)) }
flog_err(
LIB_ERR_PRIVILEGES,
"ospf_sock_init: could not lower privs");
if (ret < 0 || ospf->fd <= 0) if (ret < 0 || ospf->fd <= 0)
return 0; return 0;
thread_add_read(master, ospf_read, ospf, ospf->fd, thread_add_read(master, ospf_read, ospf, ospf->fd,

View File

@ -176,19 +176,9 @@ int pim_msdp_sock_listen(struct pim_instance *pim)
} }
} }
if (pimd_privs.change(ZPRIVS_RAISE)) { frr_elevate_privs(&pimd_privs) {
flog_err(LIB_ERR_PRIVILEGES,
"pim_msdp_socket: could not raise privs, %s",
safe_strerror(errno));
}
/* bind to well known TCP port */ /* bind to well known TCP port */
rc = bind(sock, (struct sockaddr *)&sin, socklen); 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));
} }
if (rc < 0) { if (rc < 0) {

View File

@ -113,10 +113,9 @@ int main(int argc, char **argv)
((test_privs.current_state() == ZPRIVS_RAISED) ? "Raised" : "Lowered") ((test_privs.current_state() == ZPRIVS_RAISED) ? "Raised" : "Lowered")
printf("%s\n", PRIV_STATE()); printf("%s\n", PRIV_STATE());
test_privs.change(ZPRIVS_RAISE); frr_elevate_privs(&test_privs) {
printf("%s\n", PRIV_STATE()); printf("%s\n", PRIV_STATE());
test_privs.change(ZPRIVS_LOWER); }
printf("%s\n", PRIV_STATE()); printf("%s\n", PRIV_STATE());
zprivs_get_ids(&ids); zprivs_get_ids(&ids);
@ -126,10 +125,9 @@ int main(int argc, char **argv)
/* but these should continue to work... */ /* but these should continue to work... */
printf("%s\n", PRIV_STATE()); printf("%s\n", PRIV_STATE());
test_privs.change(ZPRIVS_RAISE); frr_elevate_privs(&test_privs) {
printf("%s\n", PRIV_STATE()); printf("%s\n", PRIV_STATE());
test_privs.change(ZPRIVS_LOWER); }
printf("%s\n", PRIV_STATE()); printf("%s\n", PRIV_STATE());
zprivs_get_ids(&ids); zprivs_get_ids(&ids);

View File

@ -60,19 +60,21 @@ static int interface_list_ioctl(int af)
char *buf = NULL; char *buf = NULL;
frr_elevate_privs(&zserv_privs) { frr_elevate_privs(&zserv_privs) {
sock = socket(af, SOCK_DGRAM, 0); sock = socket(af, SOCK_DGRAM, 0);
}
if (sock < 0) { if (sock < 0) {
zlog_warn("Can't make %s socket stream: %s", zlog_warn("Can't make %s socket stream: %s",
(af == AF_INET ? "AF_INET" : "AF_INET6"), (af == AF_INET ? "AF_INET" : "AF_INET6"),
safe_strerror(errno)); safe_strerror(errno));
return -1; 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_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); ret = ioctl(sock, SIOCGLIFNUM, &lifn);
save_errno = errno; save_errno = errno;
@ -105,27 +107,18 @@ calculate_lifc_len: /* must hold privileges to enter here */
lifconf.lifc_len = needed; lifconf.lifc_len = needed;
lifconf.lifc_buf = buf; lifconf.lifc_buf = buf;
if (zserv_privs.change(ZPRIVS_RAISE)) frr_elevate_privs(&zserv_privs) {
flog_err(LIB_ERR_PRIVILEGES, "Can't raise privileges");
ret = ioctl(sock, SIOCGLIFCONF, &lifconf); ret = ioctl(sock, SIOCGLIFCONF, &lifconf);
}
if (ret < 0) { if (ret < 0) {
if (errno == EINVAL) if (errno == EINVAL)
goto calculate_lifc_len; /* deliberately hold privileges goto calculate_lifc_len;
*/
zlog_warn("SIOCGLIFCONF: %s", safe_strerror(errno)); zlog_warn("SIOCGLIFCONF: %s", safe_strerror(errno));
if (zserv_privs.change(ZPRIVS_LOWER))
flog_err(LIB_ERR_PRIVILEGES, "Can't lower privileges");
goto end; goto end;
} }
if (zserv_privs.change(ZPRIVS_LOWER))
flog_err(LIB_ERR_PRIVILEGES, "Can't lower privileges");
/* Allocate interface. */ /* Allocate interface. */
lifreq = lifconf.lifc_req; lifreq = lifconf.lifc_req;

View File

@ -206,17 +206,12 @@ static int netlink_socket(struct nlsock *nl, unsigned long groups,
struct sockaddr_nl snl; struct sockaddr_nl snl;
int sock; int sock;
int namelen; int namelen;
int save_errno;
if (zserv_privs.change(ZPRIVS_RAISE)) {
flog_err(LIB_ERR_PRIVILEGES, "Can't raise privileges");
return -1;
}
frr_elevate_privs(&zserv_privs) {
sock = ns_socket(AF_NETLINK, SOCK_RAW, NETLINK_ROUTE, ns_id); sock = ns_socket(AF_NETLINK, SOCK_RAW, NETLINK_ROUTE, ns_id);
if (sock < 0) { if (sock < 0) {
flog_err_sys(LIB_ERR_SOCKET, "Can't open %s socket: %s", zlog_err("Can't open %s socket: %s", nl->name,
nl->name, safe_strerror(errno)); safe_strerror(errno));
return -1; return -1;
} }
@ -226,14 +221,11 @@ static int netlink_socket(struct nlsock *nl, unsigned long groups,
/* Bind the socket to the netlink structure for anything. */ /* Bind the socket to the netlink structure for anything. */
ret = bind(sock, (struct sockaddr *)&snl, sizeof snl); 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");
if (ret < 0) { if (ret < 0) {
flog_err_sys(LIB_ERR_SOCKET, zlog_err("Can't bind %s socket to group 0x%x: %s", nl->name,
"Can't bind %s socket to group 0x%x: %s", nl->name, snl.nl_groups, safe_strerror(errno));
snl.nl_groups, safe_strerror(save_errno));
close(sock); close(sock);
return -1; return -1;
} }
@ -340,15 +332,15 @@ static void netlink_write_incoming(const char *buf, const unsigned int size,
char fname[MAXPATHLEN]; char fname[MAXPATHLEN];
FILE *f; FILE *f;
zserv_privs.change(ZPRIVS_RAISE);
snprintf(fname, MAXPATHLEN, "%s/%s_%u", DAEMON_VTY_DIR, "netlink", snprintf(fname, MAXPATHLEN, "%s/%s_%u", DAEMON_VTY_DIR, "netlink",
counter); counter);
frr_elevate_privs(&zserv_privs) {
f = fopen(fname, "w"); f = fopen(fname, "w");
}
if (f) { if (f) {
fwrite(buf, 1, size, f); fwrite(buf, 1, size, f);
fclose(f); fclose(f);
} }
zserv_privs.change(ZPRIVS_LOWER);
} }
/** /**
@ -363,8 +355,9 @@ static long netlink_read_file(char *buf, const char *fname)
FILE *f; FILE *f;
long file_bytes = -1; long file_bytes = -1;
zserv_privs.change(ZPRIVS_RAISE); frr_elevate_privs(&zserv_privs) {
f = fopen(fname, "r"); f = fopen(fname, "r");
}
if (f) { if (f) {
fseek(f, 0, SEEK_END); fseek(f, 0, SEEK_END);
file_bytes = ftell(f); 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); fread(buf, NL_RCV_PKT_BUF_SIZE, 1, f);
fclose(f); fclose(f);
} }
zserv_privs.change(ZPRIVS_LOWER);
return file_bytes; return file_bytes;
} }
@ -985,7 +977,6 @@ int netlink_request(struct nlsock *nl, struct nlmsghdr *n)
{ {
int ret; int ret;
struct sockaddr_nl snl; struct sockaddr_nl snl;
int save_errno;
/* Check netlink socket. */ /* Check netlink socket. */
if (nl->sock < 0) { if (nl->sock < 0) {
@ -1003,21 +994,14 @@ int netlink_request(struct nlsock *nl, struct nlmsghdr *n)
snl.nl_family = AF_NETLINK; snl.nl_family = AF_NETLINK;
/* Raise capabilities and send message, then lower capabilities. */ /* Raise capabilities and send message, then lower capabilities. */
if (zserv_privs.change(ZPRIVS_RAISE)) { frr_elevate_privs(&zserv_privs) {
flog_err(LIB_ERR_PRIVILEGES, "Can't raise privileges");
return -1;
}
ret = sendto(nl->sock, (void *)n, n->nlmsg_len, 0, ret = sendto(nl->sock, (void *)n, n->nlmsg_len, 0,
(struct sockaddr *)&snl, sizeof snl); (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) { if (ret < 0) {
flog_err_sys(LIB_ERR_SOCKET, "%s sendto failed: %s", nl->name, zlog_err("%s sendto failed: %s", nl->name,
safe_strerror(save_errno)); safe_strerror(errno));
return -1; return -1;
} }

View File

@ -1385,17 +1385,11 @@ static int kernel_read(struct thread *thread)
/* Make routing socket. */ /* Make routing socket. */
static void routing_socket(struct zebra_ns *zns) static void routing_socket(struct zebra_ns *zns)
{ {
if (zserv_privs.change(ZPRIVS_RAISE)) frr_elevate_privs(&zserv_privs) {
flog_err(LIB_ERR_PRIVILEGES, routing_sock = ns_socket(AF_ROUTE, SOCK_RAW, 0, zns->ns_id);
"routing_socket: Can't raise privileges"); }
routing_sock =
ns_socket(AF_ROUTE, SOCK_RAW, 0, zns->ns_id);
if (routing_sock < 0) { 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"); zlog_warn("Can't init kernel routing socket");
return; return;
} }
@ -1407,10 +1401,6 @@ static void routing_socket(struct zebra_ns *zns)
/*if (fcntl (routing_sock, F_SETFL, O_NONBLOCK) < 0) /*if (fcntl (routing_sock, F_SETFL, O_NONBLOCK) < 0)
zlog_warn ("Can't set O_NONBLOCK to routing socket");*/ 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. */ /* kernel_read needs rewrite. */
thread_add_read(zebrad.master, kernel_read, NULL, routing_sock, NULL); thread_add_read(zebrad.master, kernel_read, NULL, routing_sock, NULL);
} }

View File

@ -3087,12 +3087,13 @@ static void zserv_write_incoming(struct stream *orig, uint16_t command)
copy = stream_dup(orig); copy = stream_dup(orig);
stream_set_getp(copy, 0); stream_set_getp(copy, 0);
zserv_privs.change(ZPRIVS_RAISE);
snprintf(fname, MAXPATHLEN, "%s/%u", DAEMON_VTY_DIR, command); snprintf(fname, MAXPATHLEN, "%s/%u", DAEMON_VTY_DIR, command);
frr_elevate_privs(&zserv_privs) {
fd = open(fname, O_CREAT | O_WRONLY | O_EXCL, 0644); fd = open(fname, O_CREAT | O_WRONLY | O_EXCL, 0644);
}
stream_flush(copy, fd); stream_flush(copy, fd);
close(fd); close(fd);
zserv_privs.change(ZPRIVS_LOWER);
stream_free(copy); stream_free(copy);
} }
#endif #endif

View File

@ -787,15 +787,14 @@ void zserv_start(char *path)
unlink(suna->sun_path); unlink(suna->sun_path);
} }
zserv_privs.change(ZPRIVS_RAISE); frr_elevate_privs(&zserv_privs) {
setsockopt_so_recvbuf(zebrad.sock, 1048576); setsockopt_so_recvbuf(zebrad.sock, 1048576);
setsockopt_so_sendbuf(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((sa.ss_family != AF_UNIX) ? &zserv_privs : NULL) {
ret = bind(zebrad.sock, (struct sockaddr *)&sa, sa_len); ret = bind(zebrad.sock, (struct sockaddr *)&sa, sa_len);
}
if (ret < 0) { if (ret < 0) {
zlog_warn("Can't bind zserv socket on %s: %s", path, zlog_warn("Can't bind zserv socket on %s: %s", path,
safe_strerror(errno)); safe_strerror(errno));
@ -805,8 +804,6 @@ void zserv_start(char *path)
zebrad.sock = -1; zebrad.sock = -1;
return; 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); ret = listen(zebrad.sock, 5);
if (ret < 0) { if (ret < 0) {