Netdev List
 help / color / mirror / Atom feed
From: Stephen Hemminger <stephen@networkplumber.org>
To: John McAndrew <jmcandrew.nc@gmail.com>
Cc: netdev@vger.kernel.org
Subject: Re: Vulnerability Report: iproute2-6.19.0 Stack Buffer Overflow in print_queuelen (CWE-120)
Date: Tue, 28 Jul 2026 14:36:52 -0700	[thread overview]
Message-ID: <20260728143652.5a1cb187@phoenix.local> (raw)
In-Reply-To: <CADCQVCg_ppRbJfmE5QDS0kDwwfMLGKDn7q8V+rbs0_=HCmbbsg@mail.gmail.com>

On Tue, 28 Jul 2026 16:03:16 -0400
John McAndrew <jmcandrew.nc@gmail.com> wrote:

> Dear iproute2 Maintainers,
> 
> I have discovered a critical stack buffer overflow vulnerability in
> iproute2 version 6.19.0
> in the print_queuelen() function (ip/ipaddress.c:173).
> 
> *VULNERABILITY SUMMARY*
> 
> Type:              Stack Buffer Overflow (CWE-120)
> Affected Component: iproute2
> Affected Version:  6.19.0
> Vulnerability ID:  CVE-PENDING
> Severity:          HIGH/CRITICAL
> CVSS Score:        7.5 - 8.8
> Location:          ip/ipaddress.c, line 173
> Function:          print_queuelen()
> 
> 
> *DETAILED DESCRIPTION*
> 
> The print_queuelen() function contains a critical vulnerability where
> untrusted
> kernel-supplied netlink data is copied directly into a fixed-size stack
> buffer
> without any bounds checking.
> 
> Vulnerable Code Location: ip/ipaddress.c:173
> 
>     static void print_queuelen(FILE *f, struct rtattr *tb[IFLA_MAX + 1])
>     {
>         int qlen;
>         if (tb[IFLA_TXQLEN])
>             qlen = rta_getattr_u32(tb[IFLA_TXQLEN]);
>         else {
>             struct ifreq ifr = {};
>             int s = socket(AF_INET, SOCK_STREAM, 0);
>             if (s < 0)
>                 return;
>             strcpy(ifr.ifr_name, rta_getattr_str(tb[IFLA_IFNAME]));  // ←
> VULNERABLE LINE
>             if (ioctl(s, SIOCGIFTXQLEN, &ifr) < 0) {
>                 fprintf(stderr, "ioctl(SIOCGIFTXQLEN) failed: %s\n",
> strerror(errno));
>                 close(s);
>                 return;
>             }
>         }
>     }
> 
> 
> *VULNERABILITY ANALYSIS*
> 
> The Vulnerability:
>   • Buffer: ifr.ifr_name is char[IFNAMSIZ] = char[16] (fixed size,
> stack-allocated)
>   • Copy Function: strcpy() - DOES NOT CHECK LENGTH
>   • Source: rta_getattr_str(tb[IFLA_IFNAME]) - untrusted kernel netlink data
>   • Result: If IFLA_IFNAME > 15 bytes → STACK BUFFER OVERFLOW
> 
> Attack Vector:
>   1. Attacker crafts malformed RTM_NEWLINK netlink message
>   2. Sets IFLA_IFNAME attribute to string > 15 bytes (e.g., 100 bytes)
>   3. Sends message to kernel (netlink socket)
>   4. User runs: ip addr show (or similar command)
>   5. iproute2 processes message, calls print_queuelen()
>   6. strcpy() overflows 16-byte buffer
>   7. Stack memory corrupted: return addresses, saved registers, etc.
>   8. Attacker gains code execution
> 
> Impact:
>   • Local privilege escalation
>   • Arbitrary code execution
>   • Denial of service via crash
>   • Information disclosure from stack memory
> 
> 
> *PROOF OF CONCEPT*
> 
> 1. CODE ANALYSIS PROOF:
>    ✓ Vulnerable function exists at ip/ipaddress.c:173
>    ✓ No input validation before strcpy()
>    ✓ Buffer is fixed 16 bytes (IFNAMSIZ)
>    ✓ Source is untrusted netlink data
> 
> 2. COMPILATION PROOF:
>    ✓ Compiled iproute2-6.19.0 with AddressSanitizer
>    ✓ Binary: ip_asan_compiled (attached)
>    ✓ Compilation flags: -fsanitize=address -fsanitize=undefined -g -O1
>    ✓ Test output shows ASAN is active and monitoring memory
> 
> 3. TRIGGER PROOF:
>    ✓ Created malicious RTM_NEWLINK netlink message (140 bytes)
>    ✓ IFLA_IFNAME attribute set to 100 bytes (triggers overflow)
>    ✓ Successfully sent message to kernel via netlink socket
>    ✓ Binary executes with memory monitoring active
> 
>    Test Output:
>    $ sudo python3 simple_trigger.py
>    [✓] Created message with 100-byte IFLA_IFNAME
>    [✓] Sent 140 bytes to kernel
> 
> 4. ASAN MONITORING PROOF:
>    $ ./ip_asan_compiled -V
>    ==2583902==ASan runtime does not come first in initial library list;
>    you should either link runtime to your application or manually preload
> it with LD_PRELOAD.
> 
>    This message confirms AddressSanitizer is linked and active.
>    Any buffer overflow will be detected and reported.
> 
> 
> *RECOMMENDED FIX*
> 
> Replace strcpy() with bounds-checking variant:
> 
> OPTION 1 - Use strncpy (safest):
>     strncpy(ifr.ifr_name, rta_getattr_str(tb[IFLA_IFNAME]), IFNAMSIZ - 1);
>     ifr.ifr_name[IFNAMSIZ - 1] = '\0';
> 
> OPTION 2 - Use strlcpy (simpler):
>     strlcpy(ifr.ifr_name, rta_getattr_str(tb[IFLA_IFNAME]), IFNAMSIZ);
> 
> OPTION 3 - Use existing validation function:
>     if (get_ifname(ifr.ifr_name, rta_getattr_str(tb[IFLA_IFNAME])) < 0)
>         return;
> 
> Patch File:
>     --- a/ip/ipaddress.c
>     +++ b/ip/ipaddress.c
>     @@ -170,7 +170,8 @@ static void print_queuelen(FILE *f, struct rtattr
> *tb[IFLA_MAX + 1])
>              struct ifreq ifr = {};
>              int s = socket(AF_INET, SOCK_STREAM, 0);
>              if (s < 0)
>                  return;
>     -        strcpy(ifr.ifr_name, rta_getattr_str(tb[IFLA_IFNAME]));
>     +        strncpy(ifr.ifr_name, rta_getattr_str(tb[IFLA_IFNAME]),
> IFNAMSIZ - 1);
>     +        ifr.ifr_name[IFNAMSIZ - 1] = '\0';
>              if (ioctl(s, SIOCGIFTXQLEN, &ifr) < 0) {
> 
> TIMELINE & RESPONSIBLE DISCLOSURE
> 
> I am following responsible disclosure practices:
> 
> 1. Reporting privately to maintainers FIRST (not public)
> 2.  Not posting to bug trackers or social media
> 3.  Requesting embargo until patch is available
> 4.  Ready to coordinate on patch timing
> 5.  Willing to hold disclosure for 30+ days
> 
> I request:
> 1. Acknowledgment of receipt within 48 hours
> 2. Timeline for patch development
> 3. Coordination on CVE assignment (via MITRE if needed)
> 4. Notification when patch is ready
> 5. Agreed embargo period before public disclosure
> 
> 
> *ATTACHMENTS*
> 
> Attached files:
> 1. ip_asan_custom (12 MB)
>    - iproute2-6.19.0 compiled with AddressSanitizer
>    - Ready for testing and verification
> 
> 2. iproute2_vulnerability_report.md
>    - Complete technical analysis
>    - Root cause breakdown
>    - Impact assessment
> 
> 3. simple_trigger.py
>    - Proof of concept trigger (100-byte IFLA_IFNAME)
>    - Demonstrates ability to send malicious netlink message
> 
> 
> *CONTACT INFORMATION*
> 
> Researcher:     John McAndrew
> Email:          jmcandrew.nc@gmail.com
> Timezone:       EST
> 
> 
> *RESOURCES*
> 
> CWE-120: Buffer Copy without Checking Size of Input
> https://cwe.mitre.org/data/definitions/120.html
> 
> AddressSanitizer Documentation:
> https://github.com/google/sanitizers/wiki/AddressSanitizer
> 
> iproute2 Project:
> https://github.com/iproute2/iproute2
> 
> Linux Kernel Netlink:
> https://man7.org/linux/man-pages/man7/netlink.7.html
> 
> 
> I am available to:
> - Provide additional technical details
> - Coordinate public disclosure timing
> 
> Thank you for your attention to this security issue. I look forward to
> working with you to develop and release a fix.
> 
> Best regards,
> 
> John McAndrew
> jmcandrew.nc@gmail.com

Human response: This is crap, go away. Learn to use AI better.

AI response:
Thank you for the report, but after reviewing it we don't believe this constitutes an exploitable vulnerability.

The PoC doesn't validate the kernel's response. RTM_NEWLINK with a 100-byte IFLA_IFNAME is rejected by the kernel at dev_valid_name() — interface names are bounded by IFNAMSIZ at creation time and enforced by the netlink policy. The oversized name never reaches userspace.

The code path in question is also not reached on any modern kernel: IFLA_TXQLEN is included in RTM_NEWLINK responses, so the SIOCGIFTXQLEN fallback (and the strcpy) is dead code in practice.

Finally, iproute2 is a userspace utility that reads kernel-validated data. Even if this path were reachable, the interface name returned by the kernel is already bounded to IFNAMSIZ, so there is no overflow.

We won't be pursuing a CVE for this. When submitting future reports, please include a working PoC that demonstrates the actual overflow — an ASAN stack trace, for example — rather than a proof of successful transmission to the kernel.


      parent reply	other threads:[~2026-07-28 21:36 UTC|newest]

Thread overview: 3+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-07-28 20:03 Vulnerability Report: iproute2-6.19.0 Stack Buffer Overflow in print_queuelen (CWE-120) John McAndrew
2026-07-28 20:20 ` Stephen Hemminger
2026-07-28 21:36 ` Stephen Hemminger [this message]

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20260728143652.5a1cb187@phoenix.local \
    --to=stephen@networkplumber.org \
    --cc=jmcandrew.nc@gmail.com \
    --cc=netdev@vger.kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox