Commit aa2c96d6 authored by Josh Hunt's avatar Josh Hunt Committed by Linus Torvalds

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: default avatarTapan Dhimant <tdhimant@akamai.com>
Signed-off-by: default avatarJosh Hunt <johunt@akamai.com>
Acked-by: default avatarAnkita Garg <ankita@in.ibm.com>
Cc: <stable@kernel.org>
Signed-off-by: default avatarAndrew Morton <akpm@linux-foundation.org>
Signed-off-by: default avatarLinus Torvalds <torvalds@linux-foundation.org>
parent 507c5f12
...@@ -120,6 +120,7 @@ static int recur_count = REC_NUM_DEFAULT; ...@@ -120,6 +120,7 @@ static int recur_count = REC_NUM_DEFAULT;
static enum cname cpoint = CN_INVALID; static enum cname cpoint = CN_INVALID;
static enum ctype cptype = CT_NONE; static enum ctype cptype = CT_NONE;
static int count = DEFAULT_COUNT; static int count = DEFAULT_COUNT;
static DEFINE_SPINLOCK(count_lock);
module_param(recur_count, int, 0644); module_param(recur_count, int, 0644);
MODULE_PARM_DESC(recur_count, " Recursion level for the stack overflow test, "\ 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) ...@@ -230,11 +231,14 @@ static const char *cp_name_to_str(enum cname name)
static int lkdtm_parse_commandline(void) static int lkdtm_parse_commandline(void)
{ {
int i; int i;
unsigned long flags;
if (cpoint_count < 1 || recur_count < 1) if (cpoint_count < 1 || recur_count < 1)
return -EINVAL; return -EINVAL;
spin_lock_irqsave(&count_lock, flags);
count = cpoint_count; count = cpoint_count;
spin_unlock_irqrestore(&count_lock, flags);
/* No special parameters */ /* No special parameters */
if (!cpoint_type && !cpoint_name) if (!cpoint_type && !cpoint_name)
...@@ -349,6 +353,9 @@ static void lkdtm_do_action(enum ctype which) ...@@ -349,6 +353,9 @@ static void lkdtm_do_action(enum ctype which)
static void lkdtm_handler(void) static void lkdtm_handler(void)
{ {
unsigned long flags;
spin_lock_irqsave(&count_lock, flags);
count--; count--;
printk(KERN_INFO "lkdtm: Crash point %s of type %s hit, trigger in %d rounds\n", 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); cp_name_to_str(cpoint), cp_type_to_str(cptype), count);
...@@ -357,6 +364,7 @@ static void lkdtm_handler(void) ...@@ -357,6 +364,7 @@ static void lkdtm_handler(void)
lkdtm_do_action(cptype); lkdtm_do_action(cptype);
count = cpoint_count; count = cpoint_count;
} }
spin_unlock_irqrestore(&count_lock, flags);
} }
static int lkdtm_register_cpoint(enum cname which) static int lkdtm_register_cpoint(enum cname which)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment