Security
Headlines
HeadlinesLatestCVEs

Headline

CVE-2022-45885: [PATCH 1/4] media: dvb-core: Fix use-after-free due to race condition occurring in dvb_frontend

An issue was discovered in the Linux kernel through 6.0.9. drivers/media/dvb-core/dvb_frontend.c has a race condition that can cause a use-after-free when a device is disconnected.

CVE
#vulnerability#linux#git

From: [email protected] To: [email protected] Cc: Hyunwoo Kim [email protected], [email protected], [email protected], [email protected], [email protected], [email protected] Subject: [PATCH 1/4] media: dvb-core: Fix use-after-free due to race condition occurring in dvb_frontend Date: Tue, 15 Nov 2022 05:18:19 -0800 [thread overview] Message-ID: [email protected] (raw) In-Reply-To: <[email protected]>

From: Hyunwoo Kim [email protected]

If the device node of dvb_frontend is open() and the device is disconnected, many kinds of UAFs may occur when calling close() on the device node.

The root cause of this is that wake_up() for dvbdev->wait_queue is implemented in the dvb_frontend_release() function, but wait_event() is not implemented in the dvb_frontend_stop() function.

So, implement wait_event() function in dvb_frontend_stop() and add ‘remove_mutex’ which prevents race condition for 'fe->exit’.

Signed-off-by: Hyunwoo Kim [email protected]

drivers/media/dvb-core/dvb_frontend.c | 39 ++++++++++++++++++++++±— include/media/dvb_frontend.h | 6 +++± 2 files changed, 39 insertions(+), 6 deletions(-)

diff --git a/drivers/media/dvb-core/dvb_frontend.c b/drivers/media/dvb-core/dvb_frontend.c index 48e735cdbe6b…b3556e3580c6 100644 — a/drivers/media/dvb-core/dvb_frontend.c +++ b/drivers/media/dvb-core/dvb_frontend.c @@ -809,6 +809,8 @@ static void dvb_frontend_stop(struct dvb_frontend *fe)

dev\_dbg(fe->dvb->device, "%s:\\n", \_\_func\_\_);
  • mutex_lock(&fe->remove_mutex);

  • if (fe->exit != DVB_FE_DEVICE_REMOVED) fe->exit = DVB_FE_NORMAL_EXIT; mb(); @@ -818,6 +820,13 @@ static void dvb_frontend_stop(struct dvb_frontend *fe)

    kthread_stop(fepriv->thread);

  • mutex_unlock(&fe->remove_mutex);

  • if (fepriv->dvbdev->users < -1) {

  •   wait\_event(fepriv->dvbdev->wait\_queue,
    
  •           fepriv->dvbdev->users == -1);
    
  • }

  • sema_init(&fepriv->sem, 1); fepriv->state = FESTATE_IDLE;

@@ -2750,9 +2759,13 @@ static int dvb_frontend_open(struct inode *inode, struct file *file) struct dvb_adapter *adapter = fe->dvb; int ret;

  • mutex_lock(&fe->remove_mutex);

  • dev_dbg(fe->dvb->device, "%s:\n", __func__); - if (fe->exit == DVB_FE_DEVICE_REMOVED)

  • if (fe->exit == DVB_FE_DEVICE_REMOVED) {

  •   mutex\_unlock(&fe->remove\_mutex);
      return -ENODEV;
    
  • }

    if (adapter->mfe_shared) { mutex_lock(&adapter->mfe_lock); @@ -2773,8 +2786,10 @@ static int dvb_frontend_open(struct inode *inode, struct file *file) while (mferetry-- && (mfedev->users != -1 || mfepriv->thread)) { if (msleep_interruptible(500)) { - if (signal_pending(current))

  •               if (signal\_pending(current)) {
    
  •                   mutex\_unlock(&fe->remove\_mutex);
                      return -EINTR;
    
  •               }
              }
          }
    

@@ -2786,6 +2801,7 @@ static int dvb_frontend_open(struct inode *inode, struct file *file) if (mfedev->users != -1 || mfepriv->thread) { mutex_unlock(&adapter->mfe_lock);

  •               mutex\_unlock(&fe->remove\_mutex);
                  return -EBUSY;
              }
              adapter->mfe\_dvbdev = dvbdev;
    

@@ -2845,6 +2861,8 @@ static int dvb_frontend_open(struct inode *inode, struct file *file)

if (adapter->mfe\_shared)
    mutex\_unlock(&adapter->mfe\_lock);
  • mutex_unlock(&fe->remove_mutex); return ret;

err3: @@ -2866,6 +2884,8 @@ static int dvb_frontend_open(struct inode *inode, struct file *file) err0: if (adapter->mfe_shared) mutex_unlock(&adapter->mfe_lock);

  • mutex_unlock(&fe->remove_mutex); return ret; }

