views:

136

answers:

6

Does anyone tell me how to block some specific system calls within a program, please? I am building a system which takes a piece of C source code, compiles it with gcc and runs it. For security reasons, I need to prevent the compiled program from calling some system calls. Is there any way to do it, from the source code level (e.g. stripping the header files of gcc, detecting malicious external calls, ...) to the executable level?

Edited #1: Add details about malicious calls.

Edited #2: My system is a GNU/Linux one.

Edited #3:

I have tried some methods within a few days and here are the conclusions I've got so far:

  1. Scanning the source code does not solve the main problem since one can always obsfucate his/her C source file quite well.
  2. "Overriding C symbol" works well for libraries, but for system calls I have not achieved what I wanted. This idea is not dead, however, doing this would definitely cause me a lot of time hacking (gcc and/or ld).
  3. Permission deescalation works like a charm. I could use fakeroot or a "guest" user to do it. This method is also the easiest to implement.

The other one is native client which I have not tried yet but I definitely would in near future due to the common between the project and my work.

+1  A: 

Just to illustrate that this is not possible, the following program:

int main() {
    return 0;
}

makes over 20 system calls as reported using strace. The calls include open (twice) which is one of the calls you seem to want to block.

anon
Thank you, but I meant some specific ones, not all.
CMPITG
+2  A: 

You can't.

Even this program:

#include <stdio.h>

int main()
{
    printf("Hello, World\n");
    return 0;
}

makes at least one system call (to send the string "Hello, World\n" to standard out). System calls are the only way for a program to interact with the outside World. Use the operating system's security model for security.

Edited for this comment:

I meant not all system calls but malicious system calls, e.g. execv() could be used to execute a BASH script which wipes out my data on the disk.

Your operating system already includes mechanisms to stop that sort of thing happening. For instance, in order for a bash script to wipe out your data, the process must already have write access to that data. That means it must have been started by you or root. Your only real option is not to install untrustworthy software.

By the way, depending on your platform, execv is not necessarily a system call. On Linux, it's a C library wrapper for the real system call (execve).

JeremyP
Now that you mention about the file system permission, I find out a solution for that by executing it as a custom user who does not have the write permission in that directory. I almost forgot that. Thank you :-D.
CMPITG
+1  A: 

Well, if you just want to block specific calls, why not just do a grep through the source code before attempting to compile it ? And reject programs which use the insecure system calls.

High Performance Mark
Could I do it automatically, by using a program which scans the source code? For example, I have one source file which includes the "unistd.h" which might result in malicious situations, and another source file which has a struct named "unistd" which has a field named ".h", how do I differentiate the circumstances?
CMPITG
You certainly can do it automatically. I'd start with grep or sed, but if that's not your cup of tea any common programming language, especially one with good regular expression capabilities, would do.
High Performance Mark
Yeah, that would probably work, though I have to carefully design the algorithm to scan using grep or inline Perl, or restricting the source code naming convention. Thank you :-).
CMPITG
I can transform my source code in arbitrary ways to try and defeat your grep. If you try this, probably best do so in the step between pre-processing and actually compiling.
crazyscot
Sure, that's why I said I had to carefully design the algorithm or restricting naming convention and then eliminate illegal ones.
CMPITG
Any such source scanner is quite likely to be bypassable, *particularly* if it's built using regular expressions (which implies that it doesn't read the C syntax). How do you know if that innocent-looking array of integer constants is actually the machine code to invoke an `execve` syscall? (You don't actually need any header files - or any external code even - to invoke a system call).
caf
+5  A: 

As others have noted, it's impossible for a program to avoid making system calls, they permate the C library all over the place.

However you might be able to make some headway with careful use of the LD_PRELOAD mechanism, if your platform supports it (e.g. Linux): you write a shared library with the same symbol names as those in the C library, which are called instead of the intended libc functions. (For example, Electric Fence is built as a shared library on Debian-based systems and intercepts calls to malloc, free et al.)

I suspect you could use this mechanism to trap or argument-check calls to any libc functions you don't like, and perhaps to note those which you consider unconditionally safe. It might then be reasonable to scan the compiled executable for the code corresponding to INT 80 to trap out any attempts to make raw syscalls (0xcd 0x80 - though beware of false positives). However I have only give this a few moments of thought, I could easily have missed something or this might turn out to be impractical...

crazyscot
Brilliant idea about the kind of overriding the C symbol! This way I could totally control and detect calls with bad purposes. I will definitely try this out as well as the other two ways (scanning the source file and permission deescalation) and see which is the most appropriate.
CMPITG
I've just thought of a more detailed example of the power of this mechanism: check out the `fakeroot` package.
crazyscot
It's possible to execute a syscall without making use of any libraries, so if you expect to build a system secure against malicious users, using LD_PRELOAD is not sufficient.
Eric Seppanen
+1  A: 

Some project have similar idea you can take a look at nacl: http://code.google.com/p/nativeclient/

mathk
It's worth a try, I'll take a shot.
CMPITG
+3  A: 
ot