Bug 2343447 (RUSTSEC-2025-0004)

Summary: rust-openssl: ssl::select_next_proto use after free
Product: [Other] Security Response Reporter: OSIDB Bzimport <bzimport>
Component: vulnerability-draftAssignee: Product Security DevOps Team <prodsec-dev>
Status: NEW --- QA Contact:
Severity: medium Docs Contact:
Priority: medium    
Version: unspecifiedKeywords: Security
Target Milestone: ---   
Target Release: ---   
Hardware: All   
OS: Linux   
Whiteboard:
Fixed In Version: Doc Type: If docs needed, set a value
Doc Text:
A flaw was found in the rust implementation of openssl. A ssl::select_next_proto can return a slice pointing into the server argument's buffer but with a lifetime bound to the client argument. In situations where the server buffer's lifetime is shorter than the client buffer's, this can cause a use-after-free, which could cause the server to crash or return arbitrary memory contents to the client.
Story Points: ---
Clone Of: Environment:
Last Closed: Type: ---
Regression: --- Mount Type: ---
Documentation: --- CRM:
Verified Versions: Category: ---
oVirt Team: --- RHEL 7.3 requirements from Atomic Host:
Cloudforms Team: --- Target Upstream Version:
Embargoed:
Bug Depends On: 2344553, 2344555, 2344557, 2344559, 2343477, 2343478, 2343479, 2344551, 2344552, 2344554, 2344556, 2344558    
Bug Blocks:    

Description OSIDB Bzimport 2025-02-03 01:01:53 UTC
In `openssl` versions before `0.10.70`, `ssl::select_next_proto` can return a slice pointing into the `server` argument's buffer but with a lifetime bound to the `client` argument. In situations where the `server` buffer's lifetime is shorter than the `client` buffer's, this can cause a use after free. This could cause the server to crash or to return arbitrary memory contents to the client.

`openssl` 0.10.70 fixes the signature of `ssl::select_next_proto` to properly constrain the output buffer's lifetime to that of both input buffers.

In standard usage of `ssl::select_next_proto` in the callback passed to `SslContextBuilder::set_alpn_select_callback`, code is only affected if the `server` buffer is constructed *within* the callback. For example:

Not vulnerable - the server buffer has a `'static` lifetime:
```rust
builder.set_alpn_select_callback(|_, client_protos| {
    ssl::select_next_proto(b"\x02h2", client_protos).ok_or_else(AlpnError::NOACK)
});
```

Not vulnerable - the server buffer outlives the handshake:
```rust
let server_protos = b"\x02h2".to_vec();
builder.set_alpn_select_callback(|_, client_protos| {
    ssl::select_next_proto(&server_protos, client_protos).ok_or_else(AlpnError::NOACK)
});
```

Vulnerable - the server buffer is freed when the callback returns:
```rust
builder.set_alpn_select_callback(|_, client_protos| {
    let server_protos = b"\x02h2".to_vec();
    ssl::select_next_proto(&server_protos, client_protos).ok_or_else(AlpnError::NOACK)
});
```