如何编译C文件但限制库使用?

时间:2012-04-21 19:46:36

标签: c unix gcc compilation

我正在使用unix服务器。

我从我的客户端获取一个c文件作为输入,我编译。

c文件应该是非常基本的,并且只包含来自stdio,stdlib,math,string的函数。

GCC编译器中是否有任何标志不允许使用任何其他库,并且在使用其他库时会抛出编译错误?

如果有一个不涉及GCC的解决方案,它也可能是好的,但我不想检查该文件。

感谢。

3 个答案:

答案 0 :(得分:6)

限制库(包括编译时的头文件和链接时的库链接)不会阻止不受信任的代码直接调用危险(如安全相关的)内核系统调用。这可以通过不可信代码来完成,例如通过使用内联汇编或shellcode / exploit技术,例如通过故意覆盖堆栈上的返回地址指向包含shellcode的字符串。

话虽如此,您可以使用-nostdlib -nodefaultlibs链接器选项来阻止链接到库。但是,这仍然只允许您拥有整个libc,或者不包含任何libc。您无法有选择地仅链接到libc的一部分(例如,有printf()而不是system())。

只允许某些包含也不是非常有效:代码只能复制包含文件中的声明,而不是包含某些标题以绕过限制,只允许特定的#include语句。例如:

int system(const char *);
int main() {
    return system("uname -a");
}

如果它必须是安全的,你应该考虑在运行时沙箱化代码而不是试图防止不安全的代码编译。

答案 1 :(得分:1)

将选项-nodefaultlibs-nostdlib传递给gcc,以及仅包含允许的库的选项(如数学库的-lm)。有关这些选项的详细信息,请查看gcc manual

  

<强> -nodefaultlibs
  链接时请勿使用标准系统库。只有   您指定的库将传递给链接器。

答案 2 :(得分:1)

为了说明你允许包含stdlib.h的不安全性,我会编写一个可以在你的机器上运行任意代码的小程序。

#include <stdlib.h>

int main() {
    system("`which python` -c \"print 'hello word'\"");
    // instead of simply printing hello world i could open a socket back to the 
    // attacker's machine and start reading in abitrary code and executing it.
    return 0;
}