From: Greg Kroah-Hartman Date: Mon, 1 Apr 2013 20:07:17 +0000 (-0700) Subject: 3.0-stable patches X-Git-Tag: v3.8.6~51 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=1cf66bc8f185d69e14751e0b99ce2aacf19743a4;p=thirdparty%2Fkernel%2Fstable-queue.git 3.0-stable patches added patches: staging-comedi-s626-fix-continuous-acquisition.patch sysfs-fix-race-between-readdir-and-lseek.patch sysfs-handle-failure-path-correctly-for-readdir.patch --- diff --git a/queue-3.0/series b/queue-3.0/series index 2f78f6c2254..24f41db5d8b 100644 --- a/queue-3.0/series +++ b/queue-3.0/series @@ -2,3 +2,6 @@ sunrpc-add-barriers-to-ensure-read-ordering-in-rpc_wake_up_task_queue_locked.pat bluetooth-fix-not-closing-sco-sockets-in-the-bt_connect2-state.patch bluetooth-add-support-for-dell.patch bluetooth-add-support-for-dell_2.patch +staging-comedi-s626-fix-continuous-acquisition.patch +sysfs-fix-race-between-readdir-and-lseek.patch +sysfs-handle-failure-path-correctly-for-readdir.patch diff --git a/queue-3.0/staging-comedi-s626-fix-continuous-acquisition.patch b/queue-3.0/staging-comedi-s626-fix-continuous-acquisition.patch new file mode 100644 index 00000000000..f13d0237b08 --- /dev/null +++ b/queue-3.0/staging-comedi-s626-fix-continuous-acquisition.patch @@ -0,0 +1,65 @@ +From e4317ce877a31dbb9d96375391c1c4ad2210d637 Mon Sep 17 00:00:00 2001 +From: Ian Abbott +Date: Fri, 22 Mar 2013 15:16:29 +0000 +Subject: staging: comedi: s626: fix continuous acquisition + +From: Ian Abbott + +commit e4317ce877a31dbb9d96375391c1c4ad2210d637 upstream. + +For the s626 driver, there is a bug in the handling of asynchronous +commands on the AI subdevice when the stop source is `TRIG_NONE`. The +command should run continuously until cancelled, but the interrupt +handler stops the command running after the first scan. + +The command set-up function `s626_ai_cmd()` contains this code: + + switch (cmd->stop_src) { + case TRIG_COUNT: + /* data arrives as one packet */ + devpriv->ai_sample_count = cmd->stop_arg; + devpriv->ai_continous = 0; + break; + case TRIG_NONE: + /* continous acquisition */ + devpriv->ai_continous = 1; + devpriv->ai_sample_count = 0; + break; + } + +The interrupt handler `s626_irq_handler()` contains this code: + + if (!(devpriv->ai_continous)) + devpriv->ai_sample_count--; + if (devpriv->ai_sample_count <= 0) { + devpriv->ai_cmd_running = 0; + /* ... */ + } + +So `devpriv->ai_sample_count` is only decremented for the `TRIG_COUNT` +case, but `devpriv->ai_cmd_running` is set to 0 (and the command +stopped) regardless. + +Fix this in `s626_ai_cmd()` by setting `devpriv->ai_sample_count = 1` +for the `TRIG_NONE` case. The interrupt handler will not decrement it +so it will remain greater than 0 and the check for stopping the +acquisition will fail. + +Signed-off-by: Ian Abbott +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/staging/comedi/drivers/s626.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/drivers/staging/comedi/drivers/s626.c ++++ b/drivers/staging/comedi/drivers/s626.c +@@ -1882,7 +1882,7 @@ static int s626_ai_cmd(struct comedi_dev + case TRIG_NONE: + /* continous acquisition */ + devpriv->ai_continous = 1; +- devpriv->ai_sample_count = 0; ++ devpriv->ai_sample_count = 1; + break; + } + diff --git a/queue-3.0/sysfs-fix-race-between-readdir-and-lseek.patch b/queue-3.0/sysfs-fix-race-between-readdir-and-lseek.patch new file mode 100644 index 00000000000..8ce57c7442a --- /dev/null +++ b/queue-3.0/sysfs-fix-race-between-readdir-and-lseek.patch @@ -0,0 +1,51 @@ +From 991f76f837bf22c5bb07261cfd86525a0a96650c Mon Sep 17 00:00:00 2001 +From: Ming Lei +Date: Wed, 20 Mar 2013 23:25:24 +0800 +Subject: sysfs: fix race between readdir and lseek + +From: Ming Lei + +commit 991f76f837bf22c5bb07261cfd86525a0a96650c upstream. + +While readdir() is running, lseek() may set filp->f_pos as zero, +then may leave filp->private_data pointing to one sysfs_dirent +object without holding its reference counter, so the sysfs_dirent +object may be used after free in next readdir(). + +This patch holds inode->i_mutex to avoid the problem since +the lock is always held in readdir path. + +Reported-by: Dave Jones +Tested-by: Sasha Levin +Signed-off-by: Ming Lei +Signed-off-by: Greg Kroah-Hartman + +--- + fs/sysfs/dir.c | 13 ++++++++++++- + 1 file changed, 12 insertions(+), 1 deletion(-) + +--- a/fs/sysfs/dir.c ++++ b/fs/sysfs/dir.c +@@ -955,10 +955,21 @@ static int sysfs_readdir(struct file * f + return 0; + } + ++static loff_t sysfs_dir_llseek(struct file *file, loff_t offset, int whence) ++{ ++ struct inode *inode = file->f_path.dentry->d_inode; ++ loff_t ret; ++ ++ mutex_lock(&inode->i_mutex); ++ ret = generic_file_llseek(file, offset, whence); ++ mutex_unlock(&inode->i_mutex); ++ ++ return ret; ++} + + const struct file_operations sysfs_dir_operations = { + .read = generic_read_dir, + .readdir = sysfs_readdir, + .release = sysfs_dir_release, +- .llseek = generic_file_llseek, ++ .llseek = sysfs_dir_llseek, + }; diff --git a/queue-3.0/sysfs-handle-failure-path-correctly-for-readdir.patch b/queue-3.0/sysfs-handle-failure-path-correctly-for-readdir.patch new file mode 100644 index 00000000000..66482bc990d --- /dev/null +++ b/queue-3.0/sysfs-handle-failure-path-correctly-for-readdir.patch @@ -0,0 +1,47 @@ +From e5110f411d2ee35bf8d202ccca2e89c633060dca Mon Sep 17 00:00:00 2001 +From: Ming Lei +Date: Wed, 20 Mar 2013 23:25:25 +0800 +Subject: sysfs: handle failure path correctly for readdir() + +From: Ming Lei + +commit e5110f411d2ee35bf8d202ccca2e89c633060dca upstream. + +In case of 'if (filp->f_pos == 0 or 1)' of sysfs_readdir(), +the failure from filldir() isn't handled, and the reference counter +of the sysfs_dirent object pointed by filp->private_data will be +released without clearing filp->private_data, so use after free +bug will be triggered later. + +This patch returns immeadiately under the situation for fixing the bug, +and it is reasonable to return from readdir() when filldir() fails. + +Reported-by: Dave Jones +Tested-by: Sasha Levin +Signed-off-by: Ming Lei +Signed-off-by: Greg Kroah-Hartman + +--- + fs/sysfs/dir.c | 4 ++++ + 1 file changed, 4 insertions(+) + +--- a/fs/sysfs/dir.c ++++ b/fs/sysfs/dir.c +@@ -917,6 +917,8 @@ static int sysfs_readdir(struct file * f + ino = parent_sd->s_ino; + if (filldir(dirent, ".", 1, filp->f_pos, ino, DT_DIR) == 0) + filp->f_pos++; ++ else ++ return 0; + } + if (filp->f_pos == 1) { + if (parent_sd->s_parent) +@@ -925,6 +927,8 @@ static int sysfs_readdir(struct file * f + ino = parent_sd->s_ino; + if (filldir(dirent, "..", 2, filp->f_pos, ino, DT_DIR) == 0) + filp->f_pos++; ++ else ++ return 0; + } + mutex_lock(&sysfs_mutex); + for (pos = sysfs_dir_pos(ns, parent_sd, filp->f_pos, pos);