[patch 0/3] Live PIDs with deleted files by /dev/PID/mem

Jan Kratochvil jan.kratochvil at redhat.com
Sat Feb 22 21:08:29 UTC 2014


Hi,

jankratochvil/devmem

this is a different approach to:
	[patch] Support live PIDs with deleted files
	https://lists.fedorahosted.org/pipermail/elfutils-devel/2013-December/003637.html
	Message-ID: <20131218191326.GA8969 at host2.jankratochvil.net>

The patch above required /proc/PID/map_files/ which is currently accessibly
only by root.  Why it is so in Linux kernel:
------------------------------------------------------------------------------
An security breach countercase upstream is ftruncate(2) for mmap(2)ed and
close(2)ed file which was not possible without map_files/ before.  This is why
map_files/ was restricted to CAP_SYS_ADMIN (=root) in the end:
	http://article.gmane.org/gmane.linux.file-systems/57619
	http://article.gmane.org/gmane.linux.file-systems/57640

As their concern there is about R/W mapping and modifications of the file they
also claim it is only an example, that the security implications may be wider.

My original plan was to make the mapping accessible for non-root in R/O mode
as elfutils is enough with R/O access only.

But now I think about a countercase where one has only a part of file
mmap(2)ped while the file is unlinked or located in inaccessible directory.
Then R/O map_files/ access will make the whole file accessible to the user.
This makes even R/O map_files/ non-root access losening of security rules.
------------------------------------------------------------------------------

Fortunately for backtracing of deleted executables/libraries one does not need
to access any unmapped memory (assuming here Fedora executables built with
-fasynchronous-unwind-tables).  ELF header, program headers and PT_GNU_EH_FRAME
are all mapped in memory and accessible by PTRACE_PEEKTEXT (and /proc/PID/mem).

Therefore the whole solution can be done in elfutils emulating all mapped
parts of ELF from remote memory.  Moreover elfutils already provides support
for ELFs in the middle of a file - as elfutils supports .a archives.

(1)
This patchset (/dev/PID/mem solution) works only on recent Linux kernels
(tested kernel-3.13.3-201.fc20.x86_64) as older kernels (RHEL-6) required
PTRACE_ATTACHed PID to read its /dev/PID/mem.  This patch does not try to
workaround older kernels by doing PTRACE_ATTACH.

$ sleep 1h&p=$!;sleep 0.1;dd if=/proc/$p/mem bs=1 skip=$[0x400000] count=4|(sleep 0.1;od -c)

new kernels:
4+0 records in
4+0 records out
4 bytes (4 B) copied, 7.0551e-05 s, 56.7 kB/s
0000000 177   E   L   F
0000004

old kernels:
0+0 records in
0+0 records out
0 bytes (0 B) copied, 0.000110785 s, 0.0 kB/s
0000000

On older kernels the testcase will:
SKIP: run-deleted.sh

(2)
The former patch using /proc/PID/map_files/ still may be useful so that
elfutils can access .debug_frame or .symtab embedded in the same file
(=not using /usr/lib/debug separate debuginfo).
/proc/PID/exe also makes sense.

/proc/PID/map_files/ - all files            but only for root tracers
/proc/PID/exe        - only main executable but even for non-root tracers

(3)
There is currently a bug in symbol resolving (eu-stack without -q) of deleted
prelinked executables.
$ cp /bin/sleep /tmp/deleteme;/tmp/deleteme 100h&p =$!;rm /tmp/deleteme;./src/stack -p $p
#0  0x000000320e6bc970 __nanosleep
#1  0x00000000004040cf x2realloc
#2  0x0000000000403f30 emit_bug_reporting_address
#3  0x00000000004018ed _init
#4  0x000000320e621d65 __libc_start_main
#5  0x00000000004019f9 _init
vs. the right one - unprelinked:
$ cp /bin/sleep /tmp/deleteme;prelink -u /tmp/deleteme;/tmp/deleteme 100h&p=$!;rm /tmp/deleteme;./src/stack -p $p
#0  0x000000320e6bc970 __nanosleep
#1  0x00000000004040cf rpl_nanosleep
#2  0x0000000000403f30 xnanosleep
#3  0x00000000004018ed main
#4  0x000000320e621d65 __libc_start_main
#5  0x00000000004019f9 _start

This is because this libdwfl/dwfl_module_getdwarf.c comment is no longer true
after this patch
         If there are no section headers at all (full stripping), then
         the end of the first segment is a valid synchronization address.
         This cannot happen in a prelinked file, since prelink itself
         relies on section headers for prelinking and for undoing it.
         (If you do full stripping on a prelinked file, then you get what
         you deserve--you can neither undo the prelinking, nor expect to
         line it up with a debug file separated before prelinking.)

because /proc/PID/mem does not have to have section headers mapped.

Primarily I am not aware how to fix it.  Besides that I find it an unrelated
bug to this patch.  And also I am not completely sure it has a strong need of
a fix.  Numerical backtrace (ABRT) is always right.  The symbols are wrong
only for prelinked executables but in reality prelink has become or becoming
more rarely used tool.


Thanks,
Jan


More information about the elfutils-devel mailing list