Assume we have a process that may dlopen()
some third-party library. This library may perform open("write_only_logfile", O_WRONLY)
on some file to which user has only write access. We need to have an ability to be notified if this library attempts to open a file, so later we may dup()
returned descriptor and redirect output.
There are few restrictions that make interception harder:
LD_PRELOAD
is forbidden - no way to hook open()
inotify(7)
doesn't help because user has no read permissions on "write_only_logfile"
and it is owned by admin"write_only_logfile"
is hardcoded inside the library, so we cannot pass another name to perform redirectingI'm wondering if Linux has an efficient way to help in such situation.
Especially taking in account the fact that process may open()
miscellaneous files pretty often.
P.S. To avoid confusion and understand better - it is a regular Android application with loaded JVM. If app hangs (so called ANR) - system sends SIGQUIT
to it. Signal is received via dedicated thread that open()
s /data/anr/traces.txt
and writes JVM state to it. These data extremely useful for debugging. But app cannot read that file directly because of security reasons (All applications write to it, so there may be somewhat sensitive). Anyway I believe that it is absolutely fair to intercept content that my process would write to it.
P.S.S. In the worst case it is possible to find JVM library image (libart.so
) and manually patch jump slot for open()
. But it doesn't sound well.
Sounds like you are in troublesome situation. Most solutions briefly mentioned below are guaranteed to interfere with SELinux, so don't take my word for any of that.
Debugging your own process with strace
to intercept open
is one of usual solutions on normal Linux. I am not sure if it would work in Android; it certainly might become off-limit for non-debuggable apps starting in some new versions (if it is has not been banned yet).
seccomp-bpf is another possibility. Might not be available on older Android versions, but since Android O seccomp is going to be a guaranteed part of Android security getup. Intercept open
in warn-only mode and give control back to yourself when something interesting happen (via debugging or signals).
If /data/anr/traces.txt
is opened on-demand, you should be able to observe that by watching contents of /proc/self/fd/
with inotify or via polling. You might be able to reduce impact of races by setting io niceness of the opening thread…
All of above are only partial solutions, you still might need to decode actual open
syscall that happened (strace source code might be helpful there for strace/seccomp solutions, readlink for /proc/self/fd/
) and act upon it (dup2, as you already mentioned).
"write_only_logfile" is hardcoded inside the library
Is it possible to modify the memory of data segment of the library/executable? Afaik mprotect
and PROTECT_EXEC
in particular have been heavily restricted, but at least mmap is certainly permitted (to support JIT compilers etc). It might be possible to cook something up to edit the string constant in place (as long as doing so is possible and allowed, I am not sure myself about that).