diff options
author | Josh Hunt <johunt@akamai.com> | 2011-06-27 16:18:08 -0700 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2011-06-27 18:00:13 -0700 |
commit | aa2c96d6f329e66cc59352b0f12e8f04e6a9593b (patch) | |
tree | 0d7db978da167df605b14d4880969b39caf5e0f4 /drivers/misc/lkdtm.c | |
parent | 507c5f1224014f9956e604ee8703b3bbea7da4a4 (diff) | |
download | linux-aa2c96d6f329e66cc59352b0f12e8f04e6a9593b.tar.gz linux-aa2c96d6f329e66cc59352b0f12e8f04e6a9593b.tar.bz2 linux-aa2c96d6f329e66cc59352b0f12e8f04e6a9593b.zip |
drivers/misc/lkdtm.c: fix race when crashpoint is hit multiple times before checking count
We observed the crash point count going negative in cases where the
crash point is hit multiple times before the check of "count == 0" is
done. Because of this we never call lkdtm_do_action(). This patch just
adds a spinlock to protect count.
Reported-by: Tapan Dhimant <tdhimant@akamai.com>
Signed-off-by: Josh Hunt <johunt@akamai.com>
Acked-by: Ankita Garg <ankita@in.ibm.com>
Cc: <stable@kernel.org>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'drivers/misc/lkdtm.c')
-rw-r--r-- | drivers/misc/lkdtm.c | 8 |
1 files changed, 8 insertions, 0 deletions
diff --git a/drivers/misc/lkdtm.c b/drivers/misc/lkdtm.c index 81d7fa4ec0db..150cd7061b80 100644 --- a/drivers/misc/lkdtm.c +++ b/drivers/misc/lkdtm.c @@ -120,6 +120,7 @@ static int recur_count = REC_NUM_DEFAULT; static enum cname cpoint = CN_INVALID; static enum ctype cptype = CT_NONE; static int count = DEFAULT_COUNT; +static DEFINE_SPINLOCK(count_lock); module_param(recur_count, int, 0644); MODULE_PARM_DESC(recur_count, " Recursion level for the stack overflow test, "\ @@ -230,11 +231,14 @@ static const char *cp_name_to_str(enum cname name) static int lkdtm_parse_commandline(void) { int i; + unsigned long flags; if (cpoint_count < 1 || recur_count < 1) return -EINVAL; + spin_lock_irqsave(&count_lock, flags); count = cpoint_count; + spin_unlock_irqrestore(&count_lock, flags); /* No special parameters */ if (!cpoint_type && !cpoint_name) @@ -349,6 +353,9 @@ static void lkdtm_do_action(enum ctype which) static void lkdtm_handler(void) { + unsigned long flags; + + spin_lock_irqsave(&count_lock, flags); count--; printk(KERN_INFO "lkdtm: Crash point %s of type %s hit, trigger in %d rounds\n", cp_name_to_str(cpoint), cp_type_to_str(cptype), count); @@ -357,6 +364,7 @@ static void lkdtm_handler(void) lkdtm_do_action(cptype); count = cpoint_count; } + spin_unlock_irqrestore(&count_lock, flags); } static int lkdtm_register_cpoint(enum cname which) |