Skip site navigation (1)Skip section navigation (2)
Date:      Thu, 20 Feb 2003 19:28:09 -0800
From:      Kirk McKusick <mckusick@beastie.mckusick.com>
To:        Juli Mallett <jmallett@FreeBSD.ORG>
Cc:        src-committers@FreeBSD.ORG, cvs-src@FreeBSD.ORG, cvs-all@FreeBSD.ORG, "Andrey A. Chernov" <ache@nagual.pp.ru>, Nate Lawson <nate@root.org>, David Schultz <dschultz@uclink.Berkeley.EDU>, Poul-Henning Kamp <phk@critter.freebsd.dk>
Subject:   Re: cvs commit: src/sbin/newfs mkfs.c src/sys/ufs/ffs ffs_alloc.c ...
Message-ID:  <200302210328.h1L3S9FL058578@beastie.mckusick.com>
In-Reply-To: Your message of "Fri, 14 Feb 2003 15:33:28 CST."

next in thread | raw e-mail | index | archive | help
	Date: Fri, 14 Feb 2003 15:33:28 -0600
	From: Juli Mallett <jmallett@FreeBSD.ORG>
	To: Kirk McKusick <mckusick@FreeBSD.ORG>
	Cc: src-committers@FreeBSD.ORG, cvs-src@FreeBSD.ORG, cvs-all@FreeBSD.ORG
	Subject: Re: cvs commit: src/sbin/newfs mkfs.c src/sys/ufs/ffs ...

	* De: Kirk McKusick <mckusick@FreeBSD.org> [ Data: 2003-02-14 ]
		[ Subjecte: cvs commit: src/sbin/newfs mkfs.c ...
	> mckusick    2003/02/14 13:31:58 PST
	> 
	>   Modified files:
	>     sbin/newfs           mkfs.c 
	>     sys/ufs/ffs          ffs_alloc.c ffs_vfsops.c 
	>   Log:
	>   Replace use of random() with arc4random() to provide less guessable
	>   values for the initial inode generation numbers in newfs and for
	>   newly allocated inode generation numbers in the kernel.

	Are the sequences for it also repeatable in the newfs case for e.g. the
	regression tests, where it is used unseeded?

	Thanx,
	juli.
	-- 
	Juli Mallett <jmallett@FreeBSD.org>
	AIM: BSDFlata -- IRC: juli on EFnet
	OpenDarwin, Mono, FreeBSD Developer
	ircd-hybrid Developer, EFnet addict
	FreeBSD on MIPS-Anything on FreeBSD
	Never trust an ELF, COFF or Mach-O!

As has been pointed out, arc4random is a lot less guessable
than than random. The reason that the fix needs to be in
newfs is because it selects the random value for the root
directory of the filesystem which is especially important
that it not be guessable. Since the complaint at hand is
that the regression is broken, I have fixed that problem
in newfs itself. When the -R flag is given to newfs it
substitutes a highly predictable and completely repeatable
function for arc4random. Proposed fix below.

	Kirk McKusick

=-=-=-=-=

Index: mkfs.c
===================================================================
RCS file: /usr/ncvs/src/sbin/newfs/mkfs.c,v
retrieving revision 1.67
diff -c -r1.67 mkfs.c
*** mkfs.c	2002/12/02 19:31:53	1.67
--- mkfs.c	2003/02/20 21:40:33
***************
*** 101,107 ****
  	((sblock.fs_magic == FS_UFS1_MAGIC) ? \
  	(dp)->dp1.field : (dp)->dp2.field)
  
- static int randinit;
  static caddr_t iobuf;
  static long iobufsize;
  static ufs2_daddr_t alloc(int size, int mode);
--- 98,103 ----
***************
*** 117,122 ****
--- 113,119 ----
  static void setblock(struct fs *, unsigned char *, int);
  static void wtfs(ufs2_daddr_t, int, char *);
  static void wtfsflush(void);
+ static u_int32_t newfs_random(void);
  
  void
  mkfs(struct partition *pp, char *fsys)
***************
*** 128,140 ****
  	int width;
  	char tmpbuf[100];	/* XXX this will break in about 2,500 years */
  
! 	if (Rflag)
  		utime = 1000000000;
! 	else 
  		time(&utime);
! 	if (!Rflag && !randinit) {
! 		randinit = 1;
! 		srandomdev();
  	}
  	sblock.fs_old_flags = FS_FLAGS_UPDATED;
  	sblock.fs_flags = 0;
--- 125,135 ----
  	int width;
  	char tmpbuf[100];	/* XXX this will break in about 2,500 years */
  
! 	if (Rflag) {
  		utime = 1000000000;
! 	} else {
  		time(&utime);
! 		arc4random_stir();
  	}
  	sblock.fs_old_flags = FS_FLAGS_UPDATED;
  	sblock.fs_flags = 0;
***************
*** 393,399 ****
  	sblock.fs_state = 0;
  	sblock.fs_clean = 1;
  	sblock.fs_id[0] = (long)utime;
! 	sblock.fs_id[1] = random();
  	sblock.fs_fsmnt[0] = '\0';
  	csfrags = howmany(sblock.fs_cssize, sblock.fs_fsize);
  	sblock.fs_dsize = sblock.fs_size - sblock.fs_sblkno -
--- 388,394 ----
  	sblock.fs_state = 0;
  	sblock.fs_clean = 1;
  	sblock.fs_id[0] = (long)utime;
! 	sblock.fs_id[1] = newfs_random();
  	sblock.fs_fsmnt[0] = '\0';
  	csfrags = howmany(sblock.fs_cssize, sblock.fs_fsize);
  	sblock.fs_dsize = sblock.fs_size - sblock.fs_sblkno -
***************
*** 655,664 ****
  	dp2 = (struct ufs2_dinode *)(&iobuf[start]);
  	for (i = 0; i < acg.cg_initediblk; i++) {
  		if (sblock.fs_magic == FS_UFS1_MAGIC) {
! 			dp1->di_gen = random();
  			dp1++;
  		} else {
! 			dp2->di_gen = random();
  			dp2++;
  		}
  	}
--- 650,659 ----
  	dp2 = (struct ufs2_dinode *)(&iobuf[start]);
  	for (i = 0; i < acg.cg_initediblk; i++) {
  		if (sblock.fs_magic == FS_UFS1_MAGIC) {
! 			dp1->di_gen = newfs_random();
  			dp1++;
  		} else {
! 			dp2->di_gen = newfs_random();
  			dp2++;
  		}
  	}
***************
*** 672,678 ****
  		     i += sblock.fs_frag) {
  			dp1 = (struct ufs1_dinode *)(&iobuf[start]);
  			for (j = 0; j < INOPB(&sblock); j++) {
! 				dp1->di_gen = random();
  				dp1++;
  			}
  			wtfs(fsbtodb(&sblock, cgimin(&sblock, cylno) + i),
--- 667,673 ----
  		     i += sblock.fs_frag) {
  			dp1 = (struct ufs1_dinode *)(&iobuf[start]);
  			for (j = 0; j < INOPB(&sblock); j++) {
! 				dp1->di_gen = newfs_random();
  				dp1++;
  			}
  			wtfs(fsbtodb(&sblock, cgimin(&sblock, cylno) + i),
***************
*** 1042,1045 ****
--- 1037,1054 ----
  		if (1 << n == val)
  			return (n);
  	errx(1, "ilog2: %d is not a power of 2\n", val);
+ }
+ 
+ /*
+  * For the regression test, return predictable random values.
+  * Otherwise use a true random number generator.
+  */
+ static u_int32_t
+ newfs_random(void)
+ {
+ 	static int nextnum = 1;
+ 
+ 	if (Rflag)
+ 		return (nextnum++);
+ 	return (arc4random());
  }
Index: ref.test
===================================================================
RCS file: /usr/ncvs/src/sbin/newfs/ref.test,v
retrieving revision 1.1
diff -c -r1.1 ref.test
*** ref.test	2002/03/19 21:05:29	1.1
--- ref.test	2003/02/21 03:24:23
***************
*** 1,7 ****
  # $FreeBSD: src/sbin/newfs/ref.test,v 1.1 2002/03/19 21:05:29 phk Exp $
! ba20315918bf2d2885eed49fee03e3ca
! e2170dc5d6bd192f85da9d1085550265
! 510df6ee7aadd7a5477b47c1a967e8db
! 47a1a6afcd21c166f32027020b0b6a7e
! 6e3b83f554b0216206a2768f8b01d9a1
! f6035a903644e118f09c6041fb29f7ce
--- 1,7 ----
  # $FreeBSD: src/sbin/newfs/ref.test,v 1.1 2002/03/19 21:05:29 phk Exp $
! 00c08266df6b0c79d2673515c182216a
! c00458f223a9119190591e8b8679bf97
! 7d5b3c75244898dbb07a4cd20860c8a1
! a69179c925b67edc20c289c3321ae87a
! 4d1c6cf3c563044a59c3d426bb890ece
! 841ed8884da029d4590b56b2f033f404

To Unsubscribe: send mail to majordomo@FreeBSD.org
with "unsubscribe cvs-all" in the body of the message




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