Skip to content

Commit

Permalink
Merge pull request #200 from simetnicbr/for-upstream/privileged-SO_BI…
Browse files Browse the repository at this point in the history
…NDTODEVICE

fping: retain privileges until after privileged setsockopt
  • Loading branch information
schweikert authored Oct 17, 2020
2 parents 49673f7 + 59d83ed commit eac2034
Showing 1 changed file with 49 additions and 6 deletions.
55 changes: 49 additions & 6 deletions src/fping.c
Original file line number Diff line number Diff line change
Expand Up @@ -395,6 +395,42 @@ struct event *host_get_timeout_event(HOST_ENTRY *h, int index);
void stats_add(HOST_ENTRY *h, int index, int success, int64_t latency);
void update_current_time();

/************************************************************
Function: p_setsockopt
*************************************************************
Inputs: p_uid: privileged uid. Others as per setsockopt(2)
Description:
Elevates privileges to p_uid when required, calls
setsockopt, and drops privileges back.
************************************************************/

int p_setsockopt(uid_t p_uid, int sockfd, int level, int optname,
const void *optval, socklen_t optlen)
{
const uid_t saved_uid = geteuid();
int res;

if (p_uid != saved_uid && seteuid(p_uid)) {
perror("cannot elevate privileges for setsockopt");
}

res = setsockopt(sockfd, level, optname, optval, optlen);

if (p_uid != saved_uid && seteuid(saved_uid)) {
perror("fatal error: could not drop privileges after setsockopt");
/* continuing would be a security hole */
exit(4);
}

return res;
}

/************************************************************
Function: main
Expand All @@ -412,7 +448,7 @@ void update_current_time();
int main(int argc, char** argv)
{
int c;
uid_t uid;
const uid_t suid = geteuid();
int tos = 0;
struct optparse optparse_state;
#ifdef USE_SIGACTION
Expand Down Expand Up @@ -448,9 +484,9 @@ int main(int argc, char** argv)
memset(&src_addr6, 0, sizeof(src_addr6));
#endif

if ((uid = getuid())) {
/* drop privileges */
if (setuid(getuid()) == -1)
if (!suid && suid != getuid()) {
/* *temporarily* drop privileges */
if (seteuid(getuid()) == -1)
perror("cannot setuid");
}

Expand Down Expand Up @@ -740,14 +776,14 @@ int main(int argc, char** argv)
case 'I':
#ifdef SO_BINDTODEVICE
if (socket4 >= 0) {
if (setsockopt(socket4, SOL_SOCKET, SO_BINDTODEVICE, optparse_state.optarg, strlen(optparse_state.optarg))) {
if (p_setsockopt(suid, socket4, SOL_SOCKET, SO_BINDTODEVICE, optparse_state.optarg, strlen(optparse_state.optarg))) {
perror("binding to specific interface (SO_BINTODEVICE)");
exit(1);
}
}
#ifdef IPV6
if (socket6 >= 0) {
if (setsockopt(socket6, SOL_SOCKET, SO_BINDTODEVICE, optparse_state.optarg, strlen(optparse_state.optarg))) {
if (p_setsockopt(suid, socket6, SOL_SOCKET, SO_BINDTODEVICE, optparse_state.optarg, strlen(optparse_state.optarg))) {
perror("binding to specific interface (SO_BINTODEVICE), IPV6");
exit(1);
}
Expand Down Expand Up @@ -796,6 +832,13 @@ int main(int argc, char** argv)
}
}

/* permanetly drop privileges */
if (suid != getuid() && setuid(getuid())) {
perror("fatal: failed to permanently drop privileges");
/* continuing would be a security hole */
exit(4);
}

/* validate various option settings */

#ifndef IPV6
Expand Down

0 comments on commit eac2034

Please sign in to comment.