CPIO是一种归档文件格式,在概念上类似于ZIP或TAR。它将多个文件(我称之为“成员文件”)组合到一个.cpio存档文件中。这是一种旧格式,设计用于磁带驱动器。
下面是一个使用Unix shell和GNU cpio实用程序的演示。我们将创建一些用于测试的文件:
现在我们将执行相同的操作,但是增加了一个名为“trailer!”的成员文件,该文件在我们的文件名列表中将在TB和TZ之间排序。
$ECHO x&>;#39;尾部!!';$ls T*>;文件列表2$cpio-o--详细<;文件列表2>;gnu2.cpioTATBTRAILER!TZ1块。
最后两份文件不见了!我们也无法提取它们。“预告片!”文件及其之后的所有文件确实存在于gnu2.cpio文件中,但是它们对于cpio实用程序是不可见的。
我还测试了cpio的其他一些实现,包括afio和libarchive软件中的bsdcpio实用程序。他们也有同样的问题,因为他们无法阅读自己写的某些档案。
问题是cpio格式使用一个特殊的伪文件,其前哨名称为“trailer!”来标记档案的结束。某种结束标记很重要,但我认为公平地说,这是一种相当愚蠢的方式。
从理论上讲,这个问题可能会有安全影响。想象一下,在服务器上,一个不受信任的用户创建了一个名为“trailer!”的文件。这会扰乱服务器的备份。但它在现实中不太可能被利用,因为:
在真正的cpio备份中,文件名几乎肯定会包含目录路径。文件名为“/home/alice/trailer!”或“WWW/UPLOADS/ALICE/TRAILER!”与哨值不匹配,并且是无害的(至少对于我测试的cpio软件是这样)。
不可见文件安全地存储在存档中。这只需要一些额外的努力来提取它们。
似乎很有可能编写一个cpio提取器,它可以启发式地检测名为“trailer!”的项目是否。是真正的文件,而不是存档结束标记。例如,如果文件模式或信息节点属性不为零,则它可能是真正的成员文件。或者,如果它不是cpio文件中的最后一项,那么它可能是一个真正的成员文件。但是cpio不是一种非常严格的格式,它有几种不同的风格,不同的cpio实用程序编写的预告片记录彼此略有不同。您不能使用的一个启发式方法是假设如果它的大小不是零,那么它一定是一个真实的文件。一些cpio实用程序总是将预告片的“文件大小”设置为零,但另一些cpio实用程序将填充数据放入其中,从而使其大小不为零。