首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >依赖PATH_MAX可能会导致溢出

问依赖PATH_MAX可能会导致溢出
EN

Stack Overflow用户
提问于 2019-07-07 18:03:02
回答 2查看 948关注 0票数 3

正如您所知道的,PATH_MAX是用于指示环境变量(在本例中为PATH变量)的最大大小的值,但在大多数情况下并不是这样的。看看这段用于将环境变量复制到大小为PATH_MAX的数组中的代码

代码语言:javascript
复制
  char env[PATH_MAX]; 
  strcpy(path, getenv("PATH"));

如果您可以看到它可以如此容易地溢出,人们会说使用strncpy可以避免溢出,但是如果您使用它并且PATH很大,那么MAX_PATH我们将无法获得完整的PATH环境变量,这让我思考,如何在假设不会溢出或丢失数据的情况下获得路径环境变量

EN

回答 2

Stack Overflow用户

发布于 2019-07-07 18:25:46

通常,如果您需要复制长度未知的字符串,请使用strncpy将其复制到有大小限制的固定大小的缓冲区中(但要注意,如果字符串太长,则不终止字符串的不便行为)。

或者使用strdup对副本进行malloc。

如您所知,

PATH_MAX是用于指示环境变量(在本例中为PATH变量)的最大大小的值。

不,它不是;它与$PATH或环境无关!!

它是单个文件系统路径名的最大长度。例如,保证/foo/bar/verylongdirectoryname/x/y.txt的长度最多为PATH_MAX。

PATH环境只是一个简单的字符串,就像任何其他环境变量一样;内核不会将它们裁剪成固定的长度。或者肯定不会被限制在PATH_MAX。

如何在假设没有溢出或数据丢失的情况下获得PATH环境变量

Uh,你已经在 getenv("PATH").上有了它返回一个指向进程内存空间中现有字符串的指针。它实际上是在静态存储中;您不需要复制它,将来对getenv的调用也不会破坏指针。(在Linux上,env var在进程启动时位于argv之上的堆栈中。在移动堆栈指针之前运行的CRT启动代码在全局envp中存储指向堆栈指针的指针,getenv稍后可以在全局CRT中找到该指针。)

如果你想复制一个环境变量的缓冲区,这样你就可以加长它,或者修改它而不改变原始文件,最简单的选择是 来malloc一个副本.(POSIX2008,以及之前的BSD和之前的各种系统)。或strndup来设置要复制的字节数限制。

GNU C甚至有一个基于alloca而不是malloc的版本,以防你想要一个更便宜的临时自动存储。

PATH_MAX

PATH_MAX 是相关的,例如,在像 这样的POSIX函数中,您提供了一个缓冲区,但没有长度限制。(但实际上,您应该使用char *getcwd(char *buf, size_t size);请参阅与getwd相同的链接。手册页还说:

注意,在某些系统上,PATH_MAX可能不是编译时常量;而且,它的值可能取决于文件系统,请参见pathconf(3)。

Linux readdir(3)手册页上没有这样说,但是struct dirent成员char d_name[256]; /* Null-terminated filename */的大小是特别指定的,因为PATH_MAX = 255。(或者更准确地说,由于readdir大小的限制,PATH_MAX是255。)

此外,允许chdir(2)或open(2)等系统调用在比PATH_MAX (ENAMETOOLONG)更长的路径上失败:

ENAMETOOLONG

路径名或路径名的组成部分太长。

readlink(2)采用缓冲区大小,因此它不需要限制链接目标的长度;它只提到ENAMETOOLONG是您提供的路径中可能出现的错误,而不是链接名称。

即使在现代Linux上,单个文件名的255个字节也是一个硬限制。但IIRC它确实选择允许更长的路径名(具有多个目录组件)。

票数 5
EN

Stack Overflow用户

发布于 2019-07-07 18:06:01

避免假设$PATH已定义或长度有限是您问题的解决方案,并使用如下所示的通用代码。

代码语言:javascript
复制
char *path = NULL; 
  const char *temp = getenv("PATH");
  if (temp != NULL) {
    path = (char*) malloc(strlen(temp) + 1);
    if (path == NULL) {
      /* Handle error condition */
    } else {
      strcpy(path, temp);
    }
    /* Use path */
  }
票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/56921129

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档