diff options
Diffstat (limited to 'fs/namei.c')
-rw-r--r-- | fs/namei.c | 344 |
1 files changed, 244 insertions, 100 deletions
diff --git a/fs/namei.c b/fs/namei.c index 941c8e8228c0..e179f71bfcb0 100644 --- a/fs/namei.c +++ b/fs/namei.c | |||
@@ -106,7 +106,7 @@ | |||
106 | * any extra contention... | 106 | * any extra contention... |
107 | */ | 107 | */ |
108 | 108 | ||
109 | static int link_path_walk(const char *name, struct nameidata *nd); | 109 | static int __link_path_walk(const char *name, struct nameidata *nd); |
110 | 110 | ||
111 | /* In order to reduce some races, while at the same time doing additional | 111 | /* In order to reduce some races, while at the same time doing additional |
112 | * checking and hopefully speeding things up, we copy filenames to the | 112 | * checking and hopefully speeding things up, we copy filenames to the |
@@ -563,6 +563,37 @@ walk_init_root(const char *name, struct nameidata *nd) | |||
563 | return 1; | 563 | return 1; |
564 | } | 564 | } |
565 | 565 | ||
566 | /* | ||
567 | * Wrapper to retry pathname resolution whenever the underlying | ||
568 | * file system returns an ESTALE. | ||
569 | * | ||
570 | * Retry the whole path once, forcing real lookup requests | ||
571 | * instead of relying on the dcache. | ||
572 | */ | ||
573 | static __always_inline int link_path_walk(const char *name, struct nameidata *nd) | ||
574 | { | ||
575 | struct path save = nd->path; | ||
576 | int result; | ||
577 | |||
578 | /* make sure the stuff we saved doesn't go away */ | ||
579 | dget(save.dentry); | ||
580 | mntget(save.mnt); | ||
581 | |||
582 | result = __link_path_walk(name, nd); | ||
583 | if (result == -ESTALE) { | ||
584 | /* nd->path had been dropped */ | ||
585 | nd->path = save; | ||
586 | dget(nd->path.dentry); | ||
587 | mntget(nd->path.mnt); | ||
588 | nd->flags |= LOOKUP_REVAL; | ||
589 | result = __link_path_walk(name, nd); | ||
590 | } | ||
591 | |||
592 | path_put(&save); | ||
593 | |||
594 | return result; | ||
595 | } | ||
596 | |||
566 | static __always_inline int __vfs_follow_link(struct nameidata *nd, const char *link) | 597 | static __always_inline int __vfs_follow_link(struct nameidata *nd, const char *link) |
567 | { | 598 | { |
568 | int res = 0; | 599 | int res = 0; |
@@ -1020,36 +1051,6 @@ return_err: | |||
1020 | return err; | 1051 | return err; |
1021 | } | 1052 | } |
1022 | 1053 | ||
1023 | /* | ||
1024 | * Wrapper to retry pathname resolution whenever the underlying | ||
1025 | * file system returns an ESTALE. | ||
1026 | * | ||
1027 | * Retry the whole path once, forcing real lookup requests | ||
1028 | * instead of relying on the dcache. | ||
1029 | */ | ||
1030 | static int link_path_walk(const char *name, struct nameidata *nd) | ||
1031 | { | ||
1032 | struct nameidata save = *nd; | ||
1033 | int result; | ||
1034 | |||
1035 | /* make sure the stuff we saved doesn't go away */ | ||
1036 | dget(save.path.dentry); | ||
1037 | mntget(save.path.mnt); | ||
1038 | |||
1039 | result = __link_path_walk(name, nd); | ||
1040 | if (result == -ESTALE) { | ||
1041 | *nd = save; | ||
1042 | dget(nd->path.dentry); | ||
1043 | mntget(nd->path.mnt); | ||
1044 | nd->flags |= LOOKUP_REVAL; | ||
1045 | result = __link_path_walk(name, nd); | ||
1046 | } | ||
1047 | |||
1048 | path_put(&save.path); | ||
1049 | |||
1050 | return result; | ||
1051 | } | ||
1052 | |||
1053 | static int path_walk(const char *name, struct nameidata *nd) | 1054 | static int path_walk(const char *name, struct nameidata *nd) |
1054 | { | 1055 | { |
1055 | current->total_link_count = 0; | 1056 | current->total_link_count = 0; |
@@ -1364,13 +1365,13 @@ static int __lookup_one_len(const char *name, struct qstr *this, | |||
1364 | } | 1365 | } |
1365 | 1366 | ||
1366 | /** | 1367 | /** |
1367 | * lookup_one_len: filesystem helper to lookup single pathname component | 1368 | * lookup_one_len - filesystem helper to lookup single pathname component |
1368 | * @name: pathname component to lookup | 1369 | * @name: pathname component to lookup |
1369 | * @base: base directory to lookup from | 1370 | * @base: base directory to lookup from |
1370 | * @len: maximum length @len should be interpreted to | 1371 | * @len: maximum length @len should be interpreted to |
1371 | * | 1372 | * |
1372 | * Note that this routine is purely a helper for filesystem useage and should | 1373 | * Note that this routine is purely a helper for filesystem usage and should |
1373 | * not be called by generic code. Also note that by using this function to | 1374 | * not be called by generic code. Also note that by using this function the |
1374 | * nameidata argument is passed to the filesystem methods and a filesystem | 1375 | * nameidata argument is passed to the filesystem methods and a filesystem |
1375 | * using this helper needs to be prepared for that. | 1376 | * using this helper needs to be prepared for that. |
1376 | */ | 1377 | */ |
@@ -1622,8 +1623,7 @@ int may_open(struct nameidata *nd, int acc_mode, int flag) | |||
1622 | return -EACCES; | 1623 | return -EACCES; |
1623 | 1624 | ||
1624 | flag &= ~O_TRUNC; | 1625 | flag &= ~O_TRUNC; |
1625 | } else if (IS_RDONLY(inode) && (acc_mode & MAY_WRITE)) | 1626 | } |
1626 | return -EROFS; | ||
1627 | 1627 | ||
1628 | error = vfs_permission(nd, acc_mode); | 1628 | error = vfs_permission(nd, acc_mode); |
1629 | if (error) | 1629 | if (error) |
@@ -1676,7 +1676,12 @@ int may_open(struct nameidata *nd, int acc_mode, int flag) | |||
1676 | return 0; | 1676 | return 0; |
1677 | } | 1677 | } |
1678 | 1678 | ||
1679 | static int open_namei_create(struct nameidata *nd, struct path *path, | 1679 | /* |
1680 | * Be careful about ever adding any more callers of this | ||
1681 | * function. Its flags must be in the namei format, not | ||
1682 | * what get passed to sys_open(). | ||
1683 | */ | ||
1684 | static int __open_namei_create(struct nameidata *nd, struct path *path, | ||
1680 | int flag, int mode) | 1685 | int flag, int mode) |
1681 | { | 1686 | { |
1682 | int error; | 1687 | int error; |
@@ -1695,26 +1700,56 @@ static int open_namei_create(struct nameidata *nd, struct path *path, | |||
1695 | } | 1700 | } |
1696 | 1701 | ||
1697 | /* | 1702 | /* |
1698 | * open_namei() | 1703 | * Note that while the flag value (low two bits) for sys_open means: |
1704 | * 00 - read-only | ||
1705 | * 01 - write-only | ||
1706 | * 10 - read-write | ||
1707 | * 11 - special | ||
1708 | * it is changed into | ||
1709 | * 00 - no permissions needed | ||
1710 | * 01 - read-permission | ||
1711 | * 10 - write-permission | ||
1712 | * 11 - read-write | ||
1713 | * for the internal routines (ie open_namei()/follow_link() etc) | ||
1714 | * This is more logical, and also allows the 00 "no perm needed" | ||
1715 | * to be used for symlinks (where the permissions are checked | ||
1716 | * later). | ||
1699 | * | 1717 | * |
1700 | * namei for open - this is in fact almost the whole open-routine. | 1718 | */ |
1701 | * | 1719 | static inline int open_to_namei_flags(int flag) |
1702 | * Note that the low bits of "flag" aren't the same as in the open | 1720 | { |
1703 | * system call - they are 00 - no permissions needed | 1721 | if ((flag+1) & O_ACCMODE) |
1704 | * 01 - read permission needed | 1722 | flag++; |
1705 | * 10 - write permission needed | 1723 | return flag; |
1706 | * 11 - read/write permissions needed | 1724 | } |
1707 | * which is a lot more logical, and also allows the "no perm" needed | 1725 | |
1708 | * for symlinks (where the permissions are checked later). | 1726 | static int open_will_write_to_fs(int flag, struct inode *inode) |
1709 | * SMP-safe | 1727 | { |
1728 | /* | ||
1729 | * We'll never write to the fs underlying | ||
1730 | * a device file. | ||
1731 | */ | ||
1732 | if (special_file(inode->i_mode)) | ||
1733 | return 0; | ||
1734 | return (flag & O_TRUNC); | ||
1735 | } | ||
1736 | |||
1737 | /* | ||
1738 | * Note that the low bits of the passed in "open_flag" | ||
1739 | * are not the same as in the local variable "flag". See | ||
1740 | * open_to_namei_flags() for more details. | ||
1710 | */ | 1741 | */ |
1711 | int open_namei(int dfd, const char *pathname, int flag, | 1742 | struct file *do_filp_open(int dfd, const char *pathname, |
1712 | int mode, struct nameidata *nd) | 1743 | int open_flag, int mode) |
1713 | { | 1744 | { |
1745 | struct file *filp; | ||
1746 | struct nameidata nd; | ||
1714 | int acc_mode, error; | 1747 | int acc_mode, error; |
1715 | struct path path; | 1748 | struct path path; |
1716 | struct dentry *dir; | 1749 | struct dentry *dir; |
1717 | int count = 0; | 1750 | int count = 0; |
1751 | int will_write; | ||
1752 | int flag = open_to_namei_flags(open_flag); | ||
1718 | 1753 | ||
1719 | acc_mode = ACC_MODE(flag); | 1754 | acc_mode = ACC_MODE(flag); |
1720 | 1755 | ||
@@ -1732,18 +1767,19 @@ int open_namei(int dfd, const char *pathname, int flag, | |||
1732 | */ | 1767 | */ |
1733 | if (!(flag & O_CREAT)) { | 1768 | if (!(flag & O_CREAT)) { |
1734 | error = path_lookup_open(dfd, pathname, lookup_flags(flag), | 1769 | error = path_lookup_open(dfd, pathname, lookup_flags(flag), |
1735 | nd, flag); | 1770 | &nd, flag); |
1736 | if (error) | 1771 | if (error) |
1737 | return error; | 1772 | return ERR_PTR(error); |
1738 | goto ok; | 1773 | goto ok; |
1739 | } | 1774 | } |
1740 | 1775 | ||
1741 | /* | 1776 | /* |
1742 | * Create - we need to know the parent. | 1777 | * Create - we need to know the parent. |
1743 | */ | 1778 | */ |
1744 | error = path_lookup_create(dfd,pathname,LOOKUP_PARENT,nd,flag,mode); | 1779 | error = path_lookup_create(dfd, pathname, LOOKUP_PARENT, |
1780 | &nd, flag, mode); | ||
1745 | if (error) | 1781 | if (error) |
1746 | return error; | 1782 | return ERR_PTR(error); |
1747 | 1783 | ||
1748 | /* | 1784 | /* |
1749 | * We have the parent and last component. First of all, check | 1785 | * We have the parent and last component. First of all, check |
@@ -1751,14 +1787,14 @@ int open_namei(int dfd, const char *pathname, int flag, | |||
1751 | * will not do. | 1787 | * will not do. |
1752 | */ | 1788 | */ |
1753 | error = -EISDIR; | 1789 | error = -EISDIR; |
1754 | if (nd->last_type != LAST_NORM || nd->last.name[nd->last.len]) | 1790 | if (nd.last_type != LAST_NORM || nd.last.name[nd.last.len]) |
1755 | goto exit; | 1791 | goto exit; |
1756 | 1792 | ||
1757 | dir = nd->path.dentry; | 1793 | dir = nd.path.dentry; |
1758 | nd->flags &= ~LOOKUP_PARENT; | 1794 | nd.flags &= ~LOOKUP_PARENT; |
1759 | mutex_lock(&dir->d_inode->i_mutex); | 1795 | mutex_lock(&dir->d_inode->i_mutex); |
1760 | path.dentry = lookup_hash(nd); | 1796 | path.dentry = lookup_hash(&nd); |
1761 | path.mnt = nd->path.mnt; | 1797 | path.mnt = nd.path.mnt; |
1762 | 1798 | ||
1763 | do_last: | 1799 | do_last: |
1764 | error = PTR_ERR(path.dentry); | 1800 | error = PTR_ERR(path.dentry); |
@@ -1767,18 +1803,31 @@ do_last: | |||
1767 | goto exit; | 1803 | goto exit; |
1768 | } | 1804 | } |
1769 | 1805 | ||
1770 | if (IS_ERR(nd->intent.open.file)) { | 1806 | if (IS_ERR(nd.intent.open.file)) { |
1771 | mutex_unlock(&dir->d_inode->i_mutex); | 1807 | error = PTR_ERR(nd.intent.open.file); |
1772 | error = PTR_ERR(nd->intent.open.file); | 1808 | goto exit_mutex_unlock; |
1773 | goto exit_dput; | ||
1774 | } | 1809 | } |
1775 | 1810 | ||
1776 | /* Negative dentry, just create the file */ | 1811 | /* Negative dentry, just create the file */ |
1777 | if (!path.dentry->d_inode) { | 1812 | if (!path.dentry->d_inode) { |
1778 | error = open_namei_create(nd, &path, flag, mode); | 1813 | /* |
1814 | * This write is needed to ensure that a | ||
1815 | * ro->rw transition does not occur between | ||
1816 | * the time when the file is created and when | ||
1817 | * a permanent write count is taken through | ||
1818 | * the 'struct file' in nameidata_to_filp(). | ||
1819 | */ | ||
1820 | error = mnt_want_write(nd.path.mnt); | ||
1779 | if (error) | 1821 | if (error) |
1822 | goto exit_mutex_unlock; | ||
1823 | error = __open_namei_create(&nd, &path, flag, mode); | ||
1824 | if (error) { | ||
1825 | mnt_drop_write(nd.path.mnt); | ||
1780 | goto exit; | 1826 | goto exit; |
1781 | return 0; | 1827 | } |
1828 | filp = nameidata_to_filp(&nd, open_flag); | ||
1829 | mnt_drop_write(nd.path.mnt); | ||
1830 | return filp; | ||
1782 | } | 1831 | } |
1783 | 1832 | ||
1784 | /* | 1833 | /* |
@@ -1803,23 +1852,52 @@ do_last: | |||
1803 | if (path.dentry->d_inode->i_op && path.dentry->d_inode->i_op->follow_link) | 1852 | if (path.dentry->d_inode->i_op && path.dentry->d_inode->i_op->follow_link) |
1804 | goto do_link; | 1853 | goto do_link; |
1805 | 1854 | ||
1806 | path_to_nameidata(&path, nd); | 1855 | path_to_nameidata(&path, &nd); |
1807 | error = -EISDIR; | 1856 | error = -EISDIR; |
1808 | if (path.dentry->d_inode && S_ISDIR(path.dentry->d_inode->i_mode)) | 1857 | if (path.dentry->d_inode && S_ISDIR(path.dentry->d_inode->i_mode)) |
1809 | goto exit; | 1858 | goto exit; |
1810 | ok: | 1859 | ok: |
1811 | error = may_open(nd, acc_mode, flag); | 1860 | /* |
1812 | if (error) | 1861 | * Consider: |
1862 | * 1. may_open() truncates a file | ||
1863 | * 2. a rw->ro mount transition occurs | ||
1864 | * 3. nameidata_to_filp() fails due to | ||
1865 | * the ro mount. | ||
1866 | * That would be inconsistent, and should | ||
1867 | * be avoided. Taking this mnt write here | ||
1868 | * ensures that (2) can not occur. | ||
1869 | */ | ||
1870 | will_write = open_will_write_to_fs(flag, nd.path.dentry->d_inode); | ||
1871 | if (will_write) { | ||
1872 | error = mnt_want_write(nd.path.mnt); | ||
1873 | if (error) | ||
1874 | goto exit; | ||
1875 | } | ||
1876 | error = may_open(&nd, acc_mode, flag); | ||
1877 | if (error) { | ||
1878 | if (will_write) | ||
1879 | mnt_drop_write(nd.path.mnt); | ||
1813 | goto exit; | 1880 | goto exit; |
1814 | return 0; | 1881 | } |
1882 | filp = nameidata_to_filp(&nd, open_flag); | ||
1883 | /* | ||
1884 | * It is now safe to drop the mnt write | ||
1885 | * because the filp has had a write taken | ||
1886 | * on its behalf. | ||
1887 | */ | ||
1888 | if (will_write) | ||
1889 | mnt_drop_write(nd.path.mnt); | ||
1890 | return filp; | ||
1815 | 1891 | ||
1892 | exit_mutex_unlock: | ||
1893 | mutex_unlock(&dir->d_inode->i_mutex); | ||
1816 | exit_dput: | 1894 | exit_dput: |
1817 | path_put_conditional(&path, nd); | 1895 | path_put_conditional(&path, &nd); |
1818 | exit: | 1896 | exit: |
1819 | if (!IS_ERR(nd->intent.open.file)) | 1897 | if (!IS_ERR(nd.intent.open.file)) |
1820 | release_open_intent(nd); | 1898 | release_open_intent(&nd); |
1821 | path_put(&nd->path); | 1899 | path_put(&nd.path); |
1822 | return error; | 1900 | return ERR_PTR(error); |
1823 | 1901 | ||
1824 | do_link: | 1902 | do_link: |
1825 | error = -ELOOP; | 1903 | error = -ELOOP; |
@@ -1835,43 +1913,60 @@ do_link: | |||
1835 | * stored in nd->last.name and we will have to putname() it when we | 1913 | * stored in nd->last.name and we will have to putname() it when we |
1836 | * are done. Procfs-like symlinks just set LAST_BIND. | 1914 | * are done. Procfs-like symlinks just set LAST_BIND. |
1837 | */ | 1915 | */ |
1838 | nd->flags |= LOOKUP_PARENT; | 1916 | nd.flags |= LOOKUP_PARENT; |
1839 | error = security_inode_follow_link(path.dentry, nd); | 1917 | error = security_inode_follow_link(path.dentry, &nd); |
1840 | if (error) | 1918 | if (error) |
1841 | goto exit_dput; | 1919 | goto exit_dput; |
1842 | error = __do_follow_link(&path, nd); | 1920 | error = __do_follow_link(&path, &nd); |
1843 | if (error) { | 1921 | if (error) { |
1844 | /* Does someone understand code flow here? Or it is only | 1922 | /* Does someone understand code flow here? Or it is only |
1845 | * me so stupid? Anathema to whoever designed this non-sense | 1923 | * me so stupid? Anathema to whoever designed this non-sense |
1846 | * with "intent.open". | 1924 | * with "intent.open". |
1847 | */ | 1925 | */ |
1848 | release_open_intent(nd); | 1926 | release_open_intent(&nd); |
1849 | return error; | 1927 | return ERR_PTR(error); |
1850 | } | 1928 | } |
1851 | nd->flags &= ~LOOKUP_PARENT; | 1929 | nd.flags &= ~LOOKUP_PARENT; |
1852 | if (nd->last_type == LAST_BIND) | 1930 | if (nd.last_type == LAST_BIND) |
1853 | goto ok; | 1931 | goto ok; |
1854 | error = -EISDIR; | 1932 | error = -EISDIR; |
1855 | if (nd->last_type != LAST_NORM) | 1933 | if (nd.last_type != LAST_NORM) |
1856 | goto exit; | 1934 | goto exit; |
1857 | if (nd->last.name[nd->last.len]) { | 1935 | if (nd.last.name[nd.last.len]) { |
1858 | __putname(nd->last.name); | 1936 | __putname(nd.last.name); |
1859 | goto exit; | 1937 | goto exit; |
1860 | } | 1938 | } |
1861 | error = -ELOOP; | 1939 | error = -ELOOP; |
1862 | if (count++==32) { | 1940 | if (count++==32) { |
1863 | __putname(nd->last.name); | 1941 | __putname(nd.last.name); |
1864 | goto exit; | 1942 | goto exit; |
1865 | } | 1943 | } |
1866 | dir = nd->path.dentry; | 1944 | dir = nd.path.dentry; |
1867 | mutex_lock(&dir->d_inode->i_mutex); | 1945 | mutex_lock(&dir->d_inode->i_mutex); |
1868 | path.dentry = lookup_hash(nd); | 1946 | path.dentry = lookup_hash(&nd); |
1869 | path.mnt = nd->path.mnt; | 1947 | path.mnt = nd.path.mnt; |
1870 | __putname(nd->last.name); | 1948 | __putname(nd.last.name); |
1871 | goto do_last; | 1949 | goto do_last; |
1872 | } | 1950 | } |
1873 | 1951 | ||
1874 | /** | 1952 | /** |
1953 | * filp_open - open file and return file pointer | ||
1954 | * | ||
1955 | * @filename: path to open | ||
1956 | * @flags: open flags as per the open(2) second argument | ||
1957 | * @mode: mode for the new file if O_CREAT is set, else ignored | ||
1958 | * | ||
1959 | * This is the helper to open a file from kernelspace if you really | ||
1960 | * have to. But in generally you should not do this, so please move | ||
1961 | * along, nothing to see here.. | ||
1962 | */ | ||
1963 | struct file *filp_open(const char *filename, int flags, int mode) | ||
1964 | { | ||
1965 | return do_filp_open(AT_FDCWD, filename, flags, mode); | ||
1966 | } | ||
1967 | EXPORT_SYMBOL(filp_open); | ||
1968 | |||
1969 | /** | ||
1875 | * lookup_create - lookup a dentry, creating it if it doesn't exist | 1970 | * lookup_create - lookup a dentry, creating it if it doesn't exist |
1876 | * @nd: nameidata info | 1971 | * @nd: nameidata info |
1877 | * @is_dir: directory flag | 1972 | * @is_dir: directory flag |
@@ -1944,6 +2039,23 @@ int vfs_mknod(struct inode *dir, struct dentry *dentry, int mode, dev_t dev) | |||
1944 | return error; | 2039 | return error; |
1945 | } | 2040 | } |
1946 | 2041 | ||
2042 | static int may_mknod(mode_t mode) | ||
2043 | { | ||
2044 | switch (mode & S_IFMT) { | ||
2045 | case S_IFREG: | ||
2046 | case S_IFCHR: | ||
2047 | case S_IFBLK: | ||
2048 | case S_IFIFO: | ||
2049 | case S_IFSOCK: | ||
2050 | case 0: /* zero mode translates to S_IFREG */ | ||
2051 | return 0; | ||
2052 | case S_IFDIR: | ||
2053 | return -EPERM; | ||
2054 | default: | ||
2055 | return -EINVAL; | ||
2056 | } | ||
2057 | } | ||
2058 | |||
1947 | asmlinkage long sys_mknodat(int dfd, const char __user *filename, int mode, | 2059 | asmlinkage long sys_mknodat(int dfd, const char __user *filename, int mode, |
1948 | unsigned dev) | 2060 | unsigned dev) |
1949 | { | 2061 | { |
@@ -1962,12 +2074,19 @@ asmlinkage long sys_mknodat(int dfd, const char __user *filename, int mode, | |||
1962 | if (error) | 2074 | if (error) |
1963 | goto out; | 2075 | goto out; |
1964 | dentry = lookup_create(&nd, 0); | 2076 | dentry = lookup_create(&nd, 0); |
1965 | error = PTR_ERR(dentry); | 2077 | if (IS_ERR(dentry)) { |
1966 | 2078 | error = PTR_ERR(dentry); | |
2079 | goto out_unlock; | ||
2080 | } | ||
1967 | if (!IS_POSIXACL(nd.path.dentry->d_inode)) | 2081 | if (!IS_POSIXACL(nd.path.dentry->d_inode)) |
1968 | mode &= ~current->fs->umask; | 2082 | mode &= ~current->fs->umask; |
1969 | if (!IS_ERR(dentry)) { | 2083 | error = may_mknod(mode); |
1970 | switch (mode & S_IFMT) { | 2084 | if (error) |
2085 | goto out_dput; | ||
2086 | error = mnt_want_write(nd.path.mnt); | ||
2087 | if (error) | ||
2088 | goto out_dput; | ||
2089 | switch (mode & S_IFMT) { | ||
1971 | case 0: case S_IFREG: | 2090 | case 0: case S_IFREG: |
1972 | error = vfs_create(nd.path.dentry->d_inode,dentry,mode,&nd); | 2091 | error = vfs_create(nd.path.dentry->d_inode,dentry,mode,&nd); |
1973 | break; | 2092 | break; |
@@ -1978,14 +2097,11 @@ asmlinkage long sys_mknodat(int dfd, const char __user *filename, int mode, | |||
1978 | case S_IFIFO: case S_IFSOCK: | 2097 | case S_IFIFO: case S_IFSOCK: |
1979 | error = vfs_mknod(nd.path.dentry->d_inode,dentry,mode,0); | 2098 | error = vfs_mknod(nd.path.dentry->d_inode,dentry,mode,0); |
1980 | break; | 2099 | break; |
1981 | case S_IFDIR: | ||
1982 | error = -EPERM; | ||
1983 | break; | ||
1984 | default: | ||
1985 | error = -EINVAL; | ||
1986 | } | ||
1987 | dput(dentry); | ||
1988 | } | 2100 | } |
2101 | mnt_drop_write(nd.path.mnt); | ||
2102 | out_dput: | ||
2103 | dput(dentry); | ||
2104 | out_unlock: | ||
1989 | mutex_unlock(&nd.path.dentry->d_inode->i_mutex); | 2105 | mutex_unlock(&nd.path.dentry->d_inode->i_mutex); |
1990 | path_put(&nd.path); | 2106 | path_put(&nd.path); |
1991 | out: | 2107 | out: |
@@ -2043,7 +2159,12 @@ asmlinkage long sys_mkdirat(int dfd, const char __user *pathname, int mode) | |||
2043 | 2159 | ||
2044 | if (!IS_POSIXACL(nd.path.dentry->d_inode)) | 2160 | if (!IS_POSIXACL(nd.path.dentry->d_inode)) |
2045 | mode &= ~current->fs->umask; | 2161 | mode &= ~current->fs->umask; |
2162 | error = mnt_want_write(nd.path.mnt); | ||
2163 | if (error) | ||
2164 | goto out_dput; | ||
2046 | error = vfs_mkdir(nd.path.dentry->d_inode, dentry, mode); | 2165 | error = vfs_mkdir(nd.path.dentry->d_inode, dentry, mode); |
2166 | mnt_drop_write(nd.path.mnt); | ||
2167 | out_dput: | ||
2047 | dput(dentry); | 2168 | dput(dentry); |
2048 | out_unlock: | 2169 | out_unlock: |
2049 | mutex_unlock(&nd.path.dentry->d_inode->i_mutex); | 2170 | mutex_unlock(&nd.path.dentry->d_inode->i_mutex); |
@@ -2150,7 +2271,12 @@ static long do_rmdir(int dfd, const char __user *pathname) | |||
2150 | error = PTR_ERR(dentry); | 2271 | error = PTR_ERR(dentry); |
2151 | if (IS_ERR(dentry)) | 2272 | if (IS_ERR(dentry)) |
2152 | goto exit2; | 2273 | goto exit2; |
2274 | error = mnt_want_write(nd.path.mnt); | ||
2275 | if (error) | ||
2276 | goto exit3; | ||
2153 | error = vfs_rmdir(nd.path.dentry->d_inode, dentry); | 2277 | error = vfs_rmdir(nd.path.dentry->d_inode, dentry); |
2278 | mnt_drop_write(nd.path.mnt); | ||
2279 | exit3: | ||
2154 | dput(dentry); | 2280 | dput(dentry); |
2155 | exit2: | 2281 | exit2: |
2156 | mutex_unlock(&nd.path.dentry->d_inode->i_mutex); | 2282 | mutex_unlock(&nd.path.dentry->d_inode->i_mutex); |
@@ -2231,7 +2357,11 @@ static long do_unlinkat(int dfd, const char __user *pathname) | |||
2231 | inode = dentry->d_inode; | 2357 | inode = dentry->d_inode; |
2232 | if (inode) | 2358 | if (inode) |
2233 | atomic_inc(&inode->i_count); | 2359 | atomic_inc(&inode->i_count); |
2360 | error = mnt_want_write(nd.path.mnt); | ||
2361 | if (error) | ||
2362 | goto exit2; | ||
2234 | error = vfs_unlink(nd.path.dentry->d_inode, dentry); | 2363 | error = vfs_unlink(nd.path.dentry->d_inode, dentry); |
2364 | mnt_drop_write(nd.path.mnt); | ||
2235 | exit2: | 2365 | exit2: |
2236 | dput(dentry); | 2366 | dput(dentry); |
2237 | } | 2367 | } |
@@ -2312,7 +2442,12 @@ asmlinkage long sys_symlinkat(const char __user *oldname, | |||
2312 | if (IS_ERR(dentry)) | 2442 | if (IS_ERR(dentry)) |
2313 | goto out_unlock; | 2443 | goto out_unlock; |
2314 | 2444 | ||
2445 | error = mnt_want_write(nd.path.mnt); | ||
2446 | if (error) | ||
2447 | goto out_dput; | ||
2315 | error = vfs_symlink(nd.path.dentry->d_inode, dentry, from, S_IALLUGO); | 2448 | error = vfs_symlink(nd.path.dentry->d_inode, dentry, from, S_IALLUGO); |
2449 | mnt_drop_write(nd.path.mnt); | ||
2450 | out_dput: | ||
2316 | dput(dentry); | 2451 | dput(dentry); |
2317 | out_unlock: | 2452 | out_unlock: |
2318 | mutex_unlock(&nd.path.dentry->d_inode->i_mutex); | 2453 | mutex_unlock(&nd.path.dentry->d_inode->i_mutex); |
@@ -2407,7 +2542,12 @@ asmlinkage long sys_linkat(int olddfd, const char __user *oldname, | |||
2407 | error = PTR_ERR(new_dentry); | 2542 | error = PTR_ERR(new_dentry); |
2408 | if (IS_ERR(new_dentry)) | 2543 | if (IS_ERR(new_dentry)) |
2409 | goto out_unlock; | 2544 | goto out_unlock; |
2545 | error = mnt_want_write(nd.path.mnt); | ||
2546 | if (error) | ||
2547 | goto out_dput; | ||
2410 | error = vfs_link(old_nd.path.dentry, nd.path.dentry->d_inode, new_dentry); | 2548 | error = vfs_link(old_nd.path.dentry, nd.path.dentry->d_inode, new_dentry); |
2549 | mnt_drop_write(nd.path.mnt); | ||
2550 | out_dput: | ||
2411 | dput(new_dentry); | 2551 | dput(new_dentry); |
2412 | out_unlock: | 2552 | out_unlock: |
2413 | mutex_unlock(&nd.path.dentry->d_inode->i_mutex); | 2553 | mutex_unlock(&nd.path.dentry->d_inode->i_mutex); |
@@ -2633,8 +2773,12 @@ static int do_rename(int olddfd, const char *oldname, | |||
2633 | if (new_dentry == trap) | 2773 | if (new_dentry == trap) |
2634 | goto exit5; | 2774 | goto exit5; |
2635 | 2775 | ||
2776 | error = mnt_want_write(oldnd.path.mnt); | ||
2777 | if (error) | ||
2778 | goto exit5; | ||
2636 | error = vfs_rename(old_dir->d_inode, old_dentry, | 2779 | error = vfs_rename(old_dir->d_inode, old_dentry, |
2637 | new_dir->d_inode, new_dentry); | 2780 | new_dir->d_inode, new_dentry); |
2781 | mnt_drop_write(oldnd.path.mnt); | ||
2638 | exit5: | 2782 | exit5: |
2639 | dput(new_dentry); | 2783 | dput(new_dentry); |
2640 | exit4: | 2784 | exit4: |