lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <20070827132843.GB21970@infradead.org>
Date:	Mon, 27 Aug 2007 14:28:43 +0100
From:	Christoph Hellwig <hch@...radead.org>
To:	Peter Firefly Lund <firefly@...64.dk>
Cc:	Christoph Lameter <clameter@....com>,
	Momchil Velikov <velco@...ata.bg>,
	Christoph Hellwig <hch@...radead.org>,
	linux-kernel@...r.kernel.org, trivial@...nel.org
Subject: Re: [PATCH] avoid negative shifts in radix-tree.c

On Sat, Aug 25, 2007 at 04:26:07PM +0200, Peter Firefly Lund wrote:
> (linux-vax@...gamentum.com only bcc'ed because it's subscribers only,
> Lameter addressed because I think he touched the code last, Velikov and
> Hellwig because they touched the code first.)
> 
> The current code in __max_index() will shift by a negative amount first
> and only then fix the situation by ignoring the result if the shift
> amount would have been negative.  This happens to work on almost any
> architecture despite not being valid C.
> 
> Chapter and verse from the (draft) ISO C99 standard, "6.5.7 Bitwise
> shift operators", paragraph 3:
> 
>   "The integer promotions are performed on each of the operands. The
>    type of the result is that of the promoted left operand. If the
>    value of the right operand is negative or is greater than or equal
>    to the width of the promoted left operand, the behavior is
>    undefined."
> 
> Right-shifting by a negative amount causes a "reserved operand fault" on
> the VAX with some gcc versions.
> 
> 
> Applies to 2.6.22.
> Boot tested lightly on an emulated VAX.
> 
> (The function is called 7 times on booth with the values 0..6 -- I
> checked that the return values were the same + that it returns ~0UL for
> height==6 as was clearly the intention.)
> 
> -Peter
> 
> --- lib/radix-tree-old.c	2007-08-25 15:36:40.000000000 +0200
> +++ lib/radix-tree.c	2007-08-25 15:36:51.000000000 +0200
> @@ -980,12 +980,14 @@ radix_tree_node_ctor(void *node, struct 
>  
>  static __init unsigned long __maxindex(unsigned int height)
>  {
> -	unsigned int tmp = height * RADIX_TREE_MAP_SHIFT;
> -	unsigned long index = (~0UL >> (RADIX_TREE_INDEX_BITS - tmp - 1)) >> 1;
> -
> -	if (tmp >= RADIX_TREE_INDEX_BITS)
> -		index = ~0UL;
> -	return index;
> +	unsigned int	tmp   = height * RADIX_TREE_MAP_SHIFT;
> +	int		shift = RADIX_TREE_INDEX_BITS - tmp;
> +	unsigned long	index;
> +
> +	if (shift < 0)
> +		return ~0UL;
> +	else
> +		return ~0UL >> shift;

The conceptual change looks fine to me, but the code looks a little odd,
what about:

static __init unsigned long __maxindex(unsigned int height)
{
	unsigned int tmp = height * RADIX_TREE_MAP_SHIFT;
	int shift = RADIX_TREE_INDEX_BITS - tmp;

	if (shift < 0)
		return ~0UL;
	return ~0UL >> shift;
}

instead?
-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@...r.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