2
0
mirror of https://github.com/sudo-project/sudo.git synced 2025-08-30 13:58:05 +00:00

Fix the buffer size parameter when serializing the interface list.

Problem reported by Matthias Gerstner of SUSE.
This commit is contained in:
Todd C. Miller
2020-12-21 10:44:22 -07:00
parent 295f099cfc
commit a29cac8bd6

View File

@@ -119,7 +119,8 @@ get_net_ifs(char **addrinfo)
#else #else
char addrstr[INET_ADDRSTRLEN], maskstr[INET_ADDRSTRLEN]; char addrstr[INET_ADDRSTRLEN], maskstr[INET_ADDRSTRLEN];
#endif #endif
int ailen, len, num_interfaces = 0; int len, num_interfaces = 0;
size_t ailen;
char *cp; char *cp;
debug_decl(get_net_ifs, SUDO_DEBUG_NETIF); debug_decl(get_net_ifs, SUDO_DEBUG_NETIF);
@@ -172,13 +173,14 @@ get_net_ifs(char **addrinfo)
if (inet_ntop(AF_INET, &sin->sin_addr, maskstr, sizeof(maskstr)) == NULL) if (inet_ntop(AF_INET, &sin->sin_addr, maskstr, sizeof(maskstr)) == NULL)
continue; continue;
len = snprintf(cp, ailen - (*addrinfo - cp), len = snprintf(cp, ailen, "%s%s/%s",
"%s%s/%s", cp == *addrinfo ? "" : " ", addrstr, maskstr); cp == *addrinfo ? "" : " ", addrstr, maskstr);
if (len < 0 || len >= ailen - (*addrinfo - cp)) { if (len < 0 || (size_t)len >= ailen) {
sudo_warnx(U_("internal error, %s overflow"), __func__); sudo_warnx(U_("internal error, %s overflow"), __func__);
goto done; goto done;
} }
cp += len; cp += len;
ailen -= len;
break; break;
#ifdef HAVE_STRUCT_IN6_ADDR #ifdef HAVE_STRUCT_IN6_ADDR
case AF_INET6: case AF_INET6:
@@ -189,13 +191,14 @@ get_net_ifs(char **addrinfo)
if (inet_ntop(AF_INET6, &sin6->sin6_addr, maskstr, sizeof(maskstr)) == NULL) if (inet_ntop(AF_INET6, &sin6->sin6_addr, maskstr, sizeof(maskstr)) == NULL)
continue; continue;
len = snprintf(cp, ailen - (*addrinfo - cp), len = snprintf(cp, ailen, "%s%s/%s",
"%s%s/%s", cp == *addrinfo ? "" : " ", addrstr, maskstr); cp == *addrinfo ? "" : " ", addrstr, maskstr);
if (len < 0 || len >= ailen - (*addrinfo - cp)) { if (len < 0 || (size_t)len >= ailen) {
sudo_warnx(U_("internal error, %s overflow"), __func__); sudo_warnx(U_("internal error, %s overflow"), __func__);
goto done; goto done;
} }
cp += len; cp += len;
ailen -= len;
break; break;
#endif /* HAVE_STRUCT_IN6_ADDR */ #endif /* HAVE_STRUCT_IN6_ADDR */
} }
@@ -223,8 +226,8 @@ get_net_ifs(char **addrinfo)
struct ifreq *ifr, *ifr_tmp = (struct ifreq *)ifr_tmpbuf; struct ifreq *ifr, *ifr_tmp = (struct ifreq *)ifr_tmpbuf;
struct ifconf *ifconf; struct ifconf *ifconf;
struct sockaddr_in *sin; struct sockaddr_in *sin;
int ailen, i, len, n, sock, num_interfaces = 0; int i, len, n, sock, num_interfaces = 0;
size_t buflen = sizeof(struct ifconf) + BUFSIZ; size_t ailen, buflen = sizeof(struct ifconf) + BUFSIZ;
char *cp, *previfname = "", *ifconf_buf = NULL; char *cp, *previfname = "", *ifconf_buf = NULL;
char addrstr[INET_ADDRSTRLEN], maskstr[INET_ADDRSTRLEN]; char addrstr[INET_ADDRSTRLEN], maskstr[INET_ADDRSTRLEN];
#ifdef _ISC #ifdef _ISC
@@ -334,13 +337,14 @@ get_net_ifs(char **addrinfo)
if (inet_ntop(AF_INET, &sin->sin_addr, maskstr, sizeof(maskstr)) == NULL) if (inet_ntop(AF_INET, &sin->sin_addr, maskstr, sizeof(maskstr)) == NULL)
continue; continue;
len = snprintf(cp, ailen - (*addrinfo - cp), len = snprintf(cp, ailen, "%s%s/%s",
"%s%s/%s", cp == *addrinfo ? "" : " ", addrstr, maskstr); cp == *addrinfo ? "" : " ", addrstr, maskstr);
if (len < 0 || len >= ailen - (*addrinfo - cp)) { if (len < 0 || (size_t)len >= ailen) {
sudo_warnx(U_("internal error, %s overflow"), __func__); sudo_warnx(U_("internal error, %s overflow"), __func__);
goto done; goto done;
} }
cp += len; cp += len;
ailen -= len;
/* Stash the name of the interface we saved. */ /* Stash the name of the interface we saved. */
previfname = ifr->ifr_name; previfname = ifr->ifr_name;