From nobody@FreeBSD.org  Thu May 24 01:48:07 2012
Return-Path: <nobody@FreeBSD.org>
Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34])
	by hub.freebsd.org (Postfix) with ESMTP id 5998B106566B
	for <freebsd-gnats-submit@FreeBSD.org>; Thu, 24 May 2012 01:48:07 +0000 (UTC)
	(envelope-from nobody@FreeBSD.org)
Received: from red.freebsd.org (red.freebsd.org [IPv6:2001:4f8:fff6::22])
	by mx1.freebsd.org (Postfix) with ESMTP id 449368FC0A
	for <freebsd-gnats-submit@FreeBSD.org>; Thu, 24 May 2012 01:48:07 +0000 (UTC)
Received: from red.freebsd.org (localhost [127.0.0.1])
	by red.freebsd.org (8.14.4/8.14.4) with ESMTP id q4O1m7O8047095
	for <freebsd-gnats-submit@FreeBSD.org>; Thu, 24 May 2012 01:48:07 GMT
	(envelope-from nobody@red.freebsd.org)
Received: (from nobody@localhost)
	by red.freebsd.org (8.14.4/8.14.4/Submit) id q4O1m6c8047094;
	Thu, 24 May 2012 01:48:06 GMT
	(envelope-from nobody)
Message-Id: <201205240148.q4O1m6c8047094@red.freebsd.org>
Date: Thu, 24 May 2012 01:48:06 GMT
From: Garrett Cooper <yaneurabeya@gmail.com>
To: freebsd-gnats-submit@FreeBSD.org
Subject: [patch] [pkg_install] fix memory leaks and potential CPU burning in lib/plist.c:delete_hierarchy
X-Send-Pr-Version: www-3.1
X-GNATS-Notify:

>Number:         168289
>Category:       bin
>Synopsis:       [patch] pkg_install(8): fix memory leaks and potential CPU burning in lib/plist.c:delete_hierarchy
>Confidential:   no
>Severity:       non-critical
>Priority:       low
>Responsible:    freebsd-bugs
>State:          closed
>Quarter:        
>Keywords:       
>Date-Required:  
>Class:          sw-bug
>Submitter-Id:   current-users
>Arrival-Date:   Thu May 24 01:50:01 UTC 2012
>Closed-Date:    Thu Mar 27 05:32:20 CDT 2014
>Last-Modified:  Thu Mar 27 05:32:20 CDT 2014
>Originator:     Garrett Cooper
>Release:        9-STABLE
>Organization:
EMC Isilon
>Environment:
FreeBSD forza.west.isilon.com 9.0-STABLE FreeBSD 9.0-STABLE #4 r235133: Mon May  7 10:31:22 PDT 2012     root@forza.isilon.com:/usr/obj/usr/src/sys/FORZA  amd64
>Description:
A case was noted internally where input in delete_hierarchy could leak memory and burn CPU cycles when trying to delete a directory hierarchy with two or more contiguous slashes next to them. Example of the CPU burning is as follows:

$ cat ~/infinite_plist.c
#include <libgen.h>
#include <stdio.h>
#include <string.h>

int
main(void)
{
        char *paths[] = {
                "foo//bar",
                "/root/foo.bar",
                "///root/foo.bar/baz",
                "a.b.c.d",
        };
        char *cp1, *cp2;
        int i;

#ifdef STUCK
        for (i = 0; i < sizeof(paths)/sizeof(paths[0]); i++) {
                cp1 = cp2 = strdup(paths[i]);
                printf("%s... ", cp2);
                fflush(stdout);
                while (cp2) {
                        if ((cp2 = strrchr(cp1, '/')) != NULL)
                                *cp2 = '\0';
                        if (cp2)
                                cp1 = strdup(paths[0]);
                }
        }
#else
        for (i = 0; i < sizeof(paths)/sizeof(paths[0]); i++) {
                cp1 = paths[i];
                for (;;) {
                        if ((cp2 = dirname(cp2)) == NULL || strcmp("/", cp2) == 0 || strcmp(".", cp2) == 0)
                                break;
                }
                printf("%s: %s\n", paths[i], cp2);
        }
#endif
        return (0);
}
$ gcc -DSTUCK -o ~/infinite_plist ~/infinite_plist.c 
$ ~/infinite_plist 
foo//bar... ^C
$ gcc -o ~/infinite_plist ~/infinite_plist.c 
$ ~/infinite_plist 
foo//bar: .
/root/foo.bar: .
///root/foo.bar/baz: .
a.b.c.d: .
$

Reported by Miles Ohlrich <miles.ohlrich!AT-SPAMFREE!isilon.com> (replace !AT-SPAMFREE! with '@').
>How-To-Repeat:
Call delete_hierarchy with dir == "/usr/local//foo-1.0", or trigger any of the error conditions with the file hierarchy tests.
>Fix:


Patch attached with submission follows:

Index: usr.sbin/pkg_install/lib/plist.c
===================================================================
--- usr.sbin/pkg_install/lib/plist.c	(revision 235484)
+++ usr.sbin/pkg_install/lib/plist.c	(working copy)
@@ -23,6 +23,7 @@
 
 #include "lib.h"
 #include <err.h>
+#include <libgen.h>
 #include <md5.h>
 
 /* Add an item to a packing list */
@@ -548,9 +549,8 @@
 int
 delete_hierarchy(const char *dir, Boolean ign_err, Boolean nukedirs)
 {
-    char *cp1, *cp2;
+    char *cp;
 
-    cp1 = cp2 = strdup(dir);
     if (!fexists(dir) && !issymlink(dir)) {
 	if (!ign_err)
 	    warnx("%s '%s' doesn't exist",
@@ -572,21 +572,21 @@
 
     if (!nukedirs)
 	return 0;
-    while (cp2) {
-	if ((cp2 = strrchr(cp1, '/')) != NULL)
-	    *cp2 = '\0';
-	if (!isemptydir(dir))
-	    return 0;
-	if (RMDIR(dir) && !ign_err) {
-	    if (!fexists(dir))
-		warnx("directory '%s' doesn't exist", dir);
-	    else
-		return 1;
+
+    cp = (char*)dir;
+    for (;;) {
+	if ((cp = dirname(cp)) == NULL)
+	    return 1;
+	if (strcmp("/", cp) == 0 || strcmp(".", cp) == 0)
+	    break;
+	if (!isemptydir(cp))
+	    break;
+	if (RMDIR(cp) && !ign_err) {
+	    if (!fexists(cp))
+		warnx("directory '%s' doesn't exist", cp);
+	    return 1;
 	}
-	/* back up the pathname one component */
-	if (cp2) {
-	    cp1 = strdup(dir);
-	}
     }
+
     return 0;
 }


>Release-Note:
>Audit-Trail:
State-Changed-From-To: open->closed 
State-Changed-By: bdrewery 
State-Changed-When: Thu Mar 27 05:32:19 CDT 2014 
State-Changed-Why:  
pkg_install is gone from head 

http://www.freebsd.org/cgi/query-pr.cgi?pr=168289 
>Unformatted:
