diff options
| author | Denys Fedoryshchenko <denys.f@collabora.com> | 2026-08-09 07:14:41 +0300 |
|---|---|---|
| committer | Denys Fedoryshchenko <denys.f@collabora.com> | 2026-08-09 08:58:08 +0300 |
| commit | a62e3abe2aae259f90289b431e086490020d49ed (patch) | |
| tree | 918411e51796e6c7f7cfc336db18ebca01cf8e86 | |
| parent | f49ed06b26b2b3ea3a97589be2e51ceb2a084243 (diff) | |
| download | accel-ppp-a62e3abe2aae259f90289b431e086490020d49ed.tar.gz accel-ppp-a62e3abe2aae259f90289b431e086490020d49ed.zip | |
pptp: check getsockname()/getpeername() results
Both calls were issued on an uninitialised struct sockaddr_in and their
results ignored, so a failure would build the tunnel endpoints, and the
call socket's local call id, out of stack garbage. Fail the call instead.
In pptp_connect() the local address was fetched into the same variable
that held the peer address obtained from accept(), so a failure there
would silently set called-station-id to the calling station. Read it
into its own variable before the connection is set up, and re-arm the
address length before each accept() rather than leaving it at whatever
the previous iteration wrote.
| -rw-r--r-- | accel-pppd/ctrl/pptp/pptp.c | 31 |
1 files changed, 24 insertions, 7 deletions
diff --git a/accel-pppd/ctrl/pptp/pptp.c b/accel-pppd/ctrl/pptp/pptp.c index 20f8495d..cc4d222a 100644 --- a/accel-pppd/ctrl/pptp/pptp.c +++ b/accel-pppd/ctrl/pptp/pptp.c @@ -360,7 +360,10 @@ static int pptp_out_call_rqst(struct pptp_conn_t *conn) src_addr.sa_protocol = PX_PROTO_PPTP; src_addr.sa_addr.pptp.call_id = 0; addrlen = sizeof(addr); - getsockname(conn->hnd.fd, (struct sockaddr*)&addr, &addrlen); + if (getsockname(conn->hnd.fd, (struct sockaddr*)&addr, &addrlen)) { + log_ppp_error("pptp: getsockname: %s\n", strerror(errno)); + return -1; + } src_addr.sa_addr.pptp.sin_addr = addr.sin_addr; memset(&dst_addr, 0, sizeof(dst_addr)); @@ -368,7 +371,10 @@ static int pptp_out_call_rqst(struct pptp_conn_t *conn) dst_addr.sa_protocol = PX_PROTO_PPTP; dst_addr.sa_addr.pptp.call_id = htons(msg->call_id); addrlen = sizeof(addr); - getpeername(conn->hnd.fd, (struct sockaddr*)&addr, &addrlen); + if (getpeername(conn->hnd.fd, (struct sockaddr*)&addr, &addrlen)) { + log_ppp_error("pptp: getpeername: %s\n", strerror(errno)); + return -1; + } dst_addr.sa_addr.pptp.sin_addr = addr.sin_addr; pptp_sock = socket(AF_PPPOX, SOCK_STREAM, PX_PROTO_PPTP); @@ -385,7 +391,11 @@ static int pptp_out_call_rqst(struct pptp_conn_t *conn) return -1; } addrlen = sizeof(src_addr); - getsockname(pptp_sock, (struct sockaddr*)&src_addr, &addrlen); + if (getsockname(pptp_sock, (struct sockaddr*)&src_addr, &addrlen)) { + log_ppp_error("pptp: getsockname: %s\n", strerror(errno)); + close(pptp_sock); + return -1; + } if (connect(pptp_sock, (struct sockaddr*)&dst_addr, sizeof(dst_addr))) { log_ppp_error("failed to connect PPTP socket (%s)\n", strerror(errno)); @@ -687,12 +697,13 @@ static void ppp_finished(struct ap_session *ses) static int pptp_connect(struct triton_md_handler_t *h) { - struct sockaddr_in addr; - socklen_t size = sizeof(addr); + struct sockaddr_in addr, laddr; + socklen_t size; int sock; struct pptp_conn_t *conn; while(1) { + size = sizeof(addr); sock = accept(h->fd, (struct sockaddr *)&addr, &size); if (sock < 0) { if (errno == EAGAIN) @@ -729,6 +740,13 @@ static int pptp_connect(struct triton_md_handler_t *h) continue; } + size = sizeof(laddr); + if (getsockname(sock, (struct sockaddr *)&laddr, &size)) { + log_error("pptp: getsockname: %s, closing connection...\n", strerror(errno)); + close(sock); + continue; + } + if (fcntl(sock, F_SETFL, O_NONBLOCK)) { log_error("pptp: failed to set nonblocking mode: %s, closing connection...\n", strerror(errno)); close(sock); @@ -761,8 +779,7 @@ static int pptp_connect(struct triton_md_handler_t *h) conn->ctrl.calling_station_id = _malloc(17); conn->ctrl.called_station_id = _malloc(17); u_inet_ntoa(addr.sin_addr.s_addr, conn->ctrl.calling_station_id); - getsockname(sock, (struct sockaddr*)&addr, &size); - u_inet_ntoa(addr.sin_addr.s_addr, conn->ctrl.called_station_id); + u_inet_ntoa(laddr.sin_addr.s_addr, conn->ctrl.called_station_id); ppp_init(&conn->ppp); conn->ppp.ses.ctrl = &conn->ctrl; |
