LINUX.ORG.RU

Сообщения GMOrk

 

Чтение заголовка ФС USB в загружаемом модуле ядра

Форум — Development

Добрый день Занимаюсь проектом, в котором мне необходимо прочитать заголовок файловой системы подключенной USB (по сути, первые 512 байт). После этого мне необходимо проверить полученную последовательность на наличие ключа - специального слова. Делаю я это в загружаемом модуле ядра Linux. Есть следующий код

#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/usb/storage.h>
#include <linux/usb.h>

char *buffer;

static struct usb_endpoint_descriptor *find_bulk_in_endpoint(struct usb_device *udev) {
    struct usb_host_interface *iface_desc;
    struct usb_interface *iface;
    struct usb_endpoint_descriptor *endpoint;
    int i, j;

    for (i = 0; i < udev->actconfig->desc.bNumInterfaces; i++) {
        iface = udev->actconfig->interface[i];
        iface_desc = iface->cur_altsetting;
        if (iface_desc->desc.bInterfaceClass == 0x08) {
            pr_info("Found storage interface:\n");
            pr_info("  Interface Number: %d\n", iface_desc->desc.bInterfaceNumber);
            pr_info("  Number of Endpoints: %d\n", iface_desc->desc.bNumEndpoints);
            for (j = 0; j < iface_desc->desc.bNumEndpoints; j++) {
                endpoint = &iface_desc->endpoint[j].desc;
                if ((endpoint->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) == USB_ENDPOINT_XFER_BULK &&
                    (endpoint->bEndpointAddress & USB_DIR_IN))
                    return endpoint;
            }
        }
    }
    pr_err("No bulk IN endpoint found\n");
    return NULL;
}

int read_first_sector(struct usb_device *udev) {
    struct usb_endpoint_descriptor *bulk_in_endpoint = find_bulk_in_endpoint(udev);

    if (!bulk_in_endpoint)
        return -ENODEV;

    u8 buf[512];
    int ret, actual_size;
    unsigned char scsi_cmd[10] = { 
        0x28,
        0x00,
        0x00,
        0x00,
        0x00,
        0x01,
        0x00,
        0x00,
        0x00,
        0x00
    };

    ret = usb_control_msg(udev, usb_sndctrlpipe(udev, 0), 0x28, USB_DIR_IN | USB_TYPE_CLASS | USB_RECIP_INTERFACE, 0, 0,(void *)scsi_cmd, sizeof(scsi_cmd), 1000);
    if (ret < 0) {
        printk(KERN_ERR "USB SCSI READ command failed: %d\n", ret);
        return ret;
    }
    ret = usb_bulk_msg(udev, usb_rcvbulkpipe(udev, bulk_in_endpoint->bEndpointAddress), buf, 512, &actual_size, 1000);
    if (ret < 0) {
        printk(KERN_ERR "USB bulk read failed: %d\n", ret);
        return ret;
    }
    printk(KERN_INFO "First sector data:\n");
    for (int i = 0; i < 512; i++) {
        printk(KERN_CONT "%02x ", buf[i]);
        if ((i + 1) % 16 == 0)
            printk(KERN_CONT "\n");
    }
    return 0;
}

static int usb_notify(struct notifier_block *self, unsigned long action, void *dev) {
    struct usb_device *usb_dev = dev;

    switch (action) {
        case USB_DEVICE_ADD:
            printk(KERN_INFO "USB device connected: Vendor ID=%04x, Product ID=%04x\n",
                      usb_dev->descriptor.idVendor, usb_dev->descriptor.idProduct);
            printk(KERN_INFO "Path: %s\n", dev_name(&usb_dev->dev));
            read_first_sector(usb_dev);
            break;
        case USB_DEVICE_REMOVE:
            printk(KERN_INFO "USB device disconnected: Vendor ID=%04x, Product ID=%04x\n",
                      usb_dev->descriptor.idVendor, usb_dev->descriptor.idProduct);
            break;
        default:
            break;
    }
    return NOTIFY_OK;
}

static struct notifier_block usb_notifier = {
    .notifier_call = usb_notify
};

static int __init usb_device_list_init(void) {
    printk(KERN_INFO "Listing all connected USB devices:\n");
    usb_register_notify(&usb_notifier); 
    return 0;
}

static void __exit usb_device_list_exit(void) {
    usb_unregister_notify(&usb_notifier);
    printk(KERN_INFO "USB device listing module exiting.\n");
    kfree(buffer); 
}

late_initcall(usb_device_list_init);
module_exit(usb_device_list_exit);
MODULE_LICENSE("GPL");
MODULE_DESCRIPTION("USB Device Module");
MODULE_AUTHOR("MyName");

Собственно я обрабатываю подключение нового USB устройства, оно происходит нормально. Затем я пытаюсь прочитать первые 512 байт с флешки с помощью SCSI, но возникает ошибка. А именно 55 строка (я вызываю usb_control_msg) возвращает код ошибки -11. Может ли это возникать из-за неправильного значения параметра bRequest, не уверен, что должен передавать туда 0х28 Вывод dmesg длинный, поэтому залил на пастбин: https://pastebin.com/XG1rESHy

Записывал слово на флешку с помощью:

echo -n "USBSECRET" | sudo dd of=/dev/sdb bs=1 count=10 conv=notrunc

Заранее благодарю!

 , , ,

GMOrk
()

RSS подписка на новые темы