Hacker News new | past | comments | ask | show | jobs | submit login
Pseudo Graceful Process Termination Through Code Injection (sigma-star.at)
51 points by Deeg9rie9usi 5 months ago | hide | past | favorite | 9 comments



This is cute, but why not just do this with gdb? All-stop mode is on by default so it will stop all threads when you attach, and then you can simply invoke the exit_group() syscall.

    tty1$ ./program
    
    tty2$ gdb attach $(ps aux | grep program | head -1 | awk '{ print $2 }')
    Attaching to process 708267
    [New LWP 708268]
    [New LWP 708269]
    [New LWP 708270]
    [New LWP 708271]
    [Thread debugging using libthread_db enabled]
    Using host libthread_db library "/lib/x86_64-linux-gnu/libthread_db.so.1".
    0x00007f00b1633117 in ?? () from /lib/x86_64-linux-gnu/libc.so.6
    
    (gdb) p (long)syscall(231, 0)
    [Thread 0x7f00565e6640 (LWP 708271) exited]
    [Thread 0x7f005a5e8640 (LWP 708270) exited]
    [Thread 0x7f005ade9640 (LWP 708269) exited]
    [Thread 0x7f005d5ee640 (LWP 708268) exited]
    [Inferior 1 (process 708267) exited normally]
    The program being debugged exited while in a function called from GDB.
    Evaluation of the expression containing the function
    (syscall) will be abandoned.
    (gdb) quit
    
    tty1$ echo $?
    0


syscall is only available if gdb is able to resolve libc. So for example this won’t work to stop a process running in a container, since gdb won’t be able to see the libc in the container’s filesystem. I did make my own variant using gdb, though, nicely explained here: https://thomasw.dev/post/killbutmakeitlooklikeanaccident/


Since you are writing to the location where rip is pointing to, you need to rewind to the beginning of the page first. Otherwise the program will crash if you're unlucky and rip is currently exactly at the end of an executable mapping. Low chance, but still...


Nice! Even better.


I guess one goal of the experiment was understanding and learning how to do it by hand (in C) instead of relying on gdb.


> However, what if the need arises to forcefully terminate a process, disguising it as a successful exit? ... Since the parent process would detect the non-zero exit code, there was a high likelihood of making things worse.

I'm still trying to imagine what situation that is. I still cannot think about any real case where this is something you need.

If there is, I guess this is a very rare case? As it was already commented, I guess just gdb then?

But the technical details on how they do it are interesting nevertheless.


One use case I have faced more than once are stuck processes in legacy build systems. For example, generating docs takes ages. Just killing the generator process will fail the build because the parent will notice. And since the build system is buggy/old, restarting the build will start from zero.


how can we build a tool to stop a process forcefully but make it look like a successful termination? As far as I know, Linux doesn’t provide an API to perform such a kill.

Interestingly, Windows does:

https://learn.microsoft.com/en-us/windows/win32/api/processt...


Using gdb is probably easier.




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: