From: Daniel Stenberg Date: Mon, 8 Sep 2025 12:14:15 +0000 (+0200) Subject: [PATCH] ws: get a new mask for each new outgoing frame X-Git-Tag: archive/raspbian/7.88.1-10+rpi1+deb12u15^2~13 X-Git-Url: https://dgit.raspbian.org/?a=commitdiff_plain;h=93d469145452d334e108da2494545898d20811f8;p=curl.git [PATCH] ws: get a new mask for each new outgoing frame Reported-by: Calvin Ruocco Closes #18496 Backported-by: Samuel Henrique Backported-by: Alex Changes: * Refresh patch context for lib/ws.c * Adapt return value to current function return type Backported by: Samuel Henrique Changes: * Apply the per-frame mask generation in ws_packethead() (bookworm 7.88.1) rather than upstream's ws_enc_add_frame() (and trixie's ws_enc_write_head()), since the bookworm code path that builds the outgoing frame header is structurally different. On Curl_rand() failure return 0 -- ws_packethead() already uses 0 as the soft-error sentinel for buffer-too-small. * Preserve the DEBUGBUILD CURL_WS_FORCE_ZERO_MASK escape hatch alongside the new per-frame mask generation, matching upstream. * Remove the corresponding one-time mask generation in Curl_ws_accept(), and initialise `result` to CURLE_OK at declaration since it is no longer unconditionally assigned by the removed Curl_rand() call. Gbp-Pq: Name CVE-2025-10148.patch --- diff --git a/lib/ws.c b/lib/ws.c index 0fc5e56a..992357ca 100644 --- a/lib/ws.c +++ b/lib/ws.c @@ -127,7 +127,7 @@ CURLcode Curl_ws_accept(struct Curl_easy *data, struct connectdata *conn = data->conn; struct websocket *wsp = &data->req.p.http->ws; struct ws_conn *wsc = &conn->proto.ws; - CURLcode result; + CURLcode result = CURLE_OK; /* Verify the Sec-WebSocket-Accept response. @@ -148,13 +148,7 @@ CURLcode Curl_ws_accept(struct Curl_easy *data, subprotocol not requested by the client), the client MUST Fail the WebSocket Connection. */ - /* 4 bytes random */ - result = Curl_rand(data, (unsigned char *)&ws->ws.mask, sizeof(ws->ws.mask)); - if(result) - return result; - - infof(data, "Received 101, switch to WebSocket; mask %02x%02x%02x%02x", - ws->ws.mask[0], ws->ws.mask[1], ws->ws.mask[2], ws->ws.mask[3]); + infof(data, "Received 101, switch to WebSocket"); Curl_dyn_init(&wsc->early, data->set.buffer_size); if(nread) { result = Curl_dyn_addn(&wsc->early, mem, nread); @@ -628,6 +622,20 @@ static size_t ws_packethead(struct Curl_easy *data, firstbyte); infof(data, "WS: send payload len %u", (int)len); + /* 4 bytes random */ + { + CURLcode result = Curl_rand(data, (unsigned char *)&ws->ws.mask, + sizeof(ws->ws.mask)); + if(result) + return 0; + } + +#ifdef DEBUGBUILD + if(getenv("CURL_WS_FORCE_ZERO_MASK")) + /* force the bit mask to 0x00000000, effectively disabling masking */ + memset(&ws->ws.mask, 0, sizeof(ws->ws.mask)); +#endif + /* 4 bytes mask */ memcpy(&out[outi], &ws->ws.mask, 4);