From: Josh Hunt <[email protected]>

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 <[email protected]>
Signed-off-by: Josh Hunt <[email protected]>
Acked-by: Ankita Garg <[email protected]>
Cc: <[email protected]>
Signed-off-by: Andrew Morton <[email protected]>
---

 drivers/misc/lkdtm.c |    8 ++++++++
 1 file changed, 8 insertions(+)

diff -puN 
drivers/misc/lkdtm.c~drivers-misc-lkdtmc-fix-race-when-crashpoint-is-hit-multiple-times-before-checking-count
 drivers/misc/lkdtm.c
--- 
a/drivers/misc/lkdtm.c~drivers-misc-lkdtmc-fix-race-when-crashpoint-is-hit-multiple-times-before-checking-count
+++ a/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 c
 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 w
 
 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)
_

_______________________________________________
stable mailing list
[email protected]
http://linux.kernel.org/mailman/listinfo/stable

Reply via email to