Dmitry Chestnykh wrote:
> Hello,
> 
> In ffs_inode_alloc(), inode generation numbers are incremented after
> being assigned an initial random value. Since the di_gen field is a
> signed integer, it may overflow, causing undefined behavior (this is
> unlikely to ever happen, though).
> 
> This patch always assigns a random non-zero positive integer in [1,
> INT_MAX] range, not equal to the previous generation number.

will this cause problems if a number repeats? we've seen problems with that
before, where you get a sequence like 4, 7, 4 and then bad things happen.


> 
> --
> Dmitry Chestnykh
> https://www.codingrobots.com
> 
> 
> Index: src/sys/ufs/ffs/ffs_alloc.c
> ===================================================================
> RCS file: /cvs/src/sys/ufs/ffs/ffs_alloc.c,v
> retrieving revision 1.108
> diff -u -p -u -r1.108 ffs_alloc.c
> --- src/sys/ufs/ffs/ffs_alloc.c 23 May 2016 20:47:49 -0000      1.108
> +++ src/sys/ufs/ffs/ffs_alloc.c 24 Jun 2017 19:25:04 -0000
> @@ -361,6 +361,7 @@ ffs_inode_alloc(struct inode *pip, mode_
>         struct inode *ip;
>         ufsino_t ino, ipref;
>         int cg, error;
> +       int32_t ngen;
> 
>         *vpp = NULL;
>         fs = pip->i_fs;
> @@ -413,16 +414,12 @@ ffs_inode_alloc(struct inode *pip, mode_
> 
>         /*
>          * Set up a new generation number for this inode.
> -        * XXX - just increment for now, this is wrong! (millert)
> -        *       Need a way to preserve randomization.
>          */
> -       if (DIP(ip, gen) != 0)
> -               DIP_ADD(ip, gen, 1);
> -       if (DIP(ip, gen) == 0)
> -               DIP_ASSIGN(ip, gen, arc4random() & INT_MAX);
> -
> -       if (DIP(ip, gen) == 0 || DIP(ip, gen) == -1)
> -               DIP_ASSIGN(ip, gen, 1); /* Shouldn't happen */
> +       do {
> +               ngen = arc4random_uniform(INT_MAX) + 1;
> +       } while (DIP(ip, gen) == ngen);
> +
> +       DIP_ASSIGN(ip, gen, ngen);
> 
>         return (0);
> 

Reply via email to