Debian 下 copendir 的安全性
名称澄清
安全性结论
常见风险与防护要点
最小示例
#include <stdio.h>
#include <stdlib.h>
#include <dirent.h>
#include <string.h>
#include <errno.h>
#include <sys/stat.h>
#include <limits.h>
// 将 path 规约并校验是否位于 base 之下
static int is_safe_path(const char *base, const char *path) {
char rbase[PATH_MAX], rpath[PATH_MAX];
if (!realpath(base, rbase) || !realpath(path, rpath)) return 0;
return strncmp(rbase, rpath, strlen(rbase)) == 0;
}
int main(int argc, char *argv[]) {
if (argc != 2) { fprintf(stderr, "Usage: %s <dir>\n", argv[0]); return 1; }
if (!is_safe_path(".", argv[1])) {
fputs("Invalid path\n", stderr);
return 1;
}
DIR *dir = opendir(argv[1]);
if (!dir) { perror("opendir"); return 1; }
struct dirent *entry;
// 注意:readdir 非线程安全;多线程请使用 readdir_r 或加锁
while ((entry = readdir(dir)) != NULL) {
if (strcmp(entry->d_name, ".") == 0 || strcmp(entry->d_name, "..") == 0) continue;
printf("%s\n", entry->d_name);
}
if (closedir(dir) == -1) { perror("closedir"); return 1; }
return 0;
}