Notes |
(0002070)
vda
01-29-07 17:00
|
Works for me:
# cat busybox-1.4.1.tar | ./busybox tar t | head -10
busybox-1.4.1/
busybox-1.4.1/loginutils/
busybox-1.4.1/loginutils/su.c
busybox-1.4.1/loginutils/Kbuild
busybox-1.4.1/loginutils/adduser.c
busybox-1.4.1/loginutils/login.c
busybox-1.4.1/loginutils/passwd.c
busybox-1.4.1/loginutils/getty.c
busybox-1.4.1/loginutils/deluser.c
busybox-1.4.1/loginutils/vlock.c
Your .config, libc, gcc version? Strace output of "busybox tar t"? |
|
(0002076)
espakman
01-30-07 11:30
|
My config is attached.
Libc: uClibc-0.9.28
gcc: gcc-3.3.3
Strace:
# strace ./busybox tar -t
execve("./busybox", ["./busybox", "tar", "-t"], [/* 26 vars */]) = 0
old_mmap(NULL, 20, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x40005000
open("/root/Bering/src/bering-uclibc/buildtool/staging/lib/libcrypt.so.0", O_RDONLY) = 3
old_mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x40006000
read(3, "\177ELF\1\1\1\0\0\0\0\0\0\0\0\0\3\0\3\0\1\0\0\0\224\4\0"..., 4096) = 4096
old_mmap(NULL, 81920, PROT_NONE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x40007000
old_mmap(0x40007000, 7798, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_FIXED, 3, 0) = 0x40007000
old_mmap(0x40009000, 184, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED, 3, 0x2000) = 0x40009000
old_mmap(0x4000a000, 67036, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS, -1, 0) = 0x4000a000
close(3) = 0
munmap(0x40006000, 4096) = 0
open("/root/Bering/src/bering-uclibc/buildtool/staging/lib/libc.so.0", O_RDONLY) = 3
old_mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x40006000
read(3, "\177ELF\1\1\1\0\0\0\0\0\0\0\0\0\3\0\3\0\1\0\0\0\360\316"..., 4096) = 4096
old_mmap(NULL, 266240, PROT_NONE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x4001b000
old_mmap(0x4001b000, 239528, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_FIXED, 3, 0) = 0x4001b000
old_mmap(0x40056000, 3616, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED, 3, 0x3b000) = 0x40056000
old_mmap(0x40057000, 19192, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS, -1, 0) = 0x40057000
close(3) = 0
munmap(0x40006000, 4096) = 0
ioctl(0, SNDCTL_TMR_TIMEBASE or TCGETS, {B38400 opost isig icanon echo ...}) = 0
ioctl(1, SNDCTL_TMR_TIMEBASE or TCGETS, {B38400 opost isig icanon echo ...}) = 0
getuid() = 0
getgid() = 0
setgid(0) = 0
setuid(0) = 0
brk(0) = 0x808dea0
brk(0x808eea0) = 0x808eea0
brk(0x808f000) = 0x808f000
--- SIGSEGV (Segmentation fault) @ 0 (0) ---
+++ killed by SIGSEGV +++ |
|
(0002087)
espakman
02-03-07 03:12
|
A small update, the segfault still exists with today's snapshot. |
|
(0002089)
vda
02-03-07 06:34
|
With uclibc this enters infinite loop in exit():
int main() {
gethostbyname("127.0.0.1");
exit(1);
}
This does the same, with or without second fclose:
int main() {
FILE* fp;
char buf[4*1024];
fp = fopen("/etc/resolv.conf", "r");
fclose(fp);
fp = fopen("/etc/hosts", "r");
// fclose(fp);
exit(1);
}
If even this can't work, all bets are off.
uclibc mailing list and maintainer were informed. Twice. |
|
(0002090)
espakman
02-03-07 06:56
|
Bad.... but I don't see a call to networking code in tar.c. I will patch uClibc with the code you propose anyway and report back.
The strange thing is that tar -t with busybox-1.2.1 and uClibc-0.9.28 did work correct... |
|
(0002091)
espakman
02-03-07 16:05
|
It looks like the "gethostbyname" problem only exists with the SVN versions of uCLibc, 0.9.28 seems to work ok.
But maybe I missed the irony and you were just saying that uClibc is buggy ;-) |
|
(0002095)
espakman
02-04-07 06:02
|
I get the same segfault with busybox compiled against glibc and attached config.
gcc version 3.3.4
glibc version 2.3.4
# cat busybox-snapshot.tar | ./busybox tar t
Segmentation fault
The option which triggers the segfault is "FEATURE_TAR_FROM"
Busybox version 1.2.2.1 works ok, 1.3.0 segfaults.
Strace (on glibc):
# strace ./busybox tar -t
execve("./busybox", ["./busybox", "tar", "-t"], [/* 26 vars */]) = 0
brk(0) = 0x808dc00
access("/etc/ld.so.preload", R_OK) = -1 ENOENT (No such file or directory)
open("/etc/ld.so.cache", O_RDONLY) = 3
fstat64(3, {st_mode=S_IFREG|0644, st_size=11778, ...}) = 0
old_mmap(NULL, 11778, PROT_READ, MAP_PRIVATE, 3, 0) = 0x40017000
close(3) = 0
open("/lib/libcrypt.so.1", O_RDONLY) = 3
read(3, "\177ELF\1\1\1\0\0\0\0\0\0\0\0\0\3\0\3\0\1\0\0\0P\10\0\000"..., 512) = 512
fstat64(3, {st_mode=S_IFREG|0755, st_size=25168, ...}) = 0
old_mmap(NULL, 184636, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_DENYWRITE, 3, 0) = 0x4001a000
old_mmap(0x4001f000, 8192, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x4000) = 0x4001f000
old_mmap(0x40021000, 155964, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS, -1, 0) = 0x40021000
close(3) = 0
open("/lib/libc.so.6", O_RDONLY) = 3
read(3, "\177ELF\1\1\1\0\0\0\0\0\0\0\0\0\3\0\3\0\1\0\0\0 U\1\000"..., 512) = 512
fstat64(3, {st_mode=S_IFREG|0755, st_size=1357414, ...}) = 0
old_mmap(NULL, 1166612, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_DENYWRITE, 3, 0) = 0x40048000
mprotect(0x4015e000, 27924, PROT_NONE) = 0
old_mmap(0x4015f000, 16384, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x116000) = 0x4015f000
old_mmap(0x40163000, 7444, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS, -1, 0) = 0x40163000
close(3) = 0
old_mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x40165000
mprotect(0x4015f000, 4096, PROT_READ) = 0
munmap(0x40017000, 11778) = 0
getuid32() = 0
getgid32() = 0
setgid32(0) = 0
setuid32(0) = 0
brk(0) = 0x808dc00
brk(0x80aec00) = 0x80aec00
brk(0x80af000) = 0x80af000
--- SIGSEGV (Segmentation fault) @ 0 (0) ---
+++ killed by SIGSEGV +++ |
|
(0002096)
vda
02-04-07 08:16
|
In your strace I don't see any reads from stdin. This means that SEGV will happen even if you don't pipe tarfile to stdin. Just
# ./busybox tar t
will SEGV. I fear you will need to diagnose it further because I cannot reproduce it on glibc 2.4. Can you insert 'printf("I AM HERE\n")' in tar.c and rerun 'tar t' until you find where exactly it happens?
Start here:
if (ENABLE_FEATURE_TAR_FROM) {
tar_handle->reject = ...
/* Append excludes to reject */
while (excludes) {
llist_t *temp = excludes->link;
excludes->link = tar_handle->reject;
tar_handle->reject = excludes;
excludes = temp;
}
tar_handle->accept = ...
} |
|
(0002114)
espakman
02-04-07 10:15
|
It segfaults after "i am here", it doesn't reach "i am here2".
If I comment out the while (cur) {, it segfaults after "i am here2".
#if ENABLE_FEATURE_TAR_FROM
static llist_t *append_file_list_to_list(llist_t *list)
{
FILE *src_stream;
llist_t *cur = list;
llist_t *tmp;
char *line;
llist_t *newlist = NULL;
printf("i am here\n");
while (cur) {
printf("i am here2\n");
src_stream = xfopen(cur->data, "r");
printf("i am here3\n");
tmp = cur;
printf("i am here4\n");
cur = cur->link;
free(tmp);
while ((line = xmalloc_getline(src_stream)) != NULL) { |
|
(0002115)
espakman
02-04-07 11:54
|
Actually it happens a bit earlier, "list" is probably NULL in my test so the while loop is not entered in the previous code snippet.
It segfaults on "llist_t *temp = excludes->link;"
if (ENABLE_FEATURE_TAR_FROM) {
tar_handle->reject = append_file_list_to_list(tar_handle->reject);
/* Append excludes to reject */
printf("I am here\n");
while (excludes) {
printf("I am here2\n");
llist_t *temp = excludes->link;
printf("I am here3\n");
excludes->link = tar_handle->reject;
tar_handle->reject = excludes;
excludes = temp;
}
tar_handle->accept = append_file_list_to_list(tar_handle->accept);
} |
|
(0002116)
vda
02-04-07 12:44
|
Looks like &exclude is misplaced in getopt32 - should be placed after &verboseFlag, like this:
opt = getopt32(argc, argv,
"txC:f:Opvk"
USE_FEATURE_TAR_CREATE( "ch" )
USE_FEATURE_TAR_BZIP2( "j" )
USE_FEATURE_TAR_LZMA( "a" )
USE_FEATURE_TAR_FROM( "T:X:")
USE_FEATURE_TAR_GZIP( "z" )
USE_FEATURE_TAR_COMPRESS("Z" )
, &base_dir // -C dir
, &tar_filename // -f filename
USE_FEATURE_TAR_FROM(, &(tar_handle->accept)) // T
USE_FEATURE_TAR_FROM(, &(tar_handle->reject)) // X
, &verboseFlag // combined count for -t and -v
, &verboseFlag // combined count for -t and -v
===> USE_FEATURE_TAR_FROM(, &excludes ) // --exclude
);
Please test this. |
|
(0002117)
espakman
02-04-07 13:09
|
Yes, that did it!
# cat busybox-snapshot.tar | ./busybox tar -t | head -10
busybox/
busybox/.svn/
busybox/.svn/text-base/
busybox/.svn/text-base/AUTHORS.svn-base
busybox/.svn/text-base/Makefile.custom.svn-base
busybox/.svn/text-base/.indent.pro.svn-base
busybox/.svn/text-base/INSTALL.svn-base
busybox/.svn/text-base/Makefile.svn-base
busybox/.svn/text-base/LICENSE.svn-base
busybox/.svn/text-base/README.svn-base |
|
(0002118)
vda
02-04-07 13:32
|
Fixed in rev 17772.
NB: my guess that &exclude is misplaced was actually wrong. It is more complex than that, so please test & reopen bug if svn is still doesn't work for you. |
|