bin/144411: mtree(8) doesn't reject non-regular files for -X
Garrett Cooper
gcooper at FreeBSD.org
Tue Mar 2 04:40:03 UTC 2010
>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 at 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 at 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:
More information about the freebsd-bugs
mailing list