Почему LD_PRELOAD не работает с Python? - PullRequest
9 голосов
/ 21 июня 2011

Использование функции вставки для open() с Python, похоже, не работает после первых нескольких вызовов.Я подозреваю, что Python выполняет какую-то инициализацию, или что-то временно обходит мою функцию.

Здесь вызов open явно перехвачен:

$ cat a
hi
$ LD_PRELOAD=./libinterpose_python.so cat a
sandbox_init()
open()
hi

Здесь это происходит один раз во время инициализации Python:

$ LD_PRELOAD=./libinterpose_python.so python
sandbox_init()
Python 2.7.2 (default, Jun 12 2011, 20:20:34) 
[GCC 4.6.1] on linux2
Type "help", "copyright", "credits" or "license" for more information.
open()
>>> 
sandbox_fini()

Здесь это вообще не происходит, и нет ошибки, указывающей на то, что дескриптору файла были удалены привилегии записи:

$ LD_PRELOAD=./libinterpose_python.so python3 -c 'b = open("a", "w"); b.write("hi\n"); b.flush()'
sandbox_init()
sandbox_fini()

Код здесь .Сборка с make -f Makefile.interpose_python.

Полное решение дано здесь .

Ответы [ 3 ]

8 голосов
/ 21 июня 2011

Существуют функции open () и open64 (), вам может потребоваться переопределить обе.

1 голос
/ 18 декабря 2011

получается получается есть функция open64():

$ objdump -T /lib32/libc.so.6  | grep '\bopen'
00064f10 g    DF .text  000000fc  GLIBC_2.4   open_wmemstream
000cc010 g    DF .text  0000007b  GLIBC_2.0   openlog
000bf6d0  w   DF .text  000000b6  GLIBC_2.1   open64
00094460  w   DF .text  00000055  GLIBC_2.0   opendir
0005f9b0 g    DF .text  000000d9  GLIBC_2.0   open_memstream
000bf650  w   DF .text  0000007a  GLIBC_2.0   open
000bf980  w   DF .text  00000081  GLIBC_2.4   openat
000bfb90  w   DF .text  00000081  GLIBC_2.4   openat64

Функция open64 () является частью больших расширений файлов и эквивалентна вызову open () с флагом O_LARGEFILE.

Запуск примера кода с разделом open64 без комментариев дает:

$ LD_PRELOAD=./libinterpose_python.so python3 -c 'b = open("a", "w"); b.write("hi\n"); b.flush()'
sandbox_init()
open64()
open64()
open64()
Traceback (most recent call last):
  File "<string>", line 1, in <module>
open64()
open64()
open64()
open64()
open64()
open64()
open64()
IOError: [Errno 9] Bad file descriptor
sandbox_fini()

Который четко показывает все вызовы Python open и несколько распространенных ошибок из-за удаления флага записи из вызовов.

1 голос
/ 21 июня 2011

Вы сможете узнать, что на самом деле делает ваш процесс python, запустив его под strace (возможно, без предварительной загрузки).

Мой python3.1 (на AMD64) действительноиспользуйте open:

axa@ares:~$ strace python3.1 -c 'open("a","r+")'
...
open("a", O_RDWR)                       = -1 ENOENT (No such file or directory)
...