简体   繁体   English

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

[英]Is it safe to use a char pointer in *argv[] directly in C?

I have the following code to get a string from a user with getopt() in C:我有以下代码可以从 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 ...
}

Is this safe to do, or should I use strcpy() to copy the string into argument ?这是安全的,还是我应该使用strcpy()将字符串复制到argument中? If I accidentally change the contents of argument , could an attacker change stuff like environment variables?如果我不小心更改了argument的内容,攻击者会更改环境变量之类的内容吗?

Is this safe to do, or should I use strcpy() to copy the string into argument?这是安全的,还是我应该使用strcpy()将字符串复制到参数中?

It is safe to do, and getopt() is designed to be used that way.这样做是安全的,并且getopt()旨在以这种方式使用。 More generally, the program arguments provided to main are specified to be writable strings belonging to the program.更一般地,提供给 main 的程序参数被指定为属于该程序的可写字符串。

Do note, however, that some getopt() implementations, notably GNU's, may reorder the elements of argv .但是请注意,某些getopt()实现,尤其是 GNU 的实现,可能会重新排序argv的元素。

If I accidentally change the contents of argument, could an attacker change stuff like environment variables?如果我不小心更改了参数的内容,攻击者会更改环境变量之类的内容吗?

The argument strings are susceptible to bounds overflow errors just like any other objects in the program.与程序中的任何其他对象一样,参数字符串容易受到边界溢出错误的影响。 If, through programming error or other means, your program attempts to write past the bounds of any object then the behavior is undefined.如果通过编程错误或其他方式,您的程序尝试写入超出任何对象的边界,则该行为是未定义的。 Modification of environment variables is one of the more plausible members of the unbounded space of possible manifestations of UB.环境变量的修改是 UB 可能表现的无限空间中更合理的成员之一。

Note, however, that making a copy of the arguments doesn't help in that regard.但是请注意,在这方面制作参数的副本并没有帮助。 You must avoid overrunning the bounds of any such copies, too, lest UB be triggered, with the same unbounded space of possible manifestations.您也必须避免超出任何此类副本的边界,以免触发 UB,并具有相同的无限可能表现空间。

If you want to make sure that the program arguments cannot be modified via variable argument , then it would be idiomatic to declare it as a pointer to const char instead of a pointer to (modifiable) char .如果您想确保程序参数不能通过变量argument进行修改,那么将其声明为指向const char而不是指向 (modifiable) char的指针将是惯用的。 That will not interfere with assigning the value of optarg to it.这不会干扰将optarg的值分配给它。

Yes, this is "safe".是的,这是“安全的”。

The contents of argv are supplied by the host environment, and belong to your process for its entire duration. argv的内容由宿主环境提供,并且在整个过程中属于您的进程。

On argv :argv上:

The strings are modifiable, and any modifications made persist until program termination, although these modifications do not propagate back to the host environment: they can be used, for example, with strtok .字符串是可修改的,并且所做的任何修改都将持续到程序终止,尽管这些修改不会传播回主机环境:例如,它们可以与strtok一起使用。

With that said, privileged processes, like the ps utility, are generally capable of accessing the current values of argv .话虽如此,特权进程,如ps实用程序,通常能够访问argv的当前值。 Using argv for sensitive information is ill advised.不建议将argv用于敏感信息。

See: Hiding secret from command line parameter on Unix and Can argv be changed at runtime (not by the app itself) for security concerns.出于安全考虑,请参阅:在 Unix 上隐藏命令行参数中的秘密是否可以在运行时更改 argv(不是由应用程序本身)


Aside: getopt returns an int .另外: getopt返回一个int The distinction is important, because if char is unsigned, it cannot represent the terminating value:区别很重要,因为如果char是无符号的,它就不能代表终止值:

If all command-line options have been parsed, then getopt() returns -1.如果所有命令行选项都已解析,则 getopt() 返回 -1。

You should use int to reliably test against this value, otherwise the loop will continue infinitely.您应该使用int可靠地测试该值,否则循环将无限继续。

int ch;

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM