STINNER Victor added the comment:

Oh, I just reproduced the issue on my gdb.py program, which is part of the 
python-ptrace program. When searching for a pattern in the memory of another 
process, /proc/pid/maps is used to get the list of all memory mappings of this 
process. On Linux x64, the last mapping is "ffffffffff600000-ffffffffff601000 
r-xp 00000000 00:00 0 [vsyscall]", machine code used for system calls. gdb.py 
opens /proc/pid/mem in binary mode and tries to seek at 0xffffffffff600000 but 
FileIO.seek() fails because it gets an offset bigger than 2^63, which is seen 
as a negative number and FileIO.seek() considers a negative number as an error.

Attached patch fixes this issue by checking not only the result of lseek(), but 
also errno:

    errno = 0;
    Py_BEGIN_ALLOW_THREADS
#if defined(MS_WIN64) || defined(MS_WINDOWS)
    res = _lseeki64(fd, pos, how);
#else
    res = lseek(fd, pos, how);
#endif
    Py_END_ALLOW_THREADS
    if (res == (off_t)-1 && errno)
        return posix_error();

PyLong_AsUnsignedLong() is tried if PyLong_AsLong() failed with an 
OverflowError. I kept PyLong_AsLong() for relative seek with a negative offset, 
and I prefer to try first PyLong_AsLong() because the overflow case is very 
unlikely compared to negative offsets for relative seek.

The result is always casted to an unsigned number. I never seen a device or 
file descriptor supporting negative offset.

I don't know how to test this code path automatically. I only know the 
"[vsyscall]" mapping use case on Linux, and it requires to parse 
/proc/self/maps which is not trivial and I would prefer sometimes simpler (more 
reliable with less maintenance). I propose to not add an unit test, except 
someone find how to write a simple and reliable test.

> This is not true of a regular file where I get errno=22
> when seeking to an offset greater than or equal to 2^63.

Same behaviour on Linux: OSError(22, "Invalid argument") when I try file.seek(1 
<< 63) on a regular file.

----------
Added file: http://bugs.python.org/file30487/lseek_unsigned.patch

_______________________________________
Python tracker <rep...@bugs.python.org>
<http://bugs.python.org/issue12545>
_______________________________________
_______________________________________________
Python-bugs-list mailing list
Unsubscribe: 
http://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com

Reply via email to