Subject: pkg/21182: pkg_admin segfaulting on Solaris8/sparc
To: None <gnats-bugs@gnats.netbsd.org>
From: None <mezis@free.fr>
List: netbsd-bugs
Date: 04/14/2003 07:46:41
>Number:         21182
>Category:       pkg
>Synopsis:       pkg_admin segfaulting on Solaris8/sparc
>Confidential:   no
>Severity:       serious
>Priority:       low
>Responsible:    pkg-manager
>State:          open
>Class:          sw-bug
>Submitter-Id:   net
>Arrival-Date:   Mon Apr 14 07:47:00 PDT 2003
>Closed-Date:
>Last-Modified:
>Originator:     Julien Letessier
>Release:        current
>Organization:
CLIPS / IMAG
>Environment:
SunOS shasha 5.8 Generic_108528-13 sun4u sparc SUNW,Ultra-5_10
>Description:
Using the bootstrap kit in othersrc/bootstrap-pkgsrc (as of today), 'pkg_admin lsall' and 'pkg_admin lsbest' fail, the former by issuing a segfault, the latter by returning nothing.

Fooling around with GDB showed that the calls to getcwd(3) at lines 488 and 527 of pkg_install/admin/main.c always returned NULL. Solaris' getcwd() seamingly never allocates a buffer when its second argument is zero.

With the below patch applied, the problem vanishes in thin air, allowing me to perform bulk builds (since bsd.bulk.mk is the only place where lsall and lsbest are ever used) !
>How-To-Repeat:
# cd /tmp
# touch foobar-1.0.tgz
# pkg_admin lsall 'foobar>=1.0'
(Segmentation Fault)
# pkg_admin lsbest 'foobar>=1.0'
(Blank line)
>Fix:
Use of a stack buffer for getcwd(3).

Index: pkg_install/admin/main.c
===================================================================
RCS file: /cvsroot/othersrc/bootstrap-pkgsrc/pkg_install/admin/main.c,v
retrieving revision 1.9
diff -u -B -b -w -r1.9 main.c
--- pkg_install/admin/main.c    2003/03/29 18:39:11     1.9
+++ pkg_install/admin/main.c    2003/04/14 14:33:54
@@ -473,7 +473,7 @@
                        /* args specified */
                        int     rc;
                        const char *basep, *dir;
-                       char *cwd;
+                       char cwd[MAXPATHLEN];
                        char base[FILENAME_MAX];
 
                        dir = dirname_of(*argv);
@@ -485,11 +485,10 @@
                        if (rc == -1)
                                err(EXIT_FAILURE, "Cannot chdir to %s", _pkgdb_getPKGDB_DIR());
 
-                       cwd = getcwd(NULL, 0);
+                       getcwd(cwd, MAXPATHLEN);
                        if (findmatchingname(cwd, base, lspattern_fn, cwd) == -1)
                                errx(EXIT_FAILURE, "Error in findmatchingname(\"%s\", \"%s\", ...)",
                                     cwd, base);
-                       free(cwd);
                        
                        argv++;
                }
@@ -511,7 +510,7 @@
                        /* args specified */
                        int     rc;
                        const char *basep, *dir;
-                       char *cwd;
+                       char cwd[MAXPATHLEN];
                        char base[FILENAME_MAX];
                        char *p;
 
@@ -524,13 +523,12 @@
                        if (rc == -1)
                                err(EXIT_FAILURE, "Cannot chdir to %s", _pkgdb_getPKGDB_DIR());
 
-                       cwd = getcwd(NULL, 0);
+                       getcwd(cwd, MAXPATHLEN);
                        p = findbestmatchingname(cwd, base);
                        if (p) {
                                printf("%s/%s\n", cwd, p);
                                free(p);
                        }
-                       free(cwd);
                        
                        argv++;
                }

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