>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     
garrc...@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:

[r...@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:
_______________________________________________
freebsd-bugs@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-bugs
To unsubscribe, send any mail to "freebsd-bugs-unsubscr...@freebsd.org"

Reply via email to