bin/136419: [regression] pkg_add segfault on adding package when it's a broken symlink

pluknet pluknet at gmail.com
Tue Jul 7 11:20:02 UTC 2009


>Number:         136419
>Category:       bin
>Synopsis:       [regression] pkg_add segfault on adding package when it's a broken symlink
>Confidential:   no
>Severity:       non-critical
>Priority:       low
>Responsible:    freebsd-bugs
>State:          open
>Quarter:        
>Keywords:       
>Date-Required:
>Class:          sw-bug
>Submitter-Id:   current-users
>Arrival-Date:   Tue Jul 07 11:20:01 UTC 2009
>Closed-Date:
>Last-Modified:
>Originator:     pluknet
>Release:        6.4-RELEASE-p5
>Organization:
>Environment:
world and kernel are in sync
>Description:
pkg_add coredumps in strdup() on adding package which is a broken symlink.
Symlink is a sort of foo -> bar/baz, where bar doesn't exists.

# file /usr/sbin/pkg_add 
/usr/sbin/pkg_add: ELF 32-bit LSB executable, Intel 80386, version 1 (FreeBSD), for FreeBSD 6.4, dynamically linked (uses shared libs), FreeBSD-style, stripped
>How-To-Repeat:
Add package: pkg_add cannot process properly a broken symlink.

# pkg_add /usr/local/src/packages/p5-IO-Tty-1.08.tbz 
Segmentation fault (core dumped)
# ls -l /usr/local/src/packages/p5-IO-Tty-1.08.tbz 
lrwxr-xr-x  1 root  wheel  34 Jul  6 18:34 /usr/local/src/packages/p5-IO-Tty-1.08.tbz -> ../packages-6.4/p5-IO-Tty-1.08.tbz
# ls /usr/local/src/
packages
# ./pkg_add /usr/local/src/packages/p5-IO-Tty-1.08.tbz 
Segmentation fault (core dumped)
# gdb ./pkg_add pkg_add.core
[...]
#0  0x28262ff0 in strdup () from /lib/libc.so.6
(gdb) bt
#0  0x28262ff0 in strdup () from /lib/libc.so.6
#1  0x0804a1d3 in real_main (argc=0, argv=0xbfbfec80) at main.c:245
#2  0x0804d8f4 in main ()
(gdb) f 1
#1  0x0804a1d3 in real_main (argc=0, argv=0xbfbfec80) at main.c:245
245                         pkgs[ch] = strdup(realpath(*argv, temp));
(gdb) list
240                     if (strlcpy(temp, remotepkg, sizeof(temp)) >= sizeof(temp))
241                         errx(1, "package name too long");
242                     pkgs[ch] = strdup(temp);
243                 } else {                    /* expand all pathnames to fullnames */
244                     if (fexists(*argv)) /* refers to a file directly */
245                         pkgs[ch] = strdup(realpath(*argv, temp));
246                     else {          /* look for the file in the expected places */
247                         if (!(cp = fileFindByPath(NULL, *argv))) {
248                             /* let pkg_do() fail later, so that error is reported */
249                             if (strlcpy(temp, *argv, sizeof(temp)) >= sizeof(temp))

>Fix:
Workaround: restore a broken symlink.

# mount -t nfs nfs-server:/path/to/packages-6.4 /usr/local/src/packages-6.4
# ./pkg_add /usr/local/src/packages/p5-IO-Tty-1.08.tbz                 
#

Fix: revert usr.sbin/pkg_install/lib/file.c cvs r1.11 to a lesser bogus access() check. From r1.11 change:
@@ -30,7 +30,8 @@ static const char *rcsid = "$Id: file.c,
 Boolean
 fexists(char *fname)
 {
-    if (!access(fname, F_OK))
+    struct stat dummy;
+    if (!lstat(fname, &dummy))
 	return TRUE;
     return FALSE;
 }

Let's see how fexists() taken from lib/file.c goes on current lstat():

[pluknet at host-156]$ ls -l foo 
lrwxr-xr-x  1 pluknet  pluknet  7  7 июл 14:40 foo -> bar/baz
[pluknet at host-156]$ ls -l bar
ls: bar: No such file or directory
[pluknet at host-156]$ head -21 test.c | tail -12
fexists(const char *fname)
{ 
    struct stat dummy;

    printf("checking %s..\n", fname);
    if (!lstat(fname, &dummy)) {
        printf("looks good\n");
        return 1;
    }
    printf("bad fnpath\n");
    return 0;
} 
[pluknet at host-156]$ ./test foo
checking foo..
looks good
Segmentation fault: 11 (core dumped)

. and on older access() check:

[pluknet at host-156]$ head -21 test.c | tail -12
fexists(const char *fname)
{ 
//    struct stat dummy;

    printf("checking %s..\n", fname);
    if (!access(fname, F_OK)) {
        printf("looks good\n");
        return 1;
    }
    printf("bad fnpath\n");
    return 0;
} 
[pluknet at host-156]$ ./test foo
checking foo..
bad fnpath


>Release-Note:
>Audit-Trail:
>Unformatted:


More information about the freebsd-bugs mailing list