Hi all, I'm new in this mailing list. I start to work/test PREEPT_RT and making some test I seee that there is a bug on backfire module in rt-tests repository. I'm attaching my patch. best regards. Michele
From cd94ede8cf9eb8c26a196ea0111220969451cbb2 Mon Sep 17 00:00:00 2001 From: Michele Dionisio <michele.dionisio@xxxxxxxxxxxx> Date: Tue, 26 Sep 2017 14:32:51 +0200 Subject: [FIX] fix copy data to and from userspace diff --git a/src/backfire/backfire.c b/src/backfire/backfire.c index aaf9c4a..b38651b 100644 --- a/src/backfire/backfire.c +++ b/src/backfire/backfire.c @@ -20,11 +20,9 @@ */ #include <linux/module.h> - #include <linux/sched.h> #include <linux/cpumask.h> #include <linux/time.h> -#include <linux/smp_lock.h> #include <linux/types.h> #include <linux/errno.h> #include <linux/miscdevice.h> @@ -32,25 +30,33 @@ #include <linux/spinlock.h> #include <asm/uaccess.h> -#include <asm/system.h> #define BACKFIRE_MINOR MISC_DYNAMIC_MINOR -static spinlock_t backfire_state_lock = SPIN_LOCK_UNLOCKED; +static DEFINE_SPINLOCK(backfire_state_lock); static int backfire_open_cnt; /* #times opened */ static int backfire_open_mode; /* special open modes */ static struct timeval sendtime; /* when the most recent signal was sent */ #define BACKFIRE_WRITE 1 /* opened for writing (exclusive) */ #define BACKFIRE_EXCL 2 /* opened with O_EXCL */ +#define MAX_SIZE_DATA_RW 512 + /* * These are the file operation function for user access to /dev/backfire */ static ssize_t backfire_read(struct file *file, char *buf, size_t count, loff_t *ppos) { - return snprintf(buf, count, "%d,%d\n", (int) sendtime.tv_sec, + char kbuf[MAX_SIZE_DATA_RW]; + ssize_t res; + if (count > MAX_SIZE_DATA_RW) { + count = MAX_SIZE_DATA_RW; + } + res = snprintf(kbuf, count, "%d,%d\n", (int) sendtime.tv_sec, (int) sendtime.tv_usec); + copy_to_user(buf, kbuf, res+1); + return res; } static ssize_t @@ -58,16 +64,28 @@ backfire_write(struct file *file, const char *buf, size_t count, loff_t *ppos) { int signo; struct pid *pid; - - if (sscanf(buf, "%d", &signo) >= 1) { + char kbuf[MAX_SIZE_DATA_RW+1]; + ssize_t retval = 0; + + if (count == 0) { + return 0; + } + if (count > MAX_SIZE_DATA_RW) { + count = MAX_SIZE_DATA_RW; + } + copy_from_user(kbuf, buf, count); + kbuf[count] = '\0'; + + if (sscanf(kbuf, "%d", &signo) >= 1) { if (signo > 0 && signo < 32) { pid = get_pid(task_pid(current)); do_gettimeofday(&sendtime); kill_pid(pid, signo, 1); + retval = strlen(kbuf); } else printk(KERN_ERR "Invalid signal no. %d\n", signo); } - return strlen(buf); + return retval; } static int