From owner-freebsd-bugs@FreeBSD.ORG Tue Jul 7 11:20:01 2009 Return-Path: Delivered-To: freebsd-bugs@hub.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id F31B91065678 for ; Tue, 7 Jul 2009 11:20:01 +0000 (UTC) (envelope-from gnats@FreeBSD.org) Received: from freefall.freebsd.org (freefall.freebsd.org [IPv6:2001:4f8:fff6::28]) by mx1.freebsd.org (Postfix) with ESMTP id CDAC78FC26 for ; Tue, 7 Jul 2009 11:20:01 +0000 (UTC) (envelope-from gnats@FreeBSD.org) Received: from freefall.freebsd.org (gnats@localhost [127.0.0.1]) by freefall.freebsd.org (8.14.3/8.14.3) with ESMTP id n67BK1J2014247 for ; Tue, 7 Jul 2009 11:20:01 GMT (envelope-from gnats@freefall.freebsd.org) Received: (from gnats@localhost) by freefall.freebsd.org (8.14.3/8.14.3/Submit) id n67BK1QQ014246; Tue, 7 Jul 2009 11:20:01 GMT (envelope-from gnats) Resent-Date: Tue, 7 Jul 2009 11:20:01 GMT Resent-Message-Id: <200907071120.n67BK1QQ014246@freefall.freebsd.org> Resent-From: FreeBSD-gnats-submit@FreeBSD.org (GNATS Filer) Resent-To: freebsd-bugs@FreeBSD.org Resent-Reply-To: FreeBSD-gnats-submit@FreeBSD.org, pluknet Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id 72A50106564A for ; Tue, 7 Jul 2009 11:17:32 +0000 (UTC) (envelope-from nobody@FreeBSD.org) Received: from www.freebsd.org (www.freebsd.org [IPv6:2001:4f8:fff6::21]) by mx1.freebsd.org (Postfix) with ESMTP id 602638FC0A for ; Tue, 7 Jul 2009 11:17:32 +0000 (UTC) (envelope-from nobody@FreeBSD.org) Received: from www.freebsd.org (localhost [127.0.0.1]) by www.freebsd.org (8.14.3/8.14.3) with ESMTP id n67BHVCH072444 for ; Tue, 7 Jul 2009 11:17:31 GMT (envelope-from nobody@www.freebsd.org) Received: (from nobody@localhost) by www.freebsd.org (8.14.3/8.14.3/Submit) id n67BHVNX072443; Tue, 7 Jul 2009 11:17:31 GMT (envelope-from nobody) Message-Id: <200907071117.n67BHVNX072443@www.freebsd.org> Date: Tue, 7 Jul 2009 11:17:31 GMT From: pluknet To: freebsd-gnats-submit@FreeBSD.org X-Send-Pr-Version: www-3.1 Cc: Subject: bin/136419: [regression] pkg_add segfault on adding package when it's a broken symlink X-BeenThere: freebsd-bugs@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: Bug reports List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Tue, 07 Jul 2009 11:20:02 -0000 >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@host-156]$ ls -l foo lrwxr-xr-x 1 pluknet pluknet 7 7 июл 14:40 foo -> bar/baz [pluknet@host-156]$ ls -l bar ls: bar: No such file or directory [pluknet@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@host-156]$ ./test foo checking foo.. looks good Segmentation fault: 11 (core dumped) . and on older access() check: [pluknet@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@host-156]$ ./test foo checking foo.. bad fnpath >Release-Note: >Audit-Trail: >Unformatted: