Skip site navigation (1)Skip section navigation (2)
Date:      Tue, 2 Mar 2010 04:31:59 GMT
From:      Garrett Cooper <gcooper@FreeBSD.org>
To:        freebsd-gnats-submit@FreeBSD.org
Subject:   bin/144411: mtree(8) doesn't reject non-regular files for -X
Message-ID:  <201003020431.o224VxH1008729@www.freebsd.org>
Resent-Message-ID: <201003020440.o224e28h019402@freefall.freebsd.org>

next in thread | raw e-mail | index | archive | help

>Number:         144411
>Category:       bin
>Synopsis:       mtree(8) doesn't reject non-regular files for -X
>Confidential:   no
>Severity:       non-critical
>Priority:       medium
>Responsible:    freebsd-bugs
>State:          open
>Quarter:        
>Keywords:       
>Date-Required:
>Class:          sw-bug
>Submitter-Id:   current-users
>Arrival-Date:   Tue Mar 02 04:40:02 UTC 2010
>Closed-Date:
>Last-Modified:
>Originator:     Garrett Cooper
>Release:        RELENG_8
>Organization:
Cisco Systems, Inc
>Environment:
FreeBSD garrcoop-fbsd.cisco.com 8.0-STABLE FreeBSD 8.0-STABLE #2: Wed Feb  3 16:57:07 PST 2010     garrcoop@garrcoop-fbsd.cisco.com:/usr/obj/usr/src/sys/LAPPY_X86  i386
>Description:
Didn't fully read the manpage for mtree(8), and I assumed that -X accepted exclusion arguments like tar does.

Turns out that wasn't the case, and mtree hangs when given directories via -X:

[root@garrcoop-fbsd /usr/home/garrcoop/head/tools/regression/lib/libc/gen]# mtree -X /boot/
^C

The patch attached does a stat(2) on the file first to ensure that the resolved file is in fact legitimate, then proceeds to poke at the file to make sure that it's a regular file.

This is a draft patch and can and will be revised if necessary..
>How-To-Repeat:
mtree -X /boot
>Fix:
See proposed patch attached.

Patch attached with submission follows:

Index: excludes.c
===================================================================
--- excludes.c	(revision 204532)
+++ excludes.c	(working copy)
@@ -31,6 +31,7 @@
 __FBSDID("$FreeBSD$");
 
 #include <sys/types.h>
+#include <sys/stat.h>
 #include <sys/time.h>		/* XXX for mtree.h */
 #include <sys/queue.h>
 
@@ -39,6 +40,7 @@
 #include <fts.h>
 #include <stdio.h>
 #include <stdlib.h>
+#include <errno.h>
 
 #include "mtree.h"		/* XXX for extern.h */
 #include "extern.h"
@@ -66,10 +68,23 @@
 	FILE *fp;
 	char *line, *str;
 	struct exclude *e;
+	struct stat exclude_stat;
 	size_t len;
 
+	/* Let's resolve the name via stat(2) so symlinks to files pass. */
+	if (stat(name, &exclude_stat) < 0) {
+		err(1, "%s", name);
+	}
+	/* Don't let certain files like directories, fifos, etc pass. */
+	if (!S_ISREG(exclude_stat.st_mode)) {
+		/* Make the error message make sense for the directory error
+		 * case. All other values can be EINVAL. */
+		errno = S_ISDIR(exclude_stat.st_mode) ? EISDIR : EINVAL;
+		err(1, "%s", name);
+	}
+
 	fp = fopen(name, "r");
-	if (fp == 0)
+	if (fp == NULL)
 		err(1, "%s", name);
 
 	while ((line = fgetln(fp, &len)) != 0) {


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



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201003020431.o224VxH1008729>