From nobody@FreeBSD.org  Mon Sep 12 13:28:48 2011
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 01B9E106564A
	for <freebsd-gnats-submit@FreeBSD.org>; Mon, 12 Sep 2011 13:28:48 +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 CBA7B8FC0A
	for <freebsd-gnats-submit@FreeBSD.org>; Mon, 12 Sep 2011 13:28:47 +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 p8CDSlg4081499
	for <freebsd-gnats-submit@FreeBSD.org>; Mon, 12 Sep 2011 13:28:47 GMT
	(envelope-from nobody@red.freebsd.org)
Received: (from nobody@localhost)
	by red.freebsd.org (8.14.4/8.14.4/Submit) id p8CDSl8H081498;
	Mon, 12 Sep 2011 13:28:47 GMT
	(envelope-from nobody)
Message-Id: <201109121328.p8CDSl8H081498@red.freebsd.org>
Date: Mon, 12 Sep 2011 13:28:47 GMT
From: Martin Sugioarto <martin@sugioarto.com>
To: freebsd-gnats-submit@FreeBSD.org
Subject: dump cannot do incremental backups when device name is too long
X-Send-Pr-Version: www-3.1
X-GNATS-Notify:

>Number:         160678
>Category:       bin
>Synopsis:       [patch] dump(8) cannot do incremental backups when device name is too long
>Confidential:   no
>Severity:       non-critical
>Priority:       medium
>Responsible:    mckusick
>State:          closed
>Quarter:        
>Keywords:       
>Date-Required:  
>Class:          sw-bug
>Submitter-Id:   current-users
>Arrival-Date:   Mon Sep 12 13:30:14 UTC 2011
>Closed-Date:    Fri Jan 13 07:12:17 UTC 2012
>Last-Modified:  Sat Jan 14 06:14:36 UTC 2012
>Originator:     Martin Sugioarto
>Release:        FreeBSD-9.0-BETA2
>Organization:
>Environment:
FreeBSD 9.0-BETA2 #0: Wed Sep  7 21:53:50 CEST 2011
>Description:
I've discovered a small bug in dump. When dump reads
the /etc/dumpdates, at the moment the device name in the first column is
restricted to 32 characters.

With todays GEOM implementation, it's easy to make longer device names.

My device is named: "/dev/mirror/encrypted.elig.journal". And it is
written to dumpdates as "/dev/mirror/encrypted.elig.journ". Next time
you use dump, it reads in the truncated device and internally it won't
match the current dump device. The delta won't be calculated and you
will get a level "0" dump again. Additionally, dump writes garbage in
second and third column because of wrong formatting.

>How-To-Repeat:
Create long device names with GEOM. Try dump with level 0 backup and "-u" flag, then a higher level.
>Fix:
It's a pretty trivial fix, because only the format for printf and
sscanf causes the error (attached).

Let me explain the two line patch.

1) The input is extended from 32 to 256 characters.
2) I removed the width formatting from printf. You will get a fixed
column and it's hard to read. I am assuming that dump works correctly
and does not modify the device name anywhere.

Two remarks about the fix.

1) Please note, that fixed column output of /etc/dumpdates is not used anymore. I don't personally know any tools that parse this file, but they could possibly break. On the other hand, it is not possible to support longer file names for devices without breaking this support.

2) Since I don't like this kind of parsing generally (sscanf), you are free
to improve the implementation in these places. I wanted to fix it as
simply as possible this time.

Patch attached with submission follows:

--- /usr/src/sbin/dump/dump.h	2008-05-24 07:20:46.000000000 +0200
+++ dump.h	2011-09-11 10:32:49.000000000 +0200
@@ -171,9 +171,9 @@
     	if (ddatev != NULL) \
 		for (ddp = ddatev[i = 0]; i < nddates; ddp = ddatev[++i])
 
-#define	DUMPOUTFMT	"%-32s %d %s"		/* for printf */
+#define	DUMPOUTFMT	"%s %d %s"		/* for printf */
 						/* name, level, ctime(date) */
