Subject: bin/3179: tar doesn't check if conversion from to_oct was ok
To: None <gnats-bugs@gnats.netbsd.org>
From: Hubert Feyrer <feyrer@rfhs8012.fh-regensburg.de>
List: netbsd-bugs
Date: 02/01/1997 21:28:59
>Number:         3179
>Category:       bin
>Synopsis:       tar doesn't check if conversion from to_oct was ok
>Confidential:   no
>Severity:       serious
>Priority:       medium
>Responsible:    bin-bug-people (Utility Bug People)
>State:          open
>Class:          sw-bug
>Submitter-Id:   net
>Arrival-Date:   Sat Feb  1 21:50:03 1997
>Last-Modified:
>Originator:     Hubert Feyrer
>Organization:
Hubert Feyrer <hubert.feyrer@rz.uni-regensburg.de>
>Release:        1.2
>Environment:
	
System: NetBSD miyu 1.2 NetBSD 1.2 (MIYU) #8: Sun Jan 26 20:34:03 MET 1997 feyrer@miyu:/usr/disk1/src12/sys/arch/i386/compile/MIYU i386


>Description:
	When dumping a filesystem, tar invokes to_oct to convert major-
	and minor-number, but doesn't check if there was an overflow in
	the conversion. This could lead to incomplete dumps when doing
	backups of device nodes.

	This bug was found when comparing the tar command from NetBSD
	V1.2 and FreeBSD-current (as of Feb 1st, 1997).


>How-To-Repeat:
	ugh... :-}


>Fix:

diff -crNb /usr/src/gnu/usr.bin/tar/create.c /usr/homes/feyrer/work/FreeBSD/root/usr.src/tar/create.c
*** /usr/src/gnu/usr.bin/tar/create.c	Sun Mar 27 09:26:59 1994
--- /usr/homes/feyrer/work/FreeBSD/root/usr.src/tar/create.c	Tue Nov 12 22:44:00 1996
***************
*** 880,889 ****
  #if defined(S_IFBLK) || defined(S_IFCHR)
    if (type != LF_FIFO)
      {
!       to_oct ((long) major (hstat.st_rdev), 8,
! 	      header->header.devmajor);
!       to_oct ((long) minor (hstat.st_rdev), 8,
! 	      header->header.devminor);
      }
  #endif
  
--- 875,894 ----
  #if defined(S_IFBLK) || defined(S_IFCHR)
    if (type != LF_FIFO)
      {
!       if (checked_to_oct ((long) major (hstat.st_rdev), 8,
! 			  header->header.devmajor))
! 	{
! 	  msg ("%s: major number too large; not dumped", p);
! 	  critical_error = 1;
! 	  goto badfile;
! 	}
!       if (checked_to_oct ((long) minor (hstat.st_rdev), 8,
! 			  header->header.devminor))
! 	{
! 	  msg ("%s: minor number too large; not dumped", p);
! 	  critical_error = 1;
! 	  goto badfile;
! 	}
      }
  #endif
  
***************
*** 1398,1403 ****
--- 1403,1424 ----
    while (digs > 0)
      where[--digs] = ' ';
  
+ }
+ 
+ 
+ /*
+  * Call to_oct (), then return nonzero iff the conversion failed.
+  */
+ int
+ checked_to_oct (value, digs, where)
+   register long value;
+   register int digs;
+   register char *where;
+ {
+   long from_oct ();
+ 
+   to_oct (value, digs, where);
+   return from_oct (digs, where) != value;
  }
  
  

>Audit-Trail:
>Unformatted: