Как запускать dd эффективно вводить в мою оболочку?

5

Попробуйте запустить:

dd if=/dev/urandom count=1000

Затем, как только это будет сделано, нажмите Enter. Я использую Debian Sid и получаю:

user@host$ dd if=/dev/urandom count=1000
<lots of random characters, then I hit enter again>
bash: 62: command not found
bash: 9: command not found
bash: c62: command not found
bash: 9: command not found
bash: c62: command not found
bash: 9: command not found
bash: c: command not found
user@host$

Это кажется неприлично неуместным! Как запись dd в его стандартный вывод может привести к тому, что этот текст попадет в буфер ввода в Bash? Я глубоко озадачен тем, как это может произойти, и как это можно считать приемлемым поведением с точки зрения безопасности.


источник
Упс ... если бы у нас был конкурс "вопрос месяца", он был бы победителем.
Петр
(Вы делаете это из шпатлевки?)
peterh
Экранирующие последовательности оболочки интерпретируются. Несколько месяцев назад была хорошая статья на эту тему, но я не могу найти ее прямо сейчас (конечно, кто-то другой найдет).
Домен

Ответы:

3

Не рекомендуется отправлять случайные данные на ваш терминал.

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

Простые примеры из определения терминала ECMA-48 (также известного как ANSI или vt100) включают ESC [1 м для входа в полужирный режим, ESC [2 J для очистки экрана и ESC c для сброса терминала.

Некоторые escape-последовательности не просто изменяют состояние терминала - они запрашивают информацию. Они различаются для разных терминалов и эмуляторов. Примером терминала с множеством поддерживаемых escape-последовательностей и хорошей документацией на них является xterm. Его ctlseqs.msдокумент является хорошим общим справочным материалом, потому что многие более поздние эмуляторы терминала предназначены для совместимости с ним. Вот его веб-версия: http://invisible-island.net/xterm/ctlseqs/ctlseqs.html

Обратите ваше внимание на эту команду:

CSI Ps c  Send Device Attributes (Primary DA)

Краткое руководство для понимания записи: CSIозначает либо ESC [, либо 0x9bбайт ( ESC с установленным старшим битом). Psявляется числовым параметром, который является необязательным в этой команде (и в большинстве других). Чтобы запустить это действие путем вывода случайных байтов, вам нужен только один 0x9bбайт, за которым следует 0x63( 'c') где-то в потоке, что весьма вероятно в 1000 блоках по 512 байт.

Эта команда задает терминалу вопрос: "Кто ты?" и терминал отвечает, отправляя escape-последовательность обратно. Есть несколько возможных ответов, которые вы можете прочитать в документе ctlseqs, но мне интересно, что оба 6cи 62появляются в списке.

Эти escape-последовательности запроса / ответа предназначены для использования программой, которая записывает запрос, а затем сразу же читает ответ. Если вместо этого запрос отправляется программой, которая просто извергала мусор и ничего не читала из терминала, ответ может остаться во входном буфере.

Помните, что терминал подключен к компьютеру с помощью последовательной линии (реальной или эмулированной). Он несет один поток байтов в каждом направлении. Не существует заметной разницы между ESC [6c, который прибыл в качестве ответа на запрос атрибутов устройства, и ESC [6c, который прибыл, потому что вы нажали клавиши Esc [ 6 c, за исключением времени.

Итак, что происходит в общем случае, если вы запускаете команду, которая не использует ввод с терминала, и набираете некоторые вещи во время работы? Введенный вами текст остается в буфере tty до тех пор, пока эта программа не будет завершена, а затем ваша оболочка прочитает его.

(Ввод команды для чтения в приглашении, которое еще не было напечатано, называется typeahead и экономит время. Вам не нужно вежливо сидеть на руках и ждать, пока компьютер завершит свою работу, если вы знаете, что хотите сделать дальше, вы можете просто начать печатать!)


источник