kylemanna/pydevmem

Lack of support for 64bit addresses.

david0sen opened this issue · 1 comments

In most modern systems nowadays, wether intel or ARM based, the physical and kernel virtual addresses are 64 bits, and mostly towards the top 4GB half.
When trying any such address in devmem.py, the following happens:

$ sudo python -S ./devmem.py -r 0xffffe00000000000 -n 1
Traceback (most recent call last):
  File "./devmem.py", line 279, in <module>
    sys.exit(main())
  File "./devmem.py", line 257, in main
    debug=options.debug)
  File "./devmem.py", line 123, in __init__
    offset=self.base_addr)
OverflowError: Python int too large to convert to C long

The C type long long, or the more standardized C99 type [u]int64_t should be fine.

This isn't a bug with this project, it's a limitation of an offset being a signed 64-bit number. On my platform off_t is 8 bytes which is correct.

See the implementation of mmap.mmap in CPython which uses an off_t. This identical to the C API man 3 mmap:

void *mmap(void *addr, size_t len, int prot, int flags, int fildes, off_t off);

The real problem is that the addr argument to mmap() API is set to NULL. Instead we should be setting the base address to within 2^63 so that the signed offset can reach the area of interest. However, the Python mmap() invocation prevents this.

See here. To reach the address you need you would need to correct this bug in the Python mmap module. 😬

    m_obj->data = mmap(NULL, map_size,
                       prot, flags,
                       fd, offset);

Test cases to validate this:

$ sudo -E python3 devmem.py -r 0x8000000000000000
Traceback (most recent call last):
  File "devmem.py", line 273, in <module>
    sys.exit(main())
  File "devmem.py", line 250, in main
    mem = DevMem(addr, length=options.num, filename=options.mmap,
  File "devmem.py", line 118, in __init__
    self.mem = mmap.mmap(self.f, self.length, mmap.MAP_SHARED,
OverflowError: Python int too large to convert to C long

But the following fails in a different way (likely kernel not allowing it) where it doesn't overflow a signed 64 bit number.

$ sudo -E python3 devmem.py -r 0x7000000000000000
Traceback (most recent call last):
  File "devmem.py", line 273, in <module>
    sys.exit(main())
  File "devmem.py", line 250, in main
    mem = DevMem(addr, length=options.num, filename=options.mmap,
  File "devmem.py", line 118, in __init__
    self.mem = mmap.mmap(self.f, self.length, mmap.MAP_SHARED,
OSError: [Errno 22] Invalid argument

Sorry I can't help.