diff options
| author | Denys Fedoryshchenko <denys.f@collabora.com> | 2026-01-25 23:52:07 +0200 |
|---|---|---|
| committer | Denys Fedoryshchenko <denys.f@collabora.com> | 2026-03-23 00:04:30 +0200 |
| commit | 54bf5e394dbd909c5a57a7fbc25d8d7cff2896f3 (patch) | |
| tree | af9ee38f422b108fcdb0b3ba6003d574cdaa4428 | |
| parent | 4ef81e45d567e64a41e1027c63e16309b9f1027b (diff) | |
| download | accel-ppp-54bf5e394dbd909c5a57a7fbc25d8d7cff2896f3.tar.gz accel-ppp-54bf5e394dbd909c5a57a7fbc25d8d7cff2896f3.zip | |
ppp: guard LCP logging field reads
Signed-off-by: Denys Fedoryshchenko <denys.f@collabora.com>
| -rw-r--r-- | accel-pppd/ppp/ppp_lcp.c | 40 |
1 files changed, 36 insertions, 4 deletions
diff --git a/accel-pppd/ppp/ppp_lcp.c b/accel-pppd/ppp/ppp_lcp.c index 62c0f897c..05b6c4a6 100644 --- a/accel-pppd/ppp/ppp_lcp.c +++ b/accel-pppd/ppp/ppp_lcp.c @@ -738,6 +738,8 @@ static void lcp_recv(struct ppp_handler_t*h) struct ppp_lcp_t *lcp = container_of(h, typeof(*lcp), hnd); int r; char *term_msg; + uint16_t len; + int buf_len; if (lcp->ppp->buf_size < PPP_HEADERLEN + 2) { log_ppp_warn("LCP: short packet received\n"); @@ -745,7 +747,9 @@ static void lcp_recv(struct ppp_handler_t*h) } hdr = (struct lcp_hdr_t *)lcp->ppp->buf; - if (ntohs(hdr->len) < PPP_HEADERLEN) { + len = ntohs(hdr->len); + buf_len = lcp->ppp->buf_size; + if (len < PPP_HEADERLEN) { log_ppp_warn("LCP: short packet received\n"); return; } @@ -832,25 +836,53 @@ static void lcp_recv(struct ppp_handler_t*h) ppp_fsm_recv_code_rej_bad(&lcp->fsm); break; case ECHOREQ: + if (len < PPP_HDRLEN + 4 || buf_len < (int)(sizeof(*hdr) + 4)) { + log_ppp_warn("LCP: short EchoReq received\n"); + break; + } if (conf_ppp_verbose) log_ppp_debug("recv [LCP EchoReq id=%x <magic %08x>]\n", hdr->id, ntohl(*(uint32_t*)(hdr + 1))); send_echo_reply(lcp); break; case ECHOREP: + if (len < PPP_HDRLEN + 4 || buf_len < (int)(sizeof(*hdr) + 4)) { + log_ppp_warn("LCP: short EchoRep received\n"); + break; + } lcp_recv_echo_repl(lcp, (uint8_t*)(hdr + 1), ntohs(hdr->len) - PPP_HDRLEN); break; case PROTOREJ: - if (conf_ppp_verbose) + if (conf_ppp_verbose) { + if (len < PPP_HDRLEN + 2 || buf_len < (int)(sizeof(*hdr) + 2)) { + log_ppp_warn("LCP: short ProtoRej received\n"); + break; + } log_ppp_info2("recv [LCP ProtoRej id=%x <%04x>]\n", hdr->id, ntohs(*(uint16_t*)(hdr + 1))); + } + if (len < PPP_HDRLEN + 2 || buf_len < (int)(sizeof(*hdr) + 2)) + break; ppp_recv_proto_rej(lcp->ppp, ntohs(*(uint16_t *)(hdr + 1))); break; case DISCARDREQ: - if (conf_ppp_verbose) + if (conf_ppp_verbose) { + if (len < PPP_HDRLEN + 4 || buf_len < (int)(sizeof(*hdr) + 4)) { + log_ppp_warn("LCP: short DiscardReq received\n"); + break; + } log_ppp_info2("recv [LCP DiscardReq id=%x <magic %08x>]\n", hdr->id, ntohl(*(uint32_t*)(hdr + 1))); + } break; case IDENT: if (conf_ppp_verbose) { - term_msg = _strndup((char*)(hdr + 1) + 4, ntohs(hdr->len) - 4 - 4); + int id_len; + if (len < PPP_HDRLEN + 4 || buf_len < (int)(sizeof(*hdr) + 4)) { + log_ppp_warn("LCP: short Ident received\n"); + break; + } + id_len = len - PPP_HDRLEN - 4; + if (buf_len < (int)(sizeof(*hdr) + 4 + id_len)) + id_len = buf_len - sizeof(*hdr) - 4; + term_msg = _strndup((char*)(hdr + 1) + 4, id_len); log_ppp_info2("recv [LCP Ident id=%x <%s>]\n", hdr->id, term_msg); _free(term_msg); } |
