Re: [PATCH] blktrace: Protect q->blk_trace with RCU

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

 



Hi Jan,

What do you think about following patch on the top of yours ?

The new helper that I've added on the top of your patch will also
future uses of the rcu_dereference_protected(). e.g. blktrace
extension [1] support that I'm working on.

P.S. it is compile only if your okay I'll send a separate patch.

+
+/* Dereference q->blk_trace with q->blk_trace_mutex check only. */
+static inline struct blk_trace *blk_trace_rcu_deref(struct 
request_queue *q)
+{
+       return rcu_dereference_protected(q->blk_trace,
+ 
lockdep_is_held(&q->blk_trace_mutex));
+}
  /*
   * Send out a notify message.
   */
@@ -632,8 +639,7 @@ static int __blk_trace_startstop(struct 
request_queue *q, int start)
         int ret;
         struct blk_trace *bt;

-       bt = rcu_dereference_protected(q->blk_trace,
- 
lockdep_is_held(&q->blk_trace_mutex));
+       bt = blk_trace_rcu_deref(q);
         if (bt == NULL)
                 return -EINVAL;

@@ -743,8 +749,7 @@ int blk_trace_ioctl(struct block_device *bdev, 
unsigned cmd, char __user *arg)
  void blk_trace_shutdown(struct request_queue *q)
  {
         mutex_lock(&q->blk_trace_mutex);
-       if (rcu_dereference_protected(q->blk_trace,
- 
lockdep_is_held(&q->blk_trace_mutex))) {
+       if (blk_trace_rcu_deref(q)) {
                 __blk_trace_startstop(q, 0);
                 __blk_trace_remove(q);
         }
@@ -1817,8 +1822,7 @@ static ssize_t sysfs_blk_trace_attr_show(struct 
device *dev,

         mutex_lock(&q->blk_trace_mutex);

-       bt = rcu_dereference_protected(q->blk_trace,
- 
lockdep_is_held(&q->blk_trace_mutex));
+       bt = blk_trace_rcu_deref(q);
         if (attr == &dev_attr_enable) {
                 ret = sprintf(buf, "%u\n", !!bt);
                 goto out_unlock_bdev;
@@ -1881,8 +1885,7 @@ static ssize_t sysfs_blk_trace_attr_store(struct 
device *dev,

         mutex_lock(&q->blk_trace_mutex);

-       bt = rcu_dereference_protected(q->blk_trace,
- 
lockdep_is_held(&q->blk_trace_mutex));
+       bt = blk_trace_rcu_deref(q);
         if (attr == &dev_attr_enable) {
                 if (!!value == !!bt) {
                         ret = 0;

On 02/06/2020 06:28 AM, Jan Kara wrote:
> KASAN is reporting that __blk_add_trace() has a use-after-free issue
> when accessing q->blk_trace. Indeed the switching of block tracing (and
> thus eventual freeing of q->blk_trace) is completely unsynchronized with
> the currently running tracing and thus it can happen that the blk_trace
> structure is being freed just while __blk_add_trace() works on it.
> Protect accesses to q->blk_trace by RCU during tracing and make sure we
> wait for the end of RCU grace period when shutting down tracing. Luckily
> that is rare enough event that we can afford that. Note that postponing
> the freeing of blk_trace to an RCU callback should better be avoided as
> it could have unexpected user visible side-effects as debugfs files
> would be still existing for a short while block tracing has been shut
> down.
>
> Link:https://bugzilla.kernel.org/show_bug.cgi?id=205711
> CC:stable@xxxxxxxxxxxxxxx
> Reported-by: Tristan<tristmd@xxxxxxxxx>
> Signed-off-by: Jan Kara<jack@xxxxxxx>
> ---

[1] https://marc.info/?l=linux-btrace&m=157422391521376&w=2






[Index of Archives]     [Linux Kernel]     [Kernel Development Newbies]     [Linux USB Devel]     [Video for Linux]     [Linux Audio Users]     [Yosemite Hiking]     [Linux Kernel]     [Linux SCSI]

  Powered by Linux