【发布时间】:2018-09-06 10:58:19
【问题描述】:
RHEL6
在 C 中,如何通过包含 execvp 来运行 perl 可执行文件? (这是一种在污点模式开启时将缺失的 PERL5LIB 翻译替换为 @INC 的方法)
这个问题正在寻找由 mob 提供的答案的有效实现... Why does @INC change when setgid-bit of C wrapper around perl script change?.
我在一个使用 execvp 调用 perl 的 C 程序中包装了一个 perl 脚本执行。因为启用了污点模式,@INC 将不会加载 $PERL5LIB 的内容,所以我使用“-I”将路径传递给 perl 可执行文件。 perlsec 说这是可能的(参考 mob 在上面的注释中提供的答案)。
我这样做的尝试失败了。我的 C 程序尝试将 perl 可执行文件作为第一个参数运行到 execvp,然后将 perl 脚本作为参数列表的一部分。这些包含已成为 perl 脚本可执行语句的一部分。这是示例...
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main(int argc, char *argv[])
{
char **args; /*args will be passed to execvp. prepend perl executable*/
args=malloc(3*sizeof(char*));
args[0]=malloc(sizeof("/tools/bin/perl -I/proj/perlmods")+1);
strcpy(args[0],"/tools/bin/perl -I/proj/perlmods");
args[1]=malloc(sizeof("/home/me/the.pl")+1);
strcpy(args[1],"/home/me/the.pl");
args[2]=NULL;
execvp("/tools/bin/perl",args);
}
perl 脚本很简单……
use html_mail;
print "In my.pl\n";
exit;
/proj/perlmods 有 html_mail.pm
在 linux 提示符下使用 -I works 直接执行 perl...
% /tools/bin/perl -I /proj/perlmods /home/me/my.pl
In my.pl
但运行 C 二进制文件不会。它抱怨找不到 perl 模块。但是,如果将 /proj/perlmods 放在 PERL5LIB 中,那么它确实可以工作。所以我认为 args 就 args[1] 中的 perl 脚本而言是好的。
我相信我放入 args 的 include 语句被忽略了。如果我将它作为后缀粘贴到 execvp 中的 perl 可执行调用...
execvp("/tools/bin/perl -I /proj/perlmods",args);
...C 程序失败,所以我认为它不属于那里。如果我将包含作为 perl 脚本调用的一部分....
strcpy(args[1],"/home/me/the.pl -I /proj/perlmods");
...它失败了。如果我将它作为 args (args[3]) 的新元素添加,它只是作为 arg 传递给 perl 脚本并且没有任何影响。
我查看了 execvpe,但这看起来只是一种设置环境变量的方法。
问题是,如何实际将包含信息传递给 execvp?
【问题讨论】:
-
如果
execvp失败,则设置errno。在execvp之后添加perror("execvp")以查看失败的原因。 -
还要注意
sizeof("/home/me/the.pl") == strlen("/home/me/the.pl") + 1,因为"/home/me/the.pl"是一个字符串字面量。