mISDN: make sure device name is NUL terminated [Linux 5.2]

mISDN: make sure device name is NUL terminated [Linux 5.2]

This Linux kernel change "mISDN: make sure device name is NUL terminated" is included in the Linux 5.2 release. This change is authored by Dan Carpenter <dan.carpenter [at] oracle.com> on Wed May 22 11:45:13 2019 +0300. The commit for this change in Linux stable tree is ccfb62f (patch).

mISDN: make sure device name is NUL terminated

The user can change the device_name with the IMSETDEVNAME ioctl, but we
need to ensure that the user's name is NUL terminated.  Otherwise it
could result in a buffer overflow when we copy the name back to the user
with IMGETDEVINFO ioctl.

I also changed two strcpy() calls which handle the name to strscpy().
Hopefully, there aren't any other ways to create a too long name, but
it's nice to do this as a kernel hardening measure.

Signed-off-by: Dan Carpenter <dan.carpenter@oracle.com>
Signed-off-by: David S. Miller <davem@davemloft.net>

There are 5 lines of Linux source code added/deleted in this change. Code changes to Linux kernel are as follows.

 drivers/isdn/mISDN/socket.c | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/drivers/isdn/mISDN/socket.c b/drivers/isdn/mISDN/socket.c
index a14e35d..84e1d4c 100644
--- a/drivers/isdn/mISDN/socket.c
+++ b/drivers/isdn/mISDN/socket.c
@@ -393,7 +393,7 @@ static void mISDN_sock_unlink(struct mISDN_sock_list *l, struct sock *sk)
            memcpy(di.channelmap, dev->channelmap,
                   sizeof(di.channelmap));
            di.nrbchan = dev->nrbchan;
-           strcpy(di.name, dev_name(&dev->dev));
+           strscpy(di.name, dev_name(&dev->dev), sizeof(di.name));
            if (copy_to_user((void __user *)arg, &di, sizeof(di)))
                err = -EFAULT;
        } else
@@ -676,7 +676,7 @@ static int data_sock_getsockopt(struct socket *sock, int level, int optname,
            memcpy(di.channelmap, dev->channelmap,
                   sizeof(di.channelmap));
            di.nrbchan = dev->nrbchan;
-           strcpy(di.name, dev_name(&dev->dev));
+           strscpy(di.name, dev_name(&dev->dev), sizeof(di.name));
            if (copy_to_user((void __user *)arg, &di, sizeof(di)))
                err = -EFAULT;
        } else
@@ -690,6 +690,7 @@ static int data_sock_getsockopt(struct socket *sock, int level, int optname,
            err = -EFAULT;
            break;
        }
+       dn.name[sizeof(dn.name) - 1] = '\0';
        dev = get_mdevice(dn.id);
        if (dev)
            err = device_rename(&dev->dev, dn.name);

Leave a Reply

Your email address will not be published. Required fields are marked *