CVE-2026-45887
Description
In the Linux kernel, the following vulnerability has been resolved:
af_unix: Fix memleak of newsk in unix_stream_connect().
When prepare_peercred() fails in unix_stream_connect(), unix_release_sock() is not called for newsk, and the memory is leaked.
Let's move prepare_peercred() before unix_create1().
Affected products
1Patches
66884028cd7f2af_unix: Fix memleak of newsk in unix_stream_connect().
1 file changed · +3 −9
net/unix/af_unix.c+3 −9 modifieddiff --git a/net/unix/af_unix.c b/net/unix/af_unix.c index d0511225799ba3..f6d56e70c7a2c3 100644 --- a/net/unix/af_unix.c +++ b/net/unix/af_unix.c @@ -1650,10 +1650,9 @@ static int unix_stream_connect(struct socket *sock, struct sockaddr_unsized *uad timeo = sock_sndtimeo(sk, flags & O_NONBLOCK); - /* First of all allocate resources. - * If we will make it after state is locked, - * we will have to recheck all again in any case. - */ + err = prepare_peercred(&peercred); + if (err) + goto out; /* create new sock for complete connection */ newsk = unix_create1(net, NULL, 0, sock->type); @@ -1662,10 +1661,6 @@ static int unix_stream_connect(struct socket *sock, struct sockaddr_unsized *uad goto out; } - err = prepare_peercred(&peercred); - if (err) - goto out; - /* Allocate skb for sending to listening sock */ skb = sock_wmalloc(newsk, 1, 0, GFP_KERNEL); if (!skb) { -- cgit 1.3-korg
365996a2b14daf_unix: Fix memleak of newsk in unix_stream_connect().
1 file changed · +3 −9
net/unix/af_unix.c+3 −9 modifieddiff --git a/net/unix/af_unix.c b/net/unix/af_unix.c index c634a7fc860906..9dad3af700af3e 100644 --- a/net/unix/af_unix.c +++ b/net/unix/af_unix.c @@ -1671,10 +1671,9 @@ static int unix_stream_connect(struct socket *sock, struct sockaddr *uaddr, timeo = sock_sndtimeo(sk, flags & O_NONBLOCK); - /* First of all allocate resources. - * If we will make it after state is locked, - * we will have to recheck all again in any case. - */ + err = prepare_peercred(&peercred); + if (err) + goto out; /* create new sock for complete connection */ newsk = unix_create1(net, NULL, 0, sock->type); @@ -1683,10 +1682,6 @@ static int unix_stream_connect(struct socket *sock, struct sockaddr *uaddr, goto out; } - err = prepare_peercred(&peercred); - if (err) - goto out; - /* Allocate skb for sending to listening sock */ skb = sock_wmalloc(newsk, 1, 0, GFP_KERNEL); if (!skb) { -- cgit 1.3-korg
a5d95d7caba0af_unix: Fix memleak of newsk in unix_stream_connect().
1 file changed · +3 −9
net/unix/af_unix.c+3 −9 modifieddiff --git a/net/unix/af_unix.c b/net/unix/af_unix.c index d0511225799ba3..f6d56e70c7a2c3 100644 --- a/net/unix/af_unix.c +++ b/net/unix/af_unix.c @@ -1650,10 +1650,9 @@ static int unix_stream_connect(struct socket *sock, struct sockaddr_unsized *uad timeo = sock_sndtimeo(sk, flags & O_NONBLOCK); - /* First of all allocate resources. - * If we will make it after state is locked, - * we will have to recheck all again in any case. - */ + err = prepare_peercred(&peercred); + if (err) + goto out; /* create new sock for complete connection */ newsk = unix_create1(net, NULL, 0, sock->type); @@ -1662,10 +1661,6 @@ static int unix_stream_connect(struct socket *sock, struct sockaddr_unsized *uad goto out; } - err = prepare_peercred(&peercred); - if (err) - goto out; - /* Allocate skb for sending to listening sock */ skb = sock_wmalloc(newsk, 1, 0, GFP_KERNEL); if (!skb) { -- cgit 1.3-korg
6884028cd7f2af_unix: Fix memleak of newsk in unix_stream_connect().
1 file changed · +3 −9
net/unix/af_unix.c+3 −9 modifieddiff --git a/net/unix/af_unix.c b/net/unix/af_unix.c index d0511225799ba3..f6d56e70c7a2c3 100644 --- a/net/unix/af_unix.c +++ b/net/unix/af_unix.c @@ -1650,10 +1650,9 @@ static int unix_stream_connect(struct socket *sock, struct sockaddr_unsized *uad timeo = sock_sndtimeo(sk, flags & O_NONBLOCK); - /* First of all allocate resources. - * If we will make it after state is locked, - * we will have to recheck all again in any case. - */ + err = prepare_peercred(&peercred); + if (err) + goto out; /* create new sock for complete connection */ newsk = unix_create1(net, NULL, 0, sock->type); @@ -1662,10 +1661,6 @@ static int unix_stream_connect(struct socket *sock, struct sockaddr_unsized *uad goto out; } - err = prepare_peercred(&peercred); - if (err) - goto out; - /* Allocate skb for sending to listening sock */ skb = sock_wmalloc(newsk, 1, 0, GFP_KERNEL); if (!skb) { -- cgit 1.3-korg
a5d95d7caba0af_unix: Fix memleak of newsk in unix_stream_connect().
1 file changed · +3 −9
net/unix/af_unix.c+3 −9 modifieddiff --git a/net/unix/af_unix.c b/net/unix/af_unix.c index d0511225799ba3..f6d56e70c7a2c3 100644 --- a/net/unix/af_unix.c +++ b/net/unix/af_unix.c @@ -1650,10 +1650,9 @@ static int unix_stream_connect(struct socket *sock, struct sockaddr_unsized *uad timeo = sock_sndtimeo(sk, flags & O_NONBLOCK); - /* First of all allocate resources. - * If we will make it after state is locked, - * we will have to recheck all again in any case. - */ + err = prepare_peercred(&peercred); + if (err) + goto out; /* create new sock for complete connection */ newsk = unix_create1(net, NULL, 0, sock->type); @@ -1662,10 +1661,6 @@ static int unix_stream_connect(struct socket *sock, struct sockaddr_unsized *uad goto out; } - err = prepare_peercred(&peercred); - if (err) - goto out; - /* Allocate skb for sending to listening sock */ skb = sock_wmalloc(newsk, 1, 0, GFP_KERNEL); if (!skb) { -- cgit 1.3-korg
365996a2b14daf_unix: Fix memleak of newsk in unix_stream_connect().
1 file changed · +3 −9
net/unix/af_unix.c+3 −9 modifieddiff --git a/net/unix/af_unix.c b/net/unix/af_unix.c index c634a7fc860906..9dad3af700af3e 100644 --- a/net/unix/af_unix.c +++ b/net/unix/af_unix.c @@ -1671,10 +1671,9 @@ static int unix_stream_connect(struct socket *sock, struct sockaddr *uaddr, timeo = sock_sndtimeo(sk, flags & O_NONBLOCK); - /* First of all allocate resources. - * If we will make it after state is locked, - * we will have to recheck all again in any case. - */ + err = prepare_peercred(&peercred); + if (err) + goto out; /* create new sock for complete connection */ newsk = unix_create1(net, NULL, 0, sock->type); @@ -1683,10 +1682,6 @@ static int unix_stream_connect(struct socket *sock, struct sockaddr *uaddr, goto out; } - err = prepare_peercred(&peercred); - if (err) - goto out; - /* Allocate skb for sending to listening sock */ skb = sock_wmalloc(newsk, 1, 0, GFP_KERNEL); if (!skb) { -- cgit 1.3-korg
Vulnerability mechanics
Root cause
"Missing cleanup of newly allocated socket when prepare_peercred() fails in unix_stream_connect()."
Attack vector
An attacker can trigger a memory leak by making a `connect()` call on a UNIX stream socket that causes `prepare_peercred()` to fail after `unix_create1()` has already allocated a new socket (`newsk`). Because the failure path jumps to `out` without calling `unix_release_sock()` on `newsk`, the socket object is never freed. Repeated connections can exhaust kernel memory.
Affected code
The vulnerability is in the `unix_stream_connect()` function in `net/unix/af_unix.c`. The `prepare_peercred()` call was placed after `unix_create1()` allocated `newsk`, so a failure in `prepare_peercred()` would jump to `out` without releasing the newly allocated socket [patch_id=2661659].
What the fix does
The fix moves the `prepare_peercred()` call to before `unix_create1()` so that if it fails, no socket has been allocated yet and the error path simply jumps to `out` without leaking memory [patch_id=2661659]. The original comment about allocating resources first was removed because the peercred preparation no longer needs a socket to exist. This ensures that `newsk` is only created after all preconditions that could fail have been checked.
Preconditions
- inputThe attacker must be able to make connect() calls on a UNIX stream socket (AF_UNIX, SOCK_STREAM).
- inputThe prepare_peercred() call must fail (e.g., due to resource limits or other kernel-side failure).
Generated on May 27, 2026. Inputs: CWE entries + fix-commit diffs from this CVE's patches. Citations validated against bundle.
References
3News mentions
0No linked articles in our index yet.