你可能知道有一个auditdistd(8)
FreeBSD 上可用的守护进程。它有一些记录的命令行参数,如-c
、-d
等(查看更多这里(链接))。
当我偶然发现处理未记录的命令行参数的代码时,我试图了解它是如何工作的proto
:
显然,
proto_exec
在执行时被调用/usr/sbin/auditdistd proto foo bar baz
并foo bar baz
作为参数传递给函数。/* * We are executed from proto to create sandbox. */ if (argc > 1 && strcmp(argv[1], "proto") == 0) { argc -= 2; argv += 2; if (proto_exec(argc, argv) == -1) err(EX_USAGE, "Unable to execute proto"); }
(看
/contrib/openbsm/bin/auditdistd/auditdistd.c:main()
(关联)更多细节。)这是
proto_exec
函数:int proto_exec(int argc, char *argv[]) { struct proto *proto; int error; if (argc == 0) { errno = EINVAL; return (-1); } TAILQ_FOREACH(proto, &protos, prt_next) { if (strcmp(proto->prt_name, argv[0]) == 0) break; } if (proto == NULL) { errno = EINVAL; return (-1); } if (proto->prt_exec == NULL) { errno = EOPNOTSUPP; return (-1); } error = proto->prt_exec(argc, argv); if (error != 0) { errno = error; return (-1); } /* NOTREACHED */ return (0); }
(看
/contrib/openbsm/bin/auditdistd/proto.c:proto_exec()
(关联)更多细节。)老实说,我不明白这里发生了什么。
该
protos
变量的初始化如下:static TAILQ_HEAD(, proto) protos = TAILQ_HEAD_INITIALIZER(protos);
当
/usr/sbin/auditdistd proto foo
被调用时它只是说:auditdistd:无法执行原型:参数无效
有谁知道这个选项是什么以及如何使用它?
答案1
Auditdistd 使用沙箱。为了确保从父进程到子进程没有内存泄漏,它不仅执行 fork(2)ing,还执行auditdistd 二进制文件。传递“proto”参数是为了让新执行的命令知道它是一个子进程。
答案2
据我了解,auditdistd
用于__attribute__((constructor))
初始化某些结构(参见具体如何__attribute__((constructor))
运作?更多细节)。
结果是、和结构protos
的 TAILQ 。tls
uds
tcp
proto
现在这个谜团已经解开了——protos
它是由那些proto
用该功能初始化的结构组成的__attribute__((constructor))
。