[Sony Xperia XZ1 Compact ROMs, Kernels, Recoveries,] j4nn:
extending strace to trace qseecom api

I've managed to extend strace to trace qseecom and ion ioctl calls, which are normally not compiled in strace utility.

Unfortunately qseecom ioctl calls seem to use ion allocated memory buffers, that are not accessible from strace (and most likely not from gdb either).

It is therefore not possible to further parse the command and response buffers from qseecom api ioctl calls.

It seems that in order to be able to read (or write) those buffers, there needs to be implemented the 'access' callback of the vm_operations_struct for that ion allocated memory - which is not the case as we can see in ion driver source code in kernel sources.

I would like to implement a kernel module, which would patch the 'ion_vma_ops' struct, setting the .access member to a function implemented in my module in order to provide the functionality for strace/gdb.

Unfortunately it is not easily possible to set that member, because the 'ion_vma_ops' struct is defined as

static const struct vm_operations_struct ion_vma_ops

i.e. static const. The static visibility is not that big problem, but the 'const' actually is, because that makes the struct go into read only data section in kernel, which is explicitly disabled write access in MMU page tables. So currently what I need is to modify the arm64 page table that maps the content of 'ion_vma_ops' for write access. That is hinted a bit in following stackoverflow post:

https://stackoverflow.com/questions/45216054/arm64-linux-memory-write-protection-wont-disable

unfortunately it seems not work in my case - I am not getting a valid pte pointer for 'pmd' and 'addr' pair from pte_offset_map function.

Most likely because the pmd is a section descriptor, whatever that is - pmd_sect(*pmd) evaluates to true.

-- edit --

It seems this would never work. Even when .access member is set in the ion_vma_ops, it would not allow ptrace to access the ion buffers used with qseecom ioctl calls. Most likely the code that would page fault the buffer pages into userspace via mmap is not active, being explicitly disabled inside __ion_alloc():

/*
* For now, we don't want to fault in pages individually since
* clients are already doing manual cache maintenance. In
* other words, the implicit caching infrastructure is in
* place (in code) but should not be used.
*/
flags |= ION_FLAG_CACHED_NEEDS_SYNC;

while the ION_FLAG_CACHED_NEEDS_SYNC flag is checked in ion_buffer_fault_user_mappings() needed not to be set in order to allow setup of vma->vm_ops with &ion_vma_ops inside ion_mmap function.

I am afraid we cannot strace/ptrace/gdb QSEECOM_IOCTL_SEND_CMD_REQ and other calls from userspace when qseecom api is compiled in statically as we cannot access the used ion buffers from other process.

-- edit --

openat(AT_FDCWD, "/dev/qseecom", O_RDWR) = 16
ioctl(16, QSEECOM_IOCTL_GET_QSEOS_VERSION_REQ, {qseos_version=20}) = 0
ioctl(16, QSEECOM_IOCTL_APP_LOADED_QUERY_REQ, {app_name="tzxflattest", app_id=131074, app_arch=0}) = -1 EEXIST (File exists)
openat(AT_FDCWD, "/dev/ion", O_RDONLY) = 17
ioctl(17, ION_IOC_ALLOC, {len=8192, align=4096, heap_id_mask=0x8000000, flags=0x00, handle=1}) = 0
ioctl(17, ION_IOC_MAP, {handle=1, fd=18}) = 0
mmap(NULL, 8192, PROT_READ|PROT_WRITE, MAP_SHARED, 18, 0) = 0x75e1250000
ioctl(16, QSEECOM_IOCTL_SET_MEM_PARAM_REQ, {ifd_data_fd=18, virt_sb_base=0x75e1250000, sb_len=4224}) = 0
ioctl(16, QSEECOM_IOCTL_SEND_CMD_REQ, 0x7fccdd36a8 = {cmd_req_buf=0x75e1250000, cmd_req_len=64, resp_buf=0x75e1250040, resp_len=64} -> 0x7fccdd36a8 = {resp_buf=0x75e1250040, resp_len=64}) = 0

Cannot access cmd_req_buf and resp_buf to further parse the actual qseecom api command and it's response, even when set of ION_FLAG_CACHED_NEEDS_SYNC has been removed and kernel recompiled, while having the .access member set in the ion_vma_ops.