Python 2.6 subprocess.call()似乎触发了Perl的污点检查。如何解决?

2 投票
2 回答
1443 浏览
提问于 2025-04-15 11:59

我发现Python中的subprocess.call()和os.system()在行为上有些奇怪的不同,这似乎和setgid有关。这个区别导致在使用subprocess.call()时会触发Perl的污染检查,这就麻烦了,因为我无法修改所有需要添加去污染代码的Perl脚本。

举个例子,"process.py"

#!/usr/bin/python

import os, subprocess

print "Python calling os.system"
os.system('perl subprocess.pl true')
print "Python done calling os.system"
print "Python calling subprocess.call"
subprocess.call(['perl', 'subprocess.pl', 'true'])
print "Python done calling subprocess.call"

"subprocess.pl"

#!/usr/bin/perl

print "perl subprocess\n";
`$ARGV[0]`;
print "perl subprocess done\n";

输出结果 - 两次运行subprocess.pl的结果应该是一样的,但使用subprocess.call()运行的那次却出现了污染错误:

mybox> process.py
Python calling os.system
perl subprocess
perl subprocess done
Python done calling os.system
Python calling subprocess.call
perl subprocess
Insecure dependency in `` while running setgid at subprocess.pl line 4.
Python done calling subprocess.call
mybox>

虽然使用os.system()可以正常工作,但我更希望使用subprocess.check_call(),因为它更向前兼容,并且有很好的检查功能。

有没有什么建议或者文档可以解释这两者之间的不同?这可能是我本地的unix环境中某个奇怪的设置导致的这些行为吗?

2 个回答

0

对我来说没有这个问题:

$ python proc.py
Python calling os.system
perl subprocess
perl subprocess done
Python done calling os.system
Python calling subprocess.call
perl subprocess
perl subprocess done
Python done calling subprocess.call

$ python --version
Python 2.5.2

$ perl --version
This is perl, v5.8.8 built for i486-linux-gnu-thread-multi

你的版本号是什么?

你是在什么样的账户下运行的?

编辑:

抱歉,我没注意到标题 - 我这边没有方便访问的python 2.6,所以我得先放下这个问题。

编辑:

看起来我们找到了问题所在 - 是python 2.6的二进制文件上有sgid权限。

如果用shell的subprocess也能避免这个问题,那就更有意思了。

2

我觉得你的错误可能和perl有关,或者是它和你的环境之间的互动出了问题。你的反引号(backtick)进程出于某种原因在调用setgid。我要复现这个问题,唯一的方法就是把/usr/bin/perl的权限设置为setgid(-rwxr-sr-x)。[编辑] 发现把python也设置为setgid也会出现这个问题!

[编辑] 我忘了提到os.system对你是有效的。我认为这里唯一相关的区别是,使用os.system时,子进程并不会继承环境变量。你可以检查一下每个子进程的环境,可能会找到问题的根源。

撰写回答