On 2021/04/12 19:44, Greg Kroah-Hartman wrote:
> And trying to "open exclusive only" just does not work, the kernel can
> not enforce that at all, sorry.  Any driver that you see trying to do
> that is trivial to work around in userspace, making the kernel code
> pointless.

You mean something like below cannot be used?

diff --git a/drivers/char/ttyprintk.c b/drivers/char/ttyprintk.c
index 6a0059e508e3..57200569918a 100644
--- a/drivers/char/ttyprintk.c
+++ b/drivers/char/ttyprintk.c
@@ -84,14 +84,26 @@ static int tpk_printk(const unsigned char *buf, int count)
        return count;
 }
 
+static DEFINE_MUTEX(open_close_lock);
+
 /*
  * TTY operations open function.
  */
 static int tpk_open(struct tty_struct *tty, struct file *filp)
 {
-       tty->driver_data = &tpk_port;
+       int ret;
+
+       if (mutex_lock_killable(&open_close_lock))
+               return -EINTR;
 
-       return tty_port_open(&tpk_port.port, tty, filp);
+       if (tpk_port.port.count) {
+               ret = -EBUSY;
+       } else {
+               tty->driver_data = &tpk_port;
+               ret = tty_port_open(&tpk_port.port, tty, filp);
+       }
+       mutex_unlock(&open_close_lock);
+       return ret;
 }
 
 /*
@@ -102,12 +114,14 @@ static void tpk_close(struct tty_struct *tty, struct file 
*filp)
        struct ttyprintk_port *tpkp = tty->driver_data;
        unsigned long flags;
 
+       mutex_lock(&open_close_lock);
        spin_lock_irqsave(&tpkp->spinlock, flags);
        /* flush tpk_printk buffer */
        tpk_printk(NULL, 0);
        spin_unlock_irqrestore(&tpkp->spinlock, flags);
 
        tty_port_close(&tpkp->port, tty, filp);
+       mutex_unlock(&open_close_lock);
 }
 
 /*

> Like any tty port, if you have multiple accesses, all bets are off and
> hilarity ensues.  Just don't do that and expect things to be working
> well.

Since syzkaller is a fuzzer, syzkaller happily opens /dev/ttyprintk from
multiple threads. Should we update syzkaller to use CONFIG_TTY_PRINTK=n ?

Reply via email to