Skip to content

cangen: Stack-based overflow in cangen via unchecked interface-name copy #622

@neosys007

Description

@neosys007

Hello can-utils maintainers,

I would like to report what appears to be a real stack-based overflow in cangen. I rechecked current upstream head on 2026-03-07 before writing this report, and the relevant code path still appears to be present in cangen.c.

The issue is in the handling of the interface name argument before the SIOCGIFINDEX ioctl call.

The affected code path is:

addr.can_family = AF_CAN;

strcpy(ifr.ifr_name, argv[optind]);
if (ioctl(s, SIOCGIFINDEX, &ifr) < 0) {
	perror("SIOCGIFINDEX");
	return 1;
}

What makes this look like a real bug is that the critical conditions are directly visible in the code:

argv[optind] is user-controlled command-line input.

ifr.ifr_name is the fixed-width interface-name field from struct ifreq.

strcpy is used without any prior length check.

The copy happens before ioctl(..., SIOCGIFINDEX, ...) has any chance to reject the invalid interface name.

So this is not just a generic "dangerous API" concern. The actual bug claim is that a source string longer than the destination capacity can already overwrite adjacent stack data before the kernel-side interface lookup is even attempted.

A simple way to reach the bug is to invoke cangen with an oversized interface name, for example:

cangen AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA

If the provided interface name is longer than IFNAMSIZ - 1 bytes, the strcpy into ifr.ifr_name will write past the end of the fixed-width field.

My claim here is intentionally narrow:

this is a local CLI-triggered bug,

the overflow is caused by copying an unchecked interface name into struct ifreq.ifr_name,

and the overwrite occurs before any validation step that might otherwise reject the interface name.

A straightforward fix would be to reject interface names whose length is >= IFNAMSIZ before copying, for example by checking the argument length first and then using a bounded copy that guarantees NUL termination.

For example, something along these lines would avoid the overflow:

if (strlen(argv[optind]) >= IFNAMSIZ) {
	fprintf(stderr, "Interface name too long\n");
	return 1;
}

strncpy(ifr.ifr_name, argv[optind], IFNAMSIZ - 1);
ifr.ifr_name[IFNAMSIZ - 1] = '\0';

Even if this is treated as a normal bug rather than a security issue, the unchecked stack write appears real and current-head.

Best regards,
Pengpeng Hou
pengpeng@iscas.ac.cn

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions