Patch "platform/chrome: cros_ec_debugfs: detach log reader wq from devm" has been added to the 5.17-stable tree

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



This is a note to let you know that I've just added the patch titled

    platform/chrome: cros_ec_debugfs: detach log reader wq from devm

to the 5.17-stable tree which can be found at:
    http://www.kernel.org/git/?p=linux/kernel/git/stable/stable-queue.git;a=summary

The filename of the patch is:
     platform-chrome-cros_ec_debugfs-detach-log-reader-wq.patch
and it can be found in the queue-5.17 subdirectory.

If you, or anyone else, feels it should not be added to the stable tree,
please let <stable@xxxxxxxxxxxxxxx> know about it.



commit cbfcc1e2f322132efa11ecfa42dd2585b4e67ff4
Author: Tzung-Bi Shih <tzungbi@xxxxxxxxxx>
Date:   Wed Feb 9 13:11:30 2022 +0800

    platform/chrome: cros_ec_debugfs: detach log reader wq from devm
    
    [ Upstream commit 0e8eb5e8acbad19ac2e1856b2fb2320184299b33 ]
    
    Debugfs console_log uses devm memory (e.g. debug_info in
    cros_ec_console_log_poll()).  However, lifecycles of device and debugfs
    are independent.  An use-after-free issue is observed if userland
    program operates the debugfs after the memory has been freed.
    
    The call trace:
     do_raw_spin_lock
     _raw_spin_lock_irqsave
     remove_wait_queue
     ep_unregister_pollwait
     ep_remove
     do_epoll_ctl
    
    A Python example to reproduce the issue:
    ... import select
    ... p = select.epoll()
    ... f = open('/sys/kernel/debug/cros_scp/console_log')
    ... p.register(f, select.POLLIN)
    ... p.poll(1)
    [(4, 1)]                    # 4=fd, 1=select.POLLIN
    
    [ shutdown cros_scp at the point ]
    
    ... p.poll(1)
    [(4, 16)]                   # 4=fd, 16=select.POLLHUP
    ... p.unregister(f)
    
    An use-after-free issue raises here.  It called epoll_ctl with
    EPOLL_CTL_DEL which in turn to use the workqueue in the devm (i.e.
    log_wq).
    
    Detaches log reader's workqueue from devm to make sure it is persistent
    even if the device has been removed.
    
    Signed-off-by: Tzung-Bi Shih <tzungbi@xxxxxxxxxx>
    Reviewed-by: Guenter Roeck <groeck@xxxxxxxxxx>
    Link: https://lore.kernel.org/r/20220209051130.386175-1-tzungbi@xxxxxxxxxx
    Signed-off-by: Benson Leung <bleung@xxxxxxxxxxxx>
    Signed-off-by: Sasha Levin <sashal@xxxxxxxxxx>

diff --git a/drivers/platform/chrome/cros_ec_debugfs.c b/drivers/platform/chrome/cros_ec_debugfs.c
index 272c89837d74..0dbceee87a4b 100644
--- a/drivers/platform/chrome/cros_ec_debugfs.c
+++ b/drivers/platform/chrome/cros_ec_debugfs.c
@@ -25,6 +25,9 @@
 
 #define CIRC_ADD(idx, size, value)	(((idx) + (value)) & ((size) - 1))
 
+/* waitqueue for log readers */
+static DECLARE_WAIT_QUEUE_HEAD(cros_ec_debugfs_log_wq);
+
 /**
  * struct cros_ec_debugfs - EC debugging information.
  *
@@ -33,7 +36,6 @@
  * @log_buffer: circular buffer for console log information
  * @read_msg: preallocated EC command and buffer to read console log
  * @log_mutex: mutex to protect circular buffer
- * @log_wq: waitqueue for log readers
  * @log_poll_work: recurring task to poll EC for new console log data
  * @panicinfo_blob: panicinfo debugfs blob
  */
@@ -44,7 +46,6 @@ struct cros_ec_debugfs {
 	struct circ_buf log_buffer;
 	struct cros_ec_command *read_msg;
 	struct mutex log_mutex;
-	wait_queue_head_t log_wq;
 	struct delayed_work log_poll_work;
 	/* EC panicinfo */
 	struct debugfs_blob_wrapper panicinfo_blob;
@@ -107,7 +108,7 @@ static void cros_ec_console_log_work(struct work_struct *__work)
 			buf_space--;
 		}
 
-		wake_up(&debug_info->log_wq);
+		wake_up(&cros_ec_debugfs_log_wq);
 	}
 
 	mutex_unlock(&debug_info->log_mutex);
@@ -141,7 +142,7 @@ static ssize_t cros_ec_console_log_read(struct file *file, char __user *buf,
 
 		mutex_unlock(&debug_info->log_mutex);
 
-		ret = wait_event_interruptible(debug_info->log_wq,
+		ret = wait_event_interruptible(cros_ec_debugfs_log_wq,
 					CIRC_CNT(cb->head, cb->tail, LOG_SIZE));
 		if (ret < 0)
 			return ret;
@@ -173,7 +174,7 @@ static __poll_t cros_ec_console_log_poll(struct file *file,
 	struct cros_ec_debugfs *debug_info = file->private_data;
 	__poll_t mask = 0;
 
-	poll_wait(file, &debug_info->log_wq, wait);
+	poll_wait(file, &cros_ec_debugfs_log_wq, wait);
 
 	mutex_lock(&debug_info->log_mutex);
 	if (CIRC_CNT(debug_info->log_buffer.head,
@@ -377,7 +378,6 @@ static int cros_ec_create_console_log(struct cros_ec_debugfs *debug_info)
 	debug_info->log_buffer.tail = 0;
 
 	mutex_init(&debug_info->log_mutex);
-	init_waitqueue_head(&debug_info->log_wq);
 
 	debugfs_create_file("console_log", S_IFREG | 0444, debug_info->dir,
 			    debug_info, &cros_ec_console_log_fops);



[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Index of Archives]     [Linux USB Devel]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]

  Powered by Linux