From b3713485887e685343e99342112852c85e1e5148 Mon Sep 17 00:00:00 2001 From: Jaroslav Kysela Date: Sat, 8 Apr 2017 11:10:56 +0200 Subject: [PATCH] replace 'struct sockaddr' with 'struct sockaddr_storage' this really fatal problem caused stack overflows - detected by c-lang sanitizers --- src/access.c | 20 ++++++++++---------- src/access.h | 8 ++++---- src/htsp_server.c | 10 ++++------ src/http.c | 8 +++----- src/satip/rtp.c | 4 ++-- src/satip/rtsp.c | 2 +- src/satip/server.c | 8 ++++---- src/tcp.c | 6 +++--- src/tcp.h | 2 +- src/webui/comet.c | 2 +- 10 files changed, 33 insertions(+), 37 deletions(-) diff --git a/src/access.c b/src/access.c index 1e43d0649..361b1d00c 100644 --- a/src/access.c +++ b/src/access.c @@ -225,13 +225,13 @@ access_destroy(access_t *a) * */ static int -netmask_verify(access_entry_t *ae, struct sockaddr *src) +netmask_verify(access_entry_t *ae, struct sockaddr_storage *src) { access_ipmask_t *ai; int isv4v6 = 0; uint32_t v4v6 = 0; - if (src->sa_family == AF_INET6) { + if (src->ss_family == AF_INET6) { struct in6_addr *in6 = &(((struct sockaddr_in6 *)src)->sin6_addr); uint32_t *a32 = (uint32_t*)in6->s6_addr; if (a32[0] == 0 && a32[1] == 0 && ntohl(a32[2]) == 0x0000FFFFu) { @@ -242,7 +242,7 @@ netmask_verify(access_entry_t *ae, struct sockaddr *src) TAILQ_FOREACH(ai, &ae->ae_ipmasks, ai_link) { - if (ai->ai_family == AF_INET && src->sa_family == AF_INET) { + if (ai->ai_family == AF_INET && src->ss_family == AF_INET) { struct sockaddr_in *in4 = (struct sockaddr_in *)src; uint32_t b = ntohl(in4->sin_addr.s_addr); @@ -258,7 +258,7 @@ netmask_verify(access_entry_t *ae, struct sockaddr *src) continue; - } else if (ai->ai_family == AF_INET6 && src->sa_family == AF_INET6) { + } else if (ai->ai_family == AF_INET6 && src->ss_family == AF_INET6) { struct in6_addr *in6 = &(((struct sockaddr_in6 *)src)->sin6_addr); uint8_t *a8 = (uint8_t*)in6->s6_addr; @@ -294,7 +294,7 @@ netmask_verify(access_entry_t *ae, struct sockaddr *src) */ int access_verify(const char *username, const char *password, - struct sockaddr *src, uint32_t mask) + struct sockaddr_storage *src, uint32_t mask) { uint32_t bits = 0; access_entry_t *ae; @@ -476,7 +476,7 @@ access_update(access_t *a, access_entry_t *ae) * */ access_t * -access_get(const char *username, const char *password, struct sockaddr *src) +access_get(const char *username, const char *password, struct sockaddr_storage *src) { access_t *a = calloc(1, sizeof(*a)); access_entry_t *ae; @@ -486,7 +486,7 @@ access_get(const char *username, const char *password, struct sockaddr *src) a->aa_representative = strdup(username); } else { a->aa_representative = malloc(50); - tcp_get_ip_str((struct sockaddr*)src, a->aa_representative, 50); + tcp_get_ip_str(src, a->aa_representative, 50); } if (access_noacl) { @@ -543,7 +543,7 @@ access_get(const char *username, const char *password, struct sockaddr *src) */ access_t * access_get_hashed(const char *username, const uint8_t digest[20], - const uint8_t *challenge, struct sockaddr *src) + const uint8_t *challenge, struct sockaddr_storage *src) { access_t *a = calloc(1, sizeof(*a)); access_entry_t *ae; @@ -555,7 +555,7 @@ access_get_hashed(const char *username, const uint8_t digest[20], a->aa_representative = strdup(username); } else { a->aa_representative = malloc(50); - tcp_get_ip_str((struct sockaddr*)src, a->aa_representative, 50); + tcp_get_ip_str(src, a->aa_representative, 50); } if(access_noacl) { @@ -621,7 +621,7 @@ access_get_hashed(const char *username, const uint8_t digest[20], * */ access_t * -access_get_by_addr(struct sockaddr *src) +access_get_by_addr(struct sockaddr_storage *src) { access_t *a = calloc(1, sizeof(*a)); access_entry_t *ae; diff --git a/src/access.h b/src/access.h index bdfc8e736..dd204df11 100644 --- a/src/access.h +++ b/src/access.h @@ -161,7 +161,7 @@ access_t *access_copy(access_t *src); * Return 0 if access is granted, -1 otherwise */ int access_verify(const char *username, const char *password, - struct sockaddr *src, uint32_t mask); + struct sockaddr_storage *src, uint32_t mask); static inline int access_verify2(access_t *a, uint32_t mask) { return (mask & ACCESS_OR) ? @@ -174,20 +174,20 @@ int access_verify_list(htsmsg_t *list, const char *item); * Get the access structure */ access_t *access_get(const char *username, const char *password, - struct sockaddr *src); + struct sockaddr_storage *src); /** * */ access_t * access_get_hashed(const char *username, const uint8_t digest[20], - const uint8_t *challenge, struct sockaddr *src); + const uint8_t *challenge, struct sockaddr_storage *src); /** * */ access_t * -access_get_by_addr(struct sockaddr *src); +access_get_by_addr(struct sockaddr_storage *src); /** * diff --git a/src/htsp_server.c b/src/htsp_server.c index a0441db36..7c017f5ad 100644 --- a/src/htsp_server.c +++ b/src/htsp_server.c @@ -578,7 +578,7 @@ htsp_build_channel(channel_t *ch, const char *method, htsp_connection_t *htsp) char buf[50]; addrlen = sizeof(addr); getsockname(htsp->htsp_fd, (struct sockaddr*)&addr, &addrlen); - tcp_get_ip_str((struct sockaddr*)&addr, buf, 50); + tcp_get_ip_str(&addr, buf, 50); snprintf(url, sizeof(url), "http://%s%s%s:%d%s/%s", (addr.ss_family == AF_INET6)?"[":"", buf, @@ -2542,8 +2542,7 @@ htsp_authenticate(htsp_connection_t *htsp, htsmsg_t *m) if(htsmsg_get_bin(m, "digest", &digest, &digestlen)) return 0; - rights = access_get_hashed(username, digest, htsp->htsp_challenge, - (struct sockaddr *)htsp->htsp_peer); + rights = access_get_hashed(username, digest, htsp->htsp_challenge, htsp->htsp_peer); privgain = (rights->aa_rights | htsp->htsp_granted_access->aa_rights) != @@ -2630,8 +2629,7 @@ htsp_read_loop(htsp_connection_t *htsp) pthread_mutex_lock(&global_lock); - htsp->htsp_granted_access = - access_get_by_addr((struct sockaddr *)htsp->htsp_peer); + htsp->htsp_granted_access = access_get_by_addr(htsp->htsp_peer); tcp_id = tcp_connection_launch(htsp->htsp_fd, htsp_server_status, htsp->htsp_granted_access); @@ -2793,7 +2791,7 @@ htsp_serve(int fd, void **opaque, struct sockaddr_storage *source, // Note: global_lock held on entry - tcp_get_ip_str((struct sockaddr*)source, buf, 50); + tcp_get_ip_str(source, buf, 50); memset(&htsp, 0, sizeof(htsp_connection_t)); *opaque = &htsp; diff --git a/src/http.c b/src/http.c index 2a418bbb0..760a56101 100644 --- a/src/http.c +++ b/src/http.c @@ -516,8 +516,7 @@ http_access_verify(http_connection_t *hc, int mask) http_access_verify_ticket(hc); if (hc->hc_access == NULL) { - hc->hc_access = access_get(hc->hc_username, hc->hc_password, - (struct sockaddr *)hc->hc_peer); + hc->hc_access = access_get(hc->hc_username, hc->hc_password, hc->hc_peer); if (hc->hc_access == NULL) return -1; } @@ -540,8 +539,7 @@ http_access_verify_channel(http_connection_t *hc, int mask, http_access_verify_ticket(hc); if (hc->hc_access == NULL) { - hc->hc_access = access_get(hc->hc_username, hc->hc_password, - (struct sockaddr *)hc->hc_peer); + hc->hc_access = access_get(hc->hc_username, hc->hc_password, hc->hc_peer); if (hc->hc_access == NULL) return -1; } @@ -734,7 +732,7 @@ process_request(http_connection_t *hc, htsbuf_queue_t *spill) char authbuf[150]; hc->hc_url_orig = tvh_strdupa(hc->hc_url); - tcp_get_ip_str((struct sockaddr*)hc->hc_peer, authbuf, sizeof(authbuf)); + tcp_get_ip_str(hc->hc_peer, authbuf, sizeof(authbuf)); hc->hc_peer_ipstr = tvh_strdupa(authbuf); hc->hc_representative = hc->hc_peer_ipstr; hc->hc_username = NULL; diff --git a/src/satip/rtp.c b/src/satip/rtp.c index d6062dfa4..6cea09884 100644 --- a/src/satip/rtp.c +++ b/src/satip/rtp.c @@ -168,7 +168,7 @@ satip_rtp_thread(void *aux) char peername[50]; int alive = 1, fatal = 0, r; - tcp_get_ip_str((struct sockaddr *)&rtp->peer, peername, sizeof(peername)); + tcp_get_ip_str(&rtp->peer, peername, sizeof(peername)); tvhdebug("satips", "RTP streaming to %s:%d open", peername, rtp->port); pthread_mutex_lock(&sq->sq_mutex); @@ -611,7 +611,7 @@ satip_rtcp_thread(void *aux) sizeof(struct sockaddr_in6) : sizeof(struct sockaddr_in)); if (r < 0) { err = errno; - tcp_get_ip_str((struct sockaddr*)&rtp->peer2, addrbuf, sizeof(addrbuf)); + tcp_get_ip_str(&rtp->peer2, addrbuf, sizeof(addrbuf)); tvhwarn("satips", "RTCP send to error %s:%d : %s", addrbuf, IP_PORT(rtp->peer2), strerror(err)); } diff --git a/src/satip/rtsp.c b/src/satip/rtsp.c index af4b1a379..707e5b783 100644 --- a/src/satip/rtsp.c +++ b/src/satip/rtsp.c @@ -1446,7 +1446,7 @@ rtsp_serve(int fd, void **opaque, struct sockaddr_storage *peer, memset(&aa, 0, sizeof(aa)); strcpy(buf, "SAT>IP Client "); - tcp_get_ip_str((struct sockaddr *)peer, buf + strlen(buf), sizeof(buf) - strlen(buf)); + tcp_get_ip_str(peer, buf + strlen(buf), sizeof(buf) - strlen(buf)); aa.aa_representative = buf; tcp = tcp_connection_launch(fd, rtsp_stream_status, &aa); diff --git a/src/satip/server.c b/src/satip/server.c index ae0b905d6..2c565843f 100644 --- a/src/satip/server.c +++ b/src/satip/server.c @@ -348,7 +348,7 @@ CONFIGID.UPNP.ORG: 0\r\n" return; #if ENABLE_TRACE - tcp_get_ip_str((struct sockaddr *)dst, buf, sizeof(buf)); + tcp_get_ip_str(dst, buf, sizeof(buf)); tvhtrace("satips", "sending discover reply to %s:%d%s%s", buf, IP_PORT(*dst), deviceid ? " device: " : "", deviceid ?: ""); #endif @@ -453,7 +453,7 @@ satips_upnp_discovery_received return; #if ENABLE_TRACE - tcp_get_ip_str((struct sockaddr *)storage, buf2, sizeof(buf2)); + tcp_get_ip_str(storage, buf2, sizeof(buf2)); tvhtrace("satips", "received %s M-SEARCH from %s:%d", conn->multicast ? "multicast" : "unicast", buf2, ntohs(IP_PORT(*storage))); @@ -465,7 +465,7 @@ satips_upnp_discovery_received satip_server_deviceid += 1; if (satip_server_deviceid >= 254) satip_server_deviceid = 1; - tcp_get_ip_str((struct sockaddr *)storage, buf2, sizeof(buf2)); + tcp_get_ip_str(storage, buf2, sizeof(buf2)); tvhwarn("satips", "received duplicate SAT>IP DeviceID %s from %s:%d, using %d", deviceid, buf2, ntohs(IP_PORT(*storage)), satip_server_deviceid); satips_upnp_send_discover_reply(storage, deviceid); @@ -571,7 +571,7 @@ void satip_server_init(int rtsp_port) tvherror("satips", "Unable to determine the HTTP/RTSP address"); return; } - tcp_get_ip_str((const struct sockaddr *)&http, http_ip, sizeof(http_ip)); + tcp_get_ip_str(&http, http_ip, sizeof(http_ip)); http_server_ip = strdup(http_ip); http_server_port = ntohs(IP_PORT(http)); diff --git a/src/tcp.c b/src/tcp.c index 616939cbd..0058ef6bd 100644 --- a/src/tcp.c +++ b/src/tcp.c @@ -355,12 +355,12 @@ tcp_read_timeout(int fd, void *buf, size_t len, int timeout) * */ char * -tcp_get_ip_str(const struct sockaddr *sa, char *s, size_t maxlen) +tcp_get_ip_str(const struct sockaddr_storage *sa, char *s, size_t maxlen) { if(sa == NULL || s == NULL) return NULL; - switch(sa->sa_family) + switch(sa->ss_family) { case AF_INET: inet_ntop(AF_INET, &(((struct sockaddr_in*)sa)->sin_addr), s, maxlen); @@ -857,7 +857,7 @@ tcp_server_connections ( void ) if (!tsl->status) continue; c++; e = htsmsg_create_map(); - tcp_get_ip_str((struct sockaddr*)&tsl->peer, buf, sizeof(buf)); + tcp_get_ip_str(&tsl->peer, buf, sizeof(buf)); htsmsg_add_u32(e, "id", tsl->id); htsmsg_add_str(e, "peer", buf); htsmsg_add_s64(e, "started", tsl->started); diff --git a/src/tcp.h b/src/tcp.h index 2a525976f..ef5c43c52 100644 --- a/src/tcp.h +++ b/src/tcp.h @@ -85,7 +85,7 @@ int tcp_write_queue(int fd, htsbuf_queue_t *q); int tcp_read_timeout(int fd, void *buf, size_t len, int timeout); -char *tcp_get_ip_str(const struct sockaddr *sa, char *s, size_t maxlen); +char *tcp_get_ip_str(const struct sockaddr_storage *sa, char *s, size_t maxlen); struct access; diff --git a/src/webui/comet.c b/src/webui/comet.c index 423af7261..a6b605eac 100644 --- a/src/webui/comet.c +++ b/src/webui/comet.c @@ -166,7 +166,7 @@ comet_serverIpPort(http_connection_t *hc, comet_mailbox_t *cmb) char buf[50]; uint32_t port; - tcp_get_ip_str((struct sockaddr*)hc->hc_self, buf, 50); + tcp_get_ip_str(hc->hc_self, buf, 50); if(hc->hc_self->ss_family == AF_INET) port = ((struct sockaddr_in*)hc->hc_self)->sin_port; -- 2.47.2