Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

SECCOMP: How to emulate malloc, realloc and free?

I would like to execute arbitrary (potentially dangerous) binaries on my server. Therefore, I have used objcopy to rename the "main" symbol to "other_main" so that I could link in my own small main function that sets an appropriate value for RLIMIT_CPU and toggles the SECCOMP flag before calling other_main. I am quite happy with this solution so far.

The problem now is, that the 3rd party program code might contain some calls to malloc that might kill the program instantly (sbrk isn't allowed). Therefore I would like to pre-allocate some reasonable sized array (e.g. 20MB) before setting SECCOMP that should be used by malloc / realloc / calloc / free. Unfortunately, I don't know how to archive the last step. Do I have to implement all those 4 functions on my own? How can I inject my own functions to the stdlib (e.g., what happens when printf calls malloc internally?).

like image 916
tux21b Avatar asked Jul 13 '12 20:07

tux21b


2 Answers

Not all malloc implementations are based on sbrk(), there is for example GNU mmalloc. This doc also might be useful if custom implementation is needed.

+two simple malloc implementations here

like image 78
pmod Avatar answered Oct 10 '22 20:10

pmod


For malloc and free, your program just needs to define its own versions. Most libc implementations that I've seen (including glibc, klibc, and dietlibc) will happily use your memory allocator routines. So, before entering seccomp mode, allocate a large chunk of memory using mmap or sbrk and then have your malloc/free allocate from this chunk. memmgr is a simple heap allocator that can be adapted easily for allocation out of a fixed buffer.

The real problem with seccomp is that the set of system calls it allows (read, write, exit, and sigreturn) is simply not sufficient to run programs linked against more or less any libc out there. For example:

  • in glibc, exit and _exit call exit_group
  • in glibc, printf can call mmap
  • in dietlibc, scanf can call ioctl
  • etc., etc.

There are typically good reasons why these calls are necessary. For example, dietlibc uses ioctl to check if stdin is a tty when input is read from stdin, in order to flush stdout. This is standard behavior to ensure that prompts are visible before reading interactive input if the output is line buffered.

So, I have come to the conclusion that the original seccomp mode is more or less useless. Mode 2 (a.k.a. "filter mode"), however, is much more useful since it allows you to whitelist specific system calls. I have a proof of concept on my github page which runs programs in seccomp mode 2, but allows them to use printf and scanf, as well as allocate memory using malloc/free.

like image 38
David Hovemeyer Avatar answered Oct 10 '22 19:10

David Hovemeyer