@@ -2876,6 +2896,8 @@ static int dvb_frontend_release(struct inode *inode, struct file *file) struct dvb_frontend_private *fepriv = fe->frontend_priv; int ret;

  • mutex_lock(&fe->remove_mutex);

  • dev_dbg(fe->dvb->device, "%s:\n", __func__);

    if ((file->f_flags & O_ACCMODE) != O_RDONLY) { @@ -2897,11 +2919,17 @@ static int dvb_frontend_release(struct inode *inode, struct file *file) } mutex_unlock(&fe->dvb->mdev_lock); #endif - if (fe->exit != DVB_FE_NO_EXIT)

  •       wake\_up(&dvbdev->wait\_queue);
      if (fe->ops.ts\_bus\_ctrl)
          fe->ops.ts\_bus\_ctrl(fe, 0);
    

- }

  •   if (fe->exit != DVB\_FE\_NO\_EXIT) {
    
  •       mutex\_unlock(&fe->remove\_mutex);
    
  •       wake\_up(&dvbdev->wait\_queue);
    
  •   } else
    
  •       mutex\_unlock(&fe->remove\_mutex);
    
  • } else

  •   mutex\_unlock(&fe->remove\_mutex);
    

    dvb_frontend_put(fe);

@@ -3000,6 +3028,7 @@ int dvb_register_frontend(struct dvb_adapter *dvb, fepriv = fe->frontend_priv;

kref\_init(&fe->refcount);
  • mutex_init(&fe->remove_mutex);

    /* * After initialization, there need to be two references: one diff --git a/include/media/dvb_frontend.h b/include/media/dvb_frontend.h index e7c44870f20d…411ec32cd8df 100644 — a/include/media/dvb_frontend.h +++ b/include/media/dvb_frontend.h @@ -686,7 +686,10 @@ struct dtv_frontend_properties { * @id: Frontend ID * @exit: Used to inform the DVB core that the frontend * thread should exit (usually, means that the hardware - * got disconnected. + * got disconnected.)

  • * @remove_mutex: mutex that avoids a race condition between a callback

  • * called when the hardware is disconnected and the

  • * file_operations of dvb_frontend */

struct dvb_frontend { @@ -704,6 +707,7 @@ struct dvb_frontend { int (*callback)(void *adapter_priv, int component, int cmd, int arg); int id; unsigned int exit;

  • struct mutex remove_mutex; };

/**

2.25.1

next prev parent reply other threads:[~2022-11-15 13:19 UTC|newest]

Thread overview: 6+ messages / expand[flat|nested] mbox.gz Atom feed top 2022-11-15 13:18 [PATCH 0/4] Fix multiple race condition vulnerabilities in dvb-core and device driver imv4bel 2022-11-15 13:18 ` imv4bel [this message] 2022-11-15 13:18 ` [PATCH 2/4] media: dvb-core: Fix use-after-free due to race condition occurring in dvb_net imv4bel 2022-11-15 13:18 ` [PATCH 3/4] media: dvb-core: Fix use-after-free due to race condition occurring in dvb_register_device() imv4bel 2022-11-17 4:16 ` Dan Carpenter 2022-11-15 13:18 ` [PATCH 4/4] media: ttusb-dec: Fix memory leak in ttusb_dec_exit_dvb() imv4bel

Reply instructions:

You may reply publicly to this message via plain-text email using any one of the following methods:

* Save the following mbox file, import it into your mail client, and reply-to-all from there: mbox

Avoid top-posting and favor interleaved quoting: https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the –to, –cc, and –in-reply-to switches of git-send-email(1):

git send-email \ –[email protected] \ –[email protected] \ –[email protected] \ –[email protected] \ –[email protected] \ –[email protected] \ –[email protected] \ –[email protected] \ /path/to/YOUR_REPLY

https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header via mailto: links, try the mailto: link

Be sure your reply has a Subject: header at the top and a blank line before the message body.

This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox; as well as URLs for NNTP newsgroup(s).

Related news

CVE-2022-45886: November 2022 Linux Kernel 6.0.9 Vulnerabilities in NetApp Products

An issue was discovered in the Linux kernel through 6.0.9. drivers/media/dvb-core/dvb_net.c has a .disconnect versus dvb_device_open race condition that leads to a use-after-free.

CVE: Latest News

CVE-2023-50976: Transactions API Authorization by oleiman · Pull Request #14969 · redpanda-data/redpanda
CVE-2023-6905
CVE-2023-6903
CVE-2023-6904
CVE-2023-3907