aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAlan Cox <alan@lxorguk.ukuu.org.uk>2008-07-25 04:48:15 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2008-07-25 13:53:43 -0400
commit11af7478addd34c42999b3b84095903ed9e67038 (patch)
tree90f5fb01fe1b49cef020c275f448d7eed2fbe3a9
parentf6759fdcfd79ff1827fd5d4ddfe876164466d30d (diff)
sx: push BKL down into the firmware ioctl handler
Also fix the capability checking for firmware load. Signed-off-by: Alan Cox <alan@redhat.com> Cc: Jiri Slaby <jirislaby@gmail.com> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
-rw-r--r--drivers/char/sx.c73
1 files changed, 43 insertions, 30 deletions
diff --git a/drivers/char/sx.c b/drivers/char/sx.c
index 2162439bbe48..c385206f9db5 100644
--- a/drivers/char/sx.c
+++ b/drivers/char/sx.c
@@ -286,8 +286,8 @@ static void sx_close(void *ptr);
286static int sx_chars_in_buffer(void *ptr); 286static int sx_chars_in_buffer(void *ptr);
287static int sx_init_board(struct sx_board *board); 287static int sx_init_board(struct sx_board *board);
288static int sx_init_portstructs(int nboards, int nports); 288static int sx_init_portstructs(int nboards, int nports);
289static int sx_fw_ioctl(struct inode *inode, struct file *filp, 289static long sx_fw_ioctl(struct file *filp, unsigned int cmd,
290 unsigned int cmd, unsigned long arg); 290 unsigned long arg);
291static int sx_init_drivers(void); 291static int sx_init_drivers(void);
292 292
293static struct tty_driver *sx_driver; 293static struct tty_driver *sx_driver;
@@ -396,7 +396,7 @@ static struct real_driver sx_real_driver = {
396 396
397static const struct file_operations sx_fw_fops = { 397static const struct file_operations sx_fw_fops = {
398 .owner = THIS_MODULE, 398 .owner = THIS_MODULE,
399 .ioctl = sx_fw_ioctl, 399 .unlocked_ioctl = sx_fw_ioctl,
400}; 400};
401 401
402static struct miscdevice sx_fw_device = { 402static struct miscdevice sx_fw_device = {
@@ -1686,10 +1686,10 @@ static int do_memtest_w(struct sx_board *board, int min, int max)
1686} 1686}
1687#endif 1687#endif
1688 1688
1689static int sx_fw_ioctl(struct inode *inode, struct file *filp, 1689static long sx_fw_ioctl(struct file *filp, unsigned int cmd,
1690 unsigned int cmd, unsigned long arg) 1690 unsigned long arg)
1691{ 1691{
1692 int rc = 0; 1692 long rc = 0;
1693 int __user *descr = (int __user *)arg; 1693 int __user *descr = (int __user *)arg;
1694 int i; 1694 int i;
1695 static struct sx_board *board = NULL; 1695 static struct sx_board *board = NULL;
@@ -1699,13 +1699,10 @@ static int sx_fw_ioctl(struct inode *inode, struct file *filp,
1699 1699
1700 func_enter(); 1700 func_enter();
1701 1701
1702#if 0 1702 if (!capable(CAP_SYS_RAWIO))
1703 /* Removed superuser check: Sysops can use the permissions on the device
1704 file to restrict access. Recommendation: Root only. (root.root 600) */
1705 if (!capable(CAP_SYS_ADMIN)) {
1706 return -EPERM; 1703 return -EPERM;
1707 } 1704
1708#endif 1705 lock_kernel();
1709 1706
1710 sx_dprintk(SX_DEBUG_FIRMWARE, "IOCTL %x: %lx\n", cmd, arg); 1707 sx_dprintk(SX_DEBUG_FIRMWARE, "IOCTL %x: %lx\n", cmd, arg);
1711 1708
@@ -1720,19 +1717,23 @@ static int sx_fw_ioctl(struct inode *inode, struct file *filp,
1720 for (i = 0; i < SX_NBOARDS; i++) 1717 for (i = 0; i < SX_NBOARDS; i++)
1721 sx_dprintk(SX_DEBUG_FIRMWARE, "<%x> ", boards[i].flags); 1718 sx_dprintk(SX_DEBUG_FIRMWARE, "<%x> ", boards[i].flags);
1722 sx_dprintk(SX_DEBUG_FIRMWARE, "\n"); 1719 sx_dprintk(SX_DEBUG_FIRMWARE, "\n");
1720 unlock_kernel();
1723 return -EIO; 1721 return -EIO;
1724 } 1722 }
1725 1723
1726 switch (cmd) { 1724 switch (cmd) {
1727 case SXIO_SET_BOARD: 1725 case SXIO_SET_BOARD:
1728 sx_dprintk(SX_DEBUG_FIRMWARE, "set board to %ld\n", arg); 1726 sx_dprintk(SX_DEBUG_FIRMWARE, "set board to %ld\n", arg);
1727 rc = -EIO;
1729 if (arg >= SX_NBOARDS) 1728 if (arg >= SX_NBOARDS)
1730 return -EIO; 1729 break;
1731 sx_dprintk(SX_DEBUG_FIRMWARE, "not out of range\n"); 1730 sx_dprintk(SX_DEBUG_FIRMWARE, "not out of range\n");
1732 if (!(boards[arg].flags & SX_BOARD_PRESENT)) 1731 if (!(boards[arg].flags & SX_BOARD_PRESENT))
1733 return -EIO; 1732 break;
1734 sx_dprintk(SX_DEBUG_FIRMWARE, ".. and present!\n"); 1733 sx_dprintk(SX_DEBUG_FIRMWARE, ".. and present!\n");
1735 board = &boards[arg]; 1734 board = &boards[arg];
1735 rc = 0;
1736 /* FIXME: And this does ... nothing?? */
1736 break; 1737 break;
1737 case SXIO_GET_TYPE: 1738 case SXIO_GET_TYPE:
1738 rc = -ENOENT; /* If we manage to miss one, return error. */ 1739 rc = -ENOENT; /* If we manage to miss one, return error. */
@@ -1746,7 +1747,7 @@ static int sx_fw_ioctl(struct inode *inode, struct file *filp,
1746 rc = SX_TYPE_SI; 1747 rc = SX_TYPE_SI;
1747 if (IS_EISA_BOARD(board)) 1748 if (IS_EISA_BOARD(board))
1748 rc = SX_TYPE_SI; 1749 rc = SX_TYPE_SI;
1749 sx_dprintk(SX_DEBUG_FIRMWARE, "returning type= %d\n", rc); 1750 sx_dprintk(SX_DEBUG_FIRMWARE, "returning type= %ld\n", rc);
1750 break; 1751 break;
1751 case SXIO_DO_RAMTEST: 1752 case SXIO_DO_RAMTEST:
1752 if (sx_initialized) /* Already initialized: better not ramtest the board. */ 1753 if (sx_initialized) /* Already initialized: better not ramtest the board. */
@@ -1760,19 +1761,26 @@ static int sx_fw_ioctl(struct inode *inode, struct file *filp,
1760 rc = do_memtest(board, 0, 0x7ff8); 1761 rc = do_memtest(board, 0, 0x7ff8);
1761 /* if (!rc) rc = do_memtest_w (board, 0, 0x7ff8); */ 1762 /* if (!rc) rc = do_memtest_w (board, 0, 0x7ff8); */
1762 } 1763 }
1763 sx_dprintk(SX_DEBUG_FIRMWARE, "returning memtest result= %d\n", 1764 sx_dprintk(SX_DEBUG_FIRMWARE,
1764 rc); 1765 "returning memtest result= %ld\n", rc);
1765 break; 1766 break;
1766 case SXIO_DOWNLOAD: 1767 case SXIO_DOWNLOAD:
1767 if (sx_initialized) /* Already initialized */ 1768 if (sx_initialized) {/* Already initialized */
1768 return -EEXIST; 1769 rc = -EEXIST;
1769 if (!sx_reset(board)) 1770 break;
1770 return -EIO; 1771 }
1772 if (!sx_reset(board)) {
1773 rc = -EIO;
1774 break;
1775 }
1771 sx_dprintk(SX_DEBUG_INIT, "reset the board...\n"); 1776 sx_dprintk(SX_DEBUG_INIT, "reset the board...\n");
1772 1777
1773 tmp = kmalloc(SX_CHUNK_SIZE, GFP_USER); 1778 tmp = kmalloc(SX_CHUNK_SIZE, GFP_USER);
1774 if (!tmp) 1779 if (!tmp) {
1775 return -ENOMEM; 1780 rc = -ENOMEM;
1781 break;
1782 }
1783 /* FIXME: check returns */
1776 get_user(nbytes, descr++); 1784 get_user(nbytes, descr++);
1777 get_user(offset, descr++); 1785 get_user(offset, descr++);
1778 get_user(data, descr++); 1786 get_user(data, descr++);
@@ -1782,7 +1790,8 @@ static int sx_fw_ioctl(struct inode *inode, struct file *filp,
1782 (i + SX_CHUNK_SIZE > nbytes) ? 1790 (i + SX_CHUNK_SIZE > nbytes) ?
1783 nbytes - i : SX_CHUNK_SIZE)) { 1791 nbytes - i : SX_CHUNK_SIZE)) {
1784 kfree(tmp); 1792 kfree(tmp);
1785 return -EFAULT; 1793 rc = -EFAULT;
1794 break;
1786 } 1795 }
1787 memcpy_toio(board->base2 + offset + i, tmp, 1796 memcpy_toio(board->base2 + offset + i, tmp,
1788 (i + SX_CHUNK_SIZE > nbytes) ? 1797 (i + SX_CHUNK_SIZE > nbytes) ?
@@ -1798,13 +1807,17 @@ static int sx_fw_ioctl(struct inode *inode, struct file *filp,
1798 rc = sx_nports; 1807 rc = sx_nports;
1799 break; 1808 break;
1800 case SXIO_INIT: 1809 case SXIO_INIT:
1801 if (sx_initialized) /* Already initialized */ 1810 if (sx_initialized) { /* Already initialized */
1802 return -EEXIST; 1811 rc = -EEXIST;
1812 break;
1813 }
1803 /* This is not allowed until all boards are initialized... */ 1814 /* This is not allowed until all boards are initialized... */
1804 for (i = 0; i < SX_NBOARDS; i++) { 1815 for (i = 0; i < SX_NBOARDS; i++) {
1805 if ((boards[i].flags & SX_BOARD_PRESENT) && 1816 if ((boards[i].flags & SX_BOARD_PRESENT) &&
1806 !(boards[i].flags & SX_BOARD_INITIALIZED)) 1817 !(boards[i].flags & SX_BOARD_INITIALIZED)) {
1807 return -EIO; 1818 rc = -EIO;
1819 break;
1820 }
1808 } 1821 }
1809 for (i = 0; i < SX_NBOARDS; i++) 1822 for (i = 0; i < SX_NBOARDS; i++)
1810 if (!(boards[i].flags & SX_BOARD_PRESENT)) 1823 if (!(boards[i].flags & SX_BOARD_PRESENT))
@@ -1832,10 +1845,10 @@ static int sx_fw_ioctl(struct inode *inode, struct file *filp,
1832 rc = sx_nports; 1845 rc = sx_nports;
1833 break; 1846 break;
1834 default: 1847 default:
1835 printk(KERN_WARNING "Unknown ioctl on firmware device (%x).\n", 1848 rc = -ENOTTY;
1836 cmd);
1837 break; 1849 break;
1838 } 1850 }
1851 unlock_kernel();
1839 func_exit(); 1852 func_exit();
1840 return rc; 1853 return rc;
1841} 1854}