Есть ли лучший способ, чем парсинг / proc / self / maps, чтобы определить защиту памяти? - PullRequest
18 голосов
/ 06 ноября 2008

В Linux (или Solaris) есть лучший способ, чем многократный ручной анализ /proc/self/maps, чтобы выяснить, можете ли вы читать, записывать или выполнять то, что хранится по одному или нескольким адресам в памяти?

Например, в Windows у вас есть VirtualQuery.

В Linux я могу mprotect изменить эти значения, но не могу прочитать их обратно.

Кроме того, есть ли способ узнать, когда эти разрешения меняются (например, когда кто-то использует mmap для файла за моей спиной), кроме как делать что-то ужасно инвазивное и использовать ptrace во всех потоках процесса и перехватывать любые попытаться создать syscall, который может повлиять на карту памяти?

Обновление:

К сожалению, я использую это внутри JIT, у которого очень мало информации о коде, который он выполняет, чтобы получить приближение того, что является константой. Да, я понимаю, что могу иметь постоянную карту изменяемых данных, например страницу vsyscall, используемую Linux. Я могу безопасно прибегнуть к предположению, что все, что не включено в первоначальный анализ, является изменчивым и опасным, но я не совсем доволен этим вариантом.

Прямо сейчас я читаю /proc/self/maps и строю структуру, через которую я могу выполнить бинарный поиск для защиты данного адреса. Каждый раз, когда мне нужно что-то узнать о странице, которая не входит в мою структуру, я перечитываю / proc / self / maps, предполагая, что она была добавлена ​​за это время, или я в любом случае собираюсь segfault.

Просто кажется, что анализ текста для получения этой информации и незнание того, когда она меняется, ужасно груб. (/dev/inotify почти ничего не работает в /proc)

Ответы [ 2 ]

6 голосов
/ 06 ноября 2008

Я не знаю эквивалента VirtualQuery в Linux. Но некоторые другие способы сделать это, которые могут или не могут работать:

  • Вы устанавливаете обработчик сигнала, перехватывающий SIGBUS / SIGSEGV, и продолжаете чтение или запись. Если память защищена, будет вызван ваш код захвата сигнала. Если нет, то ваш код захвата сигнала не вызывается. В любом случае вы выиграете.

  • вы можете отслеживать каждый раз, когда звоните mprotect, и создавать соответствующую структуру данных, которая поможет вам узнать, защищен ли регион от чтения или записи. Это хорошо, если у вас есть доступ ко всему коду, который использует mprotect.

  • вы можете отслеживать все вызовы mprotect в вашем процессе, связывая ваш код с библиотекой, переопределяющей функцию mprotect. Затем вы можете построить необходимую структуру данных, чтобы узнать, защищен ли регион от чтения или записи, а затем вызвать систему mprotect, чтобы действительно установить защиту.

  • вы можете попытаться использовать /dev/inotify и отслеживать файл /proc/self/maps на предмет любых изменений. Я думаю, что это не работает, но стоит попробовать.

0 голосов
/ 17 августа 2015

Там сортировка / was / proc / [pid | self] / pagemap, документация по ядру, предостережения здесь: https://lkml.org/lkml/2015/7/14/477 Так что это не совсем безобидно ...

...