public inbox for linux-kernel@vger.kernel.org
 help / color / mirror / Atom feed
From: Matthew Dobson <colpatch@us.ibm.com>
To: Linus Torvalds <torvalds@transmeta.com>,
	"Martin J. Bligh" <mbligh@aracnet.com>,
	William Lee Irwin III <wli@holomorphy.com>,
	Andrew Morton <akpm@zip.com.au>
Cc: Michael Hohnbaum <hohnbaum@us.ibm.com>,
	linux-kernel <linux-kernel@vger.kernel.org>,
	Trivial Patch Monkey <trivial@rustcorp.com.au>
Subject: [patch] Broken CLEAR_BITMAP() macro
Date: Thu, 06 Feb 2003 14:44:19 -0800	[thread overview]
Message-ID: <3E42E543.20306@us.ibm.com> (raw)

[-- Attachment #1: Type: text/plain, Size: 1293 bytes --]

Hello all,
	It appears that the CLEAR_BITMAP() macro in include/linux/types.h is 
broken.

(Examples done with BITS_PER_LONG == 32, but would work with == 64, or 
anything but 8 for that matter! :)

 >#define DECLARE_BITMAP(name,bits) \
 >	unsigned long name[((bits)+BITS_PER_LONG-1)/BITS_PER_LONG]
 >#define CLEAR_BITMAP(name,bits) \
 >	memset(name, 0, ((bits)+BITS_PER_LONG-1)/8)

If, for example, we DECLARE_BITMAP(foo, 64), we're going to get:
	unsigned long foo[((64)+32-1)/32] =>
	unsigned long foo[95/32] =>
	unsigned long foo[2]

Now, that's all well and good (and correct! ;)  But, look at what 
happens if we do a CLEAR_BITMAP(foo, 64):
	memset(foo, 0, ((64)+32-1)/8) =>
	memset(foo, 0, 95/8) =>
	memset(foo, 0, 11)

So the memset is going to try and clear 11 bytes starting at foo, which 
will overflow the foo array by 3 bytes.  This is bad.

What CLEAR_BITMAP wants to be doing is this:
  #define CLEAR_BITMAP(name,bits) \
  	memset(name, 0, 
(((bits)+BITS_PER_LONG-1)/BITS_PER_LONG)*sizeof(unsigned long))

Attatched is a patch that creates a macro BITS_TO_LONGS that just rounds 
a number of bits up to the closest number of unsigned longs.  This makes 
the DECLARE & CLEAR _BITMAP macros more readable.  I also modify the 
CLEAR_BITMAP macro to work correctly.

Cheers!

-Matt

[-- Attachment #2: clear_bitmap_fix-2.5.59.patch --]
[-- Type: text/plain, Size: 744 bytes --]

diff -Nur --exclude-from=/usr/src/.dontdiff linux-2.5.59-vanilla/include/linux/types.h linux-2.5.59-bitmap_fix/include/linux/types.h
--- linux-2.5.59-vanilla/include/linux/types.h	Thu Jan 16 18:22:41 2003
+++ linux-2.5.59-bitmap_fix/include/linux/types.h	Thu Feb  6 13:51:23 2003
@@ -4,10 +4,12 @@
 #ifdef	__KERNEL__
 #include <linux/config.h>
 
+#define BITS_TO_LONGS(bits) \
+	(((bits)+BITS_PER_LONG-1)/BITS_PER_LONG)
 #define DECLARE_BITMAP(name,bits) \
-	unsigned long name[((bits)+BITS_PER_LONG-1)/BITS_PER_LONG]
+	unsigned long name[BITS_TO_LONGS(bits)]
 #define CLEAR_BITMAP(name,bits) \
-	memset(name, 0, ((bits)+BITS_PER_LONG-1)/8)
+	memset(name, 0, BITS_TO_LONGS(bits)*sizeof(unsigned long))
 #endif
 
 #include <linux/posix_types.h>

                 reply	other threads:[~2003-02-06 22:42 UTC|newest]

Thread overview: [no followups] expand[flat|nested]  mbox.gz  Atom feed

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=3E42E543.20306@us.ibm.com \
    --to=colpatch@us.ibm.com \
    --cc=akpm@zip.com.au \
    --cc=hohnbaum@us.ibm.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=mbligh@aracnet.com \
    --cc=torvalds@transmeta.com \
    --cc=trivial@rustcorp.com.au \
    --cc=wli@holomorphy.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox