Как декодировать cmd = 3222823425 в ioctl в Linux 2.6.29

Ядро делает подсчет ссылок на ссылках на inode. См. мой ответ на то, Что происходит, когда я закрываю () дескриптор файла?.

Удаление открытых файлов вероятно не более эффективное механизм DOS, чем просто вводные файлы. ulimit на открытых файлах обеспечивает некоторую защиту против этой попытки DOS. Это относится ко всем открытым файлам, удаленным или нет.

4
08.01.2013, 09:36
1 ответ

ioctl переходит к драйверу, таким образом, самая важная вещь выяснить, что делает ioctl, - какой драйвер обрабатывает его.

О чем Вы читали type, number и data_type конвенция, которую писатели драйвера, как предполагается, используют при выборе ioctl чисел. Хотя различные драйверы могут использовать то же значение для значения совершенно других вещей, лучше избегать этого, так, чтобы, если ioctl случайно отправляется на неправильное устройство, был хороший шанс, что это возвратит ошибку, а не вызовет некоторое катастрофическое событие.

Хорошее описание конвенции находится в книжных Драйверах устройств Linux (LDD), главе 6. data_type на самом деле (с некоторого времени рано в 2.6.x серия IIRC) сделан из двух частей, direction и size.

  • type (8 битов) являются константой, которая должна быть последовательной через ioctls, реализованный в драйвере, и должна отличаться от ioctls несвязанных устройств, если это возможно. Существует устаревший репозиторий type значения в Documentation/ioctl/ioctl-number.txt.
  • number (8 битов) должны отличаться для всего ioctls в драйвере.
  • direction (2 бита) указывают на направление передачи данных (0=none, 1=write, 2=read, 3=both).
  • size размер буфера данных, если ioctl аргументом является указатель на буфер данных.

ioctl число должно быть

 direction << 30 | size << 16 | type << 8 | number

(Если Вы пишете драйвер, используйте _IOC_* макросы, определенные в asm-generic/ioctl.h.)

Для Вашего ioctl номера 3222823425 = 0xc0186201, мы получаем type=0x62 (известный как “мост хоста bit3 vme” в 1999), number=1, direction=2 и size=0x18=24, таким образом, ioctl берет 24-байтовый входной параметр.

Это значение ioctl должно быть определено как _IOR(0x62, 0x01, struct somestruct) или что-то эквивалентное как _IOR('b', 1, struct somestruct), где struct somestruct 24 байтовых структуры. Если Вы не знаете, какой драйвер обрабатывает ioctl, можно искать вызов как это в источнике ядра для сбора кандидатов. Однако обратите внимание, что простой текстовый поиск часто не будет находить драйвер, потому что им свойственно использовать макрос, например. #define FOOIO_TYPE 0x62 сопровождаемый #define FOOIO_SOMETHING _IOR(FOOIO_TYPE, 1, struct foobar).

Вызов ioctl имеет два параметра в дополнение к дескриптору файла, на который действует ioctl: ioctl число cmd, и аргумент arg. Аргументом может быть непосредственное значение или указатель на буфер. Здесь, если устройство записи драйвера следует конвенции, arg должен быть указатель на 24-байтовый буфер в пространстве памяти приложения.

8
27.01.2020, 20:50
  • 1
    Потрясающее объяснение.. Один быстрый вопрос: direction=2 Вы имеете в виду и чтение и значение направления или запись? Я принимаю первый как c (Шестнадцатеричное число) = 1100 (двоичный файл), где 11 30-й и 31-й бит cmd и 11 (мусорное ведро) = 3 (декабря). Таким образом, направление = 3 было бы корректно. Не так? –  Junaid 09.01.2013, 08:11

Теги

Похожие вопросы