OSDN Git Service

[PATCH] isdn: fix isdn_ioctl memory overrun vulnerability
authorWilly Tarreau <w@1wt.eu>
Sun, 16 Dec 2007 23:10:45 +0000 (00:10 +0100)
committerWilly Tarreau <w@1wt.eu>
Sun, 16 Dec 2007 23:11:53 +0000 (00:11 +0100)
Backport of 2.6 commit eafe1aa37e6ec2d56f14732b5240c4dd09f0613a by Karsten Keil

    I4L: fix isdn_ioctl memory overrun vulnerability

    Fix possible memory overrun issue in the isdn ioctl code.

    Found by ADLAB <adlab@venustech.com.cn>

Signed-off-by: Karsten Keil <kkeil@suse.de>
Cc: ADLAB <adlab@venustech.com.cn>
Cc: <stable@kernel.org>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Signed-off-by: Willy Tarreau <w@1wt.eu>
drivers/isdn/isdn_common.c

index 3155dc8..d251886 100644 (file)
@@ -1442,6 +1442,7 @@ isdn_ioctl(struct inode *inode, struct file *file, uint cmd, ulong arg)
                                        if (copy_from_user((char *) &iocts, (char *) arg,
                                             sizeof(isdn_ioctl_struct)))
                                                return -EFAULT;
+                                       iocts.drvid[sizeof(iocts.drvid)-1] = 0;
                                        if (strlen(iocts.drvid)) {
                                                if ((p = strchr(iocts.drvid, ',')))
                                                        *p = 0;
@@ -1527,6 +1528,7 @@ isdn_ioctl(struct inode *inode, struct file *file, uint cmd, ulong arg)
                                                            (char *) arg,
                                             sizeof(isdn_ioctl_struct)))
                                                return -EFAULT;
+                                       iocts.drvid[sizeof(iocts.drvid)-1] = 0;
                                        if (strlen(iocts.drvid)) {
                                                drvidx = -1;
                                                for (i = 0; i < ISDN_MAX_DRIVERS; i++)
@@ -1571,7 +1573,7 @@ isdn_ioctl(struct inode *inode, struct file *file, uint cmd, ulong arg)
                                        } else {
                                                p = (char *) iocts.arg;
                                                for (i = 0; i < 10; i++) {
-                                                       sprintf(bname, "%s%s",
+                                                       snprintf(bname, sizeof(bname), "%s%s",
                                                                strlen(dev->drv[drvidx]->msn2eaz[i]) ?
                                                                dev->drv[drvidx]->msn2eaz[i] : "_",
                                                                (i < 9) ? "," : "\0");
@@ -1601,6 +1603,7 @@ isdn_ioctl(struct inode *inode, struct file *file, uint cmd, ulong arg)
                                        char *p;
                                        if (copy_from_user((char *) &iocts, (char *) arg, sizeof(isdn_ioctl_struct)))
                                                return -EFAULT;
+                                       iocts.drvid[sizeof(iocts.drvid)-1] = 0;
                                        if (strlen(iocts.drvid)) {
                                                if ((p = strchr(iocts.drvid, ',')))
                                                        *p = 0;