mISDN: make sure device name is NUL terminated
authorDan Carpenter <dan.carpenter@oracle.com>
Wed, 22 May 2019 08:45:13 +0000 (11:45 +0300)
committerDavid S. Miller <davem@davemloft.net>
Thu, 23 May 2019 00:22:14 +0000 (17:22 -0700)
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>
drivers/isdn/mISDN/socket.c

index a14e35d405387d4dc43bf672139c773bf4b05d2f..84e1d4c2db6602155e6e4b842deb177c9edf7467 100644 (file)
@@ -393,7 +393,7 @@ data_sock_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg)
                        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 @@ base_sock_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg)
                        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 @@ base_sock_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg)
                        err = -EFAULT;
                        break;
                }
+               dn.name[sizeof(dn.name) - 1] = '\0';
                dev = get_mdevice(dn.id);
                if (dev)
                        err = device_rename(&dev->dev, dn.name);