-#define	DUMPINFMT	"%32s %d %[^\n]\n"	/* inverse for scanf */
+#define	DUMPINFMT	"%256s %d %[^\n]\n"	/* inverse for scanf */
 
 void	sig(int signo);
 


>Release-Note:
>Audit-Trail:
Responsible-Changed-From-To: freebsd-bugs->mckusick 
Responsible-Changed-By: mckusick 
Responsible-Changed-When: Mon Oct 17 23:15:37 UTC 2011 
Responsible-Changed-Why:  
I will take responsibility for this bug. 

http://www.freebsd.org/cgi/query-pr.cgi?pr=160678 

From: dfilter@FreeBSD.ORG (dfilter service)
To: bug-followup@FreeBSD.org
Cc:  
Subject: Re: bin/160678: commit references a PR
Date: Tue, 18 Oct 2011 18:42:41 +0000 (UTC)

 Author: mckusick
 Date: Tue Oct 18 18:42:26 2011
 New Revision: 226520
 URL: http://svn.freebsd.org/changeset/base/226520
 
 Log:
   The current /etc/dumpdates file restricts device names to 32 characters.
   With the addition of various GEOM layers some device names now exceed
   this length, for example /dev/mirror/encrypted.elig.journal. This
   change expands the field to 53 bytes which brings the /etc/dumpdates
   lines to 80 characters. Exceeding 80 characters makes the /etc/dumpdates
   file much less human readable. A test is added to dump so that it
   verifies that the device name will fit in the 53 character field
   failing the dump if it is too long.
   
   This change has been checked to verify that its /etc/dumpdates file
   is compatible with older versions of dump.
   
   Reported by: Martin Sugioarto <martin@sugioarto.com>
   PR:          kern/160678
   MFC after:   3 weeks
 
 Modified:
   head/sbin/dump/dump.h
   head/sbin/dump/itime.c
 
 Modified: head/sbin/dump/dump.h
 ==============================================================================
 --- head/sbin/dump/dump.h	Tue Oct 18 17:38:25 2011	(r226519)
 +++ head/sbin/dump/dump.h	Tue Oct 18 18:42:26 2011	(r226520)
 @@ -171,9 +171,10 @@ void	putdumptime(void);
      	if (ddatev != NULL) \
  		for (ddp = ddatev[i = 0]; i < nddates; ddp = ddatev[++i])
  
 -#define	DUMPOUTFMT	"%-32s %d %s"		/* for printf */
 +#define	DUMPFMTLEN	53			/* max device pathname length */
 +#define	DUMPOUTFMT	"%-*s %d %s"		/* for printf */
  						/* name, level, ctime(date) */
 -#define	DUMPINFMT	"%32s %d %[^\n]\n"	/* inverse for scanf */
 +#define	DUMPINFMT	"%s %d %[^\n]\n"	/* inverse for scanf */
  
  void	sig(int signo);
  
 
 Modified: head/sbin/dump/itime.c
 ==============================================================================
 --- head/sbin/dump/itime.c	Tue Oct 18 17:38:25 2011	(r226519)
 +++ head/sbin/dump/itime.c	Tue Oct 18 18:42:26 2011	(r226520)
 @@ -222,7 +222,10 @@ static void
  dumprecout(FILE *file, const struct dumpdates *what)
  {
  
 -	if (fprintf(file, DUMPOUTFMT, what->dd_name,
 +	if (strlen(what->dd_name) > DUMPFMTLEN)
 +		quit("Name '%s' exceeds DUMPFMTLEN (%d) bytes\n",
 +		    what->dd_name, DUMPFMTLEN);
 +	if (fprintf(file, DUMPOUTFMT, DUMPFMTLEN, what->dd_name,
  	      what->dd_level, ctime(&what->dd_ddate)) < 0)
  		quit("%s: %s\n", dumpdates, strerror(errno));
  }
 _______________________________________________
 svn-src-all@freebsd.org mailing list
 http://lists.freebsd.org/mailman/listinfo/svn-src-all
 To unsubscribe, send any mail to "svn-src-all-unsubscribe@freebsd.org"
 
State-Changed-From-To: open->patched 
State-Changed-By: mckusick 
State-Changed-When: Fri Oct 21 22:49:35 UTC 2011 
State-Changed-Why:  
A patch has been applied to head. 
It will be MFC'ed after appropriate burnin time. 

http://www.freebsd.org/cgi/query-pr.cgi?pr=160678 

From: dfilter@FreeBSD.ORG (dfilter service)
To: bug-followup@FreeBSD.org
Cc:  
Subject: Re: bin/160678: commit references a PR
Date: Fri, 13 Jan 2012 07:08:37 +0000 (UTC)

 Author: mckusick
 Date: Fri Jan 13 07:08:21 2012
 New Revision: 230047
 URL: http://svn.freebsd.org/changeset/base/230047
 
 Log:
   MFC: 226520
   
   The current /etc/dumpdates file restricts device names to 32 characters.
   With the addition of various GEOM layers some device names now exceed
   this length, for example /dev/mirror/encrypted.elig.journal. This
   change expands the field to 53 bytes which brings the /etc/dumpdates
   lines to 80 characters. Exceeding 80 characters makes the /etc/dumpdates
   file much less human readable. A test is added to dump so that it
   verifies that the device name will fit in the 53 character field
   failing the dump if it is too long.
   
   This change has been checked to verify that its /etc/dumpdates file
   is compatible with older versions of dump.
   
   Reported by: Martin Sugioarto <martin@sugioarto.com>
   PR:          kern/160678
 
 Modified:
   stable/9/sbin/dump/dump.h
   stable/9/sbin/dump/itime.c
 Directory Properties:
   stable/9/sbin/dump/   (props changed)
 
 Modified: stable/9/sbin/dump/dump.h
 ==============================================================================
 --- stable/9/sbin/dump/dump.h	Fri Jan 13 07:00:47 2012	(r230046)
 +++ stable/9/sbin/dump/dump.h	Fri Jan 13 07:08:21 2012	(r230047)
 @@ -171,9 +171,10 @@ void	putdumptime(void);
      	if (ddatev != NULL) \
  		for (ddp = ddatev[i = 0]; i < nddates; ddp = ddatev[++i])
  
 -#define	DUMPOUTFMT	"%-32s %d %s"		/* for printf */
 +#define	DUMPFMTLEN	53			/* max device pathname length */
 +#define	DUMPOUTFMT	"%-*s %d %s"		/* for printf */
  						/* name, level, ctime(date) */
 -#define	DUMPINFMT	"%32s %d %[^\n]\n"	/* inverse for scanf */
 +#define	DUMPINFMT	"%s %d %[^\n]\n"	/* inverse for scanf */
  
  void	sig(int signo);
  
 
 Modified: stable/9/sbin/dump/itime.c
 ==============================================================================
 --- stable/9/sbin/dump/itime.c	Fri Jan 13 07:00:47 2012	(r230046)
 +++ stable/9/sbin/dump/itime.c	Fri Jan 13 07:08:21 2012	(r230047)
 @@ -222,7 +222,10 @@ static void
  dumprecout(FILE *file, const struct dumpdates *what)
  {
  
 -	if (fprintf(file, DUMPOUTFMT, what->dd_name,
 +	if (strlen(what->dd_name) > DUMPFMTLEN)
 +		quit("Name '%s' exceeds DUMPFMTLEN (%d) bytes\n",
 +		    what->dd_name, DUMPFMTLEN);
 +	if (fprintf(file, DUMPOUTFMT, DUMPFMTLEN, what->dd_name,
  	      what->dd_level, ctime(&what->dd_ddate)) < 0)
  		quit("%s: %s\n", dumpdates, strerror(errno));
  }
 _______________________________________________
 svn-src-all@freebsd.org mailing list
 http://lists.freebsd.org/mailman/listinfo/svn-src-all
 To unsubscribe, send any mail to "svn-src-all-unsubscribe@freebsd.org"

From: dfilter@FreeBSD.ORG (dfilter service)
To: bug-followup@FreeBSD.org
Cc:  
Subject: Re: bin/160678: commit references a PR
Date: Fri, 13 Jan 2012 07:11:14 +0000 (UTC)

 Author: mckusick
 Date: Fri Jan 13 07:10:52 2012
 New Revision: 230048
 URL: http://svn.freebsd.org/changeset/base/230048
 
 Log:
   MFC: 226520
   
   The current /etc/dumpdates file restricts device names to 32 characters.
   With the addition of various GEOM layers some device names now exceed
   this length, for example /dev/mirror/encrypted.elig.journal. This
   change expands the field to 53 bytes which brings the /etc/dumpdates
   lines to 80 characters. Exceeding 80 characters makes the /etc/dumpdates
   file much less human readable. A test is added to dump so that it
   verifies that the device name will fit in the 53 character field
   failing the dump if it is too long.
   
   This change has been checked to verify that its /etc/dumpdates file
   is compatible with older versions of dump.
   
   Reported by: Martin Sugioarto <martin@sugioarto.com>
   PR:          kern/160678
 
 Modified:
   stable/8/sbin/dump/dump.h
   stable/8/sbin/dump/itime.c
 Directory Properties:
   stable/8/sbin/dump/   (props changed)
 
 Modified: stable/8/sbin/dump/dump.h
 ==============================================================================
 --- stable/8/sbin/dump/dump.h	Fri Jan 13 07:08:21 2012	(r230047)
 +++ stable/8/sbin/dump/dump.h	Fri Jan 13 07:10:52 2012	(r230048)
 @@ -171,9 +171,10 @@ void	putdumptime(void);
      	if (ddatev != NULL) \
  		for (ddp = ddatev[i = 0]; i < nddates; ddp = ddatev[++i])
  
 -#define	DUMPOUTFMT	"%-32s %d %s"		/* for printf */
 +#define	DUMPFMTLEN	53			/* max device pathname length */
 +#define	DUMPOUTFMT	"%-*s %d %s"		/* for printf */
  						/* name, level, ctime(date) */
 -#define	DUMPINFMT	"%32s %d %[^\n]\n"	/* inverse for scanf */
 +#define	DUMPINFMT	"%s %d %[^\n]\n"	/* inverse for scanf */
  
  void	sig(int signo);
  
 
 Modified: stable/8/sbin/dump/itime.c
 ==============================================================================
 --- stable/8/sbin/dump/itime.c	Fri Jan 13 07:08:21 2012	(r230047)
 +++ stable/8/sbin/dump/itime.c	Fri Jan 13 07:10:52 2012	(r230048)
 @@ -222,7 +222,10 @@ static void
  dumprecout(FILE *file, const struct dumpdates *what)
  {
  
 -	if (fprintf(file, DUMPOUTFMT, what->dd_name,
 +	if (strlen(what->dd_name) > DUMPFMTLEN)
 +		quit("Name '%s' exceeds DUMPFMTLEN (%d) bytes\n",
 +		    what->dd_name, DUMPFMTLEN);
 +	if (fprintf(file, DUMPOUTFMT, DUMPFMTLEN, what->dd_name,
  	      what->dd_level, ctime(&what->dd_ddate)) < 0)
  		quit("%s: %s\n", dumpdates, strerror(errno));
  }
 _______________________________________________
 svn-src-all@freebsd.org mailing list
 http://lists.freebsd.org/mailman/listinfo/svn-src-all
 To unsubscribe, send any mail to "svn-src-all-unsubscribe@freebsd.org"
 
State-Changed-From-To: patched->closed 
State-Changed-By: mckusick 
State-Changed-When: Fri Jan 13 07:11:22 UTC 2012 
State-Changed-Why:  
The fix has been verified in head. 
The fix has been MFC'ed to 8 and 9. 

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