From: Ian Jackson Date: Mon, 8 Apr 2019 15:46:04 +0000 (+0100) Subject: fishdescriptor: cast __errno_location correctly X-Git-Tag: archive/debian/6.0.4~4 X-Git-Url: http://www.chiark.greenend.org.uk/ucgi/~ian/git?p=chiark-utils.git;a=commitdiff_plain;h=7adf096856bc7ae9735f570b25c2d20d9edde588;hp=44c1812948913bc214b71f238d30fb1650039494 fishdescriptor: cast __errno_location correctly The return value from __errno_location() is an int*. My syntax had erroneously specified that it returned an int. Nothing spotted this bug because the expression is evaluated by gdb whose C interpreter is very strange. In particular, gdb lets you dereference an int, even on a platform where ints are 32-bit and pointers are 64-bit. If you are on a 32-bit platform, this does not matter. Likewise if you are on a 64-bit platform and the address of errno happens, by luck, to be within the 32-bit addressable part of the space. If you are mildly lucky the result of this is an error like this: gdb.MemoryError: Cannot access memory at address 0x2f24ef10 buried in stack traces from fishdescriptor. If you are unlucky, fishdescriptor will successfully access some wrong location. This means it does not actually save and restore errno, since it saves and restores somewhere else instead. So fishdescriptor will corrupt the errno value of the thread that it happens to be (ab)using, overwriting it with the errno from fishdescriptor's own calls, possibly causing the target program to become confused about the error(s) from system call(s) it is making. If you are very unlucky, fishdescriptor will successfully access some wrong location which is actively in use by something outside the target process (eg, direct IO, shared memory0. fishdescriptor will save the value (a single int) and then restore it a bit later. This might in principle cause any kind of arbitrary lossage. Signed-off-by: Ian Jackson --- diff --git a/fishdescriptor/py/fishdescriptor/indonor.py b/fishdescriptor/py/fishdescriptor/indonor.py index 20bc807..e227fb2 100644 --- a/fishdescriptor/py/fishdescriptor/indonor.py +++ b/fishdescriptor/py/fishdescriptor/indonor.py @@ -142,7 +142,7 @@ class DonorImplementation(): # in my browser). Also the error is very nonspecific :-/. # This seems to happen on jessie, and is fixed in stretch. # Anyway: - return parse_eval(expr_pat % '(*((int (*)(void))__errno_location)())') + return parse_eval(expr_pat % '(*((int*(*)(void))__errno_location)())') # calling functions (need to cast the function name to the right # type in case maybe gdb doesn't know the type)