在*argv[]中直接使用char指针是安全的吗?

  • 本文关键字:指针 char 安全 argv c getopt
  • 更新时间 :
  • 英文 :


我有以下代码从C中具有getopt()的用户获取字符串:

#include <stdio.h>
#include <getopt.h>
#include "util.h"
int main(int argc, char *argv[]) {
if (argc == 1) {
usage(); // from util.h
return 0;
}
char *argument = NULL;
char ch;
while ((ch = getopt(argc, argv, ":f:"))) {
switch (ch) {
case 'f':
argument = optarg;
break;
}
}
// ... use `argument` with other stuff ...
}

这是安全的,还是我应该使用strcpy()复制字符串到argument?如果我不小心更改了argument的内容,攻击者会更改环境变量之类的东西吗?

这是安全的,还是我应该使用strcpy()将字符串复制到参数中?

这样做是安全的,并且getopt()被设计为这样使用。更一般地说,提供给main的程序参数被指定为属于程序的可写字符串。

请注意,一些getopt()的实现,特别是GNU的,可能会重新排列argv的元素。

如果我不小心改变了参数的内容,攻击者会改变环境变量之类的东西吗?

实参字符串和程序中的其他对象一样容易发生边界溢出错误。如果由于编程错误或其他原因,您的程序试图编写超出任何对象边界的内容,则该行为是未定义的。环境变量的修改是UB可能表现的无界空间中比较可信的成员之一。

但是,请注意,在这方面,创建参数的副本并没有帮助。您还必须避免超出任何此类副本的边界,以免触发UB,并具有相同的无界空间的可能表现。

如果你想确保程序参数不能通过变量argument修改,那么习惯做法是将其声明为指向const char的指针,而不是指向(可修改的)char的指针。这不会影响将optarg的值赋给它。

是的,这是"安全"的。

argv的内容由主机环境提供,并且在整个过程中属于您的进程。

Onargv:

字符串是可修改的,任何修改都将持续到程序终止,尽管这些修改不会传播回宿主环境:例如,它们可以与strtok一起使用。

也就是说,特权进程,比如ps实用程序,通常能够访问argv的当前值。对敏感信息使用argv是不明智的。

参见:在Unix上隐藏命令行参数的秘密和argv是否可以在运行时更改(而不是应用程序本身)以考虑安全问题。


Aside:getopt返回一个int。这个区别很重要,因为如果char是无符号的,它就不能表示终止值:

如果已经解析了所有命令行选项,那么getopt()返回-1。

您应该使用int可靠地测试此值,否则循环将无限继续。

int ch;
while (-1 != (ch = getopt(argc, argv, ":f:")))

最新更新