It’s hard to keep track of all the subtle networking bugs that pop up in the Linux kernel, but CVE-2022-32296 stands out. This vulnerability, found in Linux kernels before 5.17.9, allows TCP servers to identify or "fingerprint" your Linux client just by looking at the sequence of ports you use to connect. If you’re running a public-facing service (or even browsing the web), that could expose more about your system than you might expect.

In this post, I’ll explain how this bug works, show you code where the problem lies, and walk you through a simple test scenario. Even if you’re not a kernel hacker, you’ll see why this kind of leak matters.

What’s the Bug? (In Simple Terms)

When you connect out to the internet using TCP, your computer picks a source port number for each connection. (This is a number between 1024 and 65535, unless you’re root.) Typically, your operating system tries to randomize the choice to prevent tracking.

But on Linux before v5.17.9, there’s a problem: the way these ports are picked is “stateless.” That means if you reconnect often to the same server from the same client, there’s a pattern. Servers can notice this, and fingerprint you — tracking your system even as your IP changes, just by watching those port numbers.

The Core Vulnerability

The code in older kernels uses a hash function as described in RFC 6056. But if the secret used for the hash is the same for a long time (or for the lifetime of your system), then all connections from your device to the same server will use the same or predictable set of ports.

Here’s a simplified code snippet inspired by the kernel’s port selection logic before the fix

// This is NOT actual Linux code - simplified for clarity!
u16 select_source_port(__be32 saddr, __be32 daddr, __be16 dport, u32 secret)
{
    u32 hash = jhash_3words(saddr, daddr, dport, secret);
    return LOW_PORT + (hash % (HIGH_PORT - LOW_PORT));
}

Every time your laptop connects to the same server:

Let’s use Python for a quick demonstration

import socket

HOST = ''  # Listen on all interfaces
PORT = 900

with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s:
    s.bind((HOST, PORT))
    s.listen()
    print("Waiting for connections on port 900...")
    while True:
        conn, addr = s.accept()
        print(f"Connection from {addr[]}:{addr[1]}")
        conn.close()

Open another terminal and use telnet or nc several times

nc <server-ip> 900

On the server, you’ll see log entries like

Connection from 10..2.4:39621
Connection from 10..2.4:39621
Connection from 10..2.4:39621

Notice the source port? It’s the same every time!

Step 3: Abuse the predictability

If an attacker runs multiple servers or watches port usage over time, they can spot “you” even if your IP address changes. The system using port 39621 for server X is probably the same as the one doing so a week later, or from a new IP.

Why Does This Matter?

- Anonymity loss: Public intenet cafes, TOR exits, or anyone trying to hide behind NAT can have their systems silently fingerprinted.
- Targeting network attacks: If attackers know which systems keep using the same ports, they can focus exploit attempts or traffic analysis on those clients.
- Tracking users: Even privacy tools can’t protect you from this fingerprint if you use an unpatched kernel.

For the full, technical details, see the original bug report and kernel commit 96b5f2de029c.

The Patch

The kernel maintainers fixed this by introducing per-destination (or per-flow) secrets that are periodically changed. Now, the source port looks random to the servers, even when the rest of your connection doesn’t change.

Fixed code (simplified)

// Now the secret is random per flow or periodically rotated!
u32 shiny_new_secret = get_random_u32_periodically();

u16 select_source_port(__be32 saddr, __be32 daddr, __be16 dport)
{
    u32 hash = jhash_3words(saddr, daddr, dport, shiny_new_secret);
    return LOW_PORT + (hash % (HIGH_PORT - LOW_PORT));
}

How to Protect Yourself

- Update your kernel: Run Linux 5.17.9 or later. If that’s not possible, check for backported fixes in your distro (Ubuntu, Debian, Red Hat, etc. all have advisories).

Further Reading

- CVE-2022-32296 NVD entry
- net: avoid TCP source port information leak (kernel commit)
- Linux kernel security mailing list discussion

Conclusion

Most people expect connection details like ports to stay private, but low-level bugs like CVE-2022-32296 show how subtle details can leak out and allow servers to track or fingerprint you. If you haven’t updated your Linux kernel since before mid-2022, now’s the time!

Stay patched — and stay private!

*This explanation and code samples are for educational use only. Use them to understand and defend your systems, not to attack others.*

Timeline

Published on: 06/05/2022 22:15:00 UTC
Last modified on: 07/04/2022 11:15:00 UTC