Using function interposition for open()
with Python doesn't seem to work after the first few calls. I suspect Python is doing some kind of initialization, or something is temporarily bypassing my function.
Here the open
call is clearly hooked:
$ cat a
hi
$ LD_PRELOAD=./libinterpose_python.so cat a
sandbox_init()
open()
hi
Here it happens once during Python initialization:
$ 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()
Here it doesn't happen at all, and there's no error to indicate the file handle had write privileges removed:
$ LD_PRELOAD=./libinterpose_python.so python3 -c 'b = open("a", "w"); b.write("hi\n"开发者_JS百科); b.flush()'
sandbox_init()
sandbox_fini()
The code is here. Build with make -f Makefile.interpose_python
.
A full solution is given here.
There are open() and open64() functions, you might need to redefine both.
You should be able to find out what your python process is actually doing by running it under strace
(probably without your pre-load).
My python3.1 (on AMD64) does appear to use open
:
axa@ares:~$ strace python3.1 -c 'open("a","r+")'
...
open("a", O_RDWR) = -1 ENOENT (No such file or directory)
It turns out there is an open64()
function:
$ 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
The open64() function is a part of the large file extensions, and is equivalent to calling open() with the O_LARGEFILE flag.
Running the example code with the open64
section uncommented gives:
$ 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()
Which clearly shows all of Python's open
calls, and several propagated errors due to the write flag being stripped from the calls.
精彩评论