.. | .. |
---|
158 | 158 | inode->i_bdev = NULL; |
---|
159 | 159 | inode->i_cdev = NULL; |
---|
160 | 160 | inode->i_link = NULL; |
---|
161 | | - inode->__i_dir_seq = 0; |
---|
| 161 | + inode->i_dir_seq = 0; |
---|
162 | 162 | inode->i_rdev = 0; |
---|
163 | 163 | inode->dirtied_when = 0; |
---|
164 | 164 | |
---|
.. | .. |
---|
1016 | 1016 | EXPORT_SYMBOL(discard_new_inode); |
---|
1017 | 1017 | |
---|
1018 | 1018 | /** |
---|
| 1019 | + * lock_two_inodes - lock two inodes (may be regular files but also dirs) |
---|
| 1020 | + * |
---|
| 1021 | + * Lock any non-NULL argument. The caller must make sure that if he is passing |
---|
| 1022 | + * in two directories, one is not ancestor of the other. Zero, one or two |
---|
| 1023 | + * objects may be locked by this function. |
---|
| 1024 | + * |
---|
| 1025 | + * @inode1: first inode to lock |
---|
| 1026 | + * @inode2: second inode to lock |
---|
| 1027 | + * @subclass1: inode lock subclass for the first lock obtained |
---|
| 1028 | + * @subclass2: inode lock subclass for the second lock obtained |
---|
| 1029 | + */ |
---|
| 1030 | +void lock_two_inodes(struct inode *inode1, struct inode *inode2, |
---|
| 1031 | + unsigned subclass1, unsigned subclass2) |
---|
| 1032 | +{ |
---|
| 1033 | + if (!inode1 || !inode2) { |
---|
| 1034 | + /* |
---|
| 1035 | + * Make sure @subclass1 will be used for the acquired lock. |
---|
| 1036 | + * This is not strictly necessary (no current caller cares) but |
---|
| 1037 | + * let's keep things consistent. |
---|
| 1038 | + */ |
---|
| 1039 | + if (!inode1) |
---|
| 1040 | + swap(inode1, inode2); |
---|
| 1041 | + goto lock; |
---|
| 1042 | + } |
---|
| 1043 | + |
---|
| 1044 | + /* |
---|
| 1045 | + * If one object is directory and the other is not, we must make sure |
---|
| 1046 | + * to lock directory first as the other object may be its child. |
---|
| 1047 | + */ |
---|
| 1048 | + if (S_ISDIR(inode2->i_mode) == S_ISDIR(inode1->i_mode)) { |
---|
| 1049 | + if (inode1 > inode2) |
---|
| 1050 | + swap(inode1, inode2); |
---|
| 1051 | + } else if (!S_ISDIR(inode1->i_mode)) |
---|
| 1052 | + swap(inode1, inode2); |
---|
| 1053 | +lock: |
---|
| 1054 | + if (inode1) |
---|
| 1055 | + inode_lock_nested(inode1, subclass1); |
---|
| 1056 | + if (inode2 && inode2 != inode1) |
---|
| 1057 | + inode_lock_nested(inode2, subclass2); |
---|
| 1058 | +} |
---|
| 1059 | + |
---|
| 1060 | +/** |
---|
1019 | 1061 | * lock_two_nondirectories - take two i_mutexes on non-directory objects |
---|
1020 | 1062 | * |
---|
1021 | 1063 | * Lock any non-NULL argument that is not a directory. |
---|
.. | .. |
---|
1855 | 1897 | EXPORT_SYMBOL_NS(touch_atime, ANDROID_GKI_VFS_EXPORT_ONLY); |
---|
1856 | 1898 | |
---|
1857 | 1899 | /* |
---|
1858 | | - * The logic we want is |
---|
1859 | | - * |
---|
1860 | | - * if suid or (sgid and xgrp) |
---|
1861 | | - * remove privs |
---|
1862 | | - */ |
---|
1863 | | -int should_remove_suid(struct dentry *dentry) |
---|
1864 | | -{ |
---|
1865 | | - umode_t mode = d_inode(dentry)->i_mode; |
---|
1866 | | - int kill = 0; |
---|
1867 | | - |
---|
1868 | | - /* suid always must be killed */ |
---|
1869 | | - if (unlikely(mode & S_ISUID)) |
---|
1870 | | - kill = ATTR_KILL_SUID; |
---|
1871 | | - |
---|
1872 | | - /* |
---|
1873 | | - * sgid without any exec bits is just a mandatory locking mark; leave |
---|
1874 | | - * it alone. If some exec bits are set, it's a real sgid; kill it. |
---|
1875 | | - */ |
---|
1876 | | - if (unlikely((mode & S_ISGID) && (mode & S_IXGRP))) |
---|
1877 | | - kill |= ATTR_KILL_SGID; |
---|
1878 | | - |
---|
1879 | | - if (unlikely(kill && !capable(CAP_FSETID) && S_ISREG(mode))) |
---|
1880 | | - return kill; |
---|
1881 | | - |
---|
1882 | | - return 0; |
---|
1883 | | -} |
---|
1884 | | -EXPORT_SYMBOL(should_remove_suid); |
---|
1885 | | - |
---|
1886 | | -/* |
---|
1887 | 1900 | * Return mask of changes for notify_change() that need to be done as a |
---|
1888 | 1901 | * response to write or truncate. Return 0 if nothing has to be changed. |
---|
1889 | 1902 | * Negative value on error (change should be denied). |
---|
.. | .. |
---|
1897 | 1910 | if (IS_NOSEC(inode)) |
---|
1898 | 1911 | return 0; |
---|
1899 | 1912 | |
---|
1900 | | - mask = should_remove_suid(dentry); |
---|
| 1913 | + mask = setattr_should_drop_suidgid(inode); |
---|
1901 | 1914 | ret = security_inode_need_killpriv(dentry); |
---|
1902 | 1915 | if (ret < 0) |
---|
1903 | 1916 | return ret; |
---|
.. | .. |
---|
2147 | 2160 | /* Directories are special, and always inherit S_ISGID */ |
---|
2148 | 2161 | if (S_ISDIR(mode)) |
---|
2149 | 2162 | mode |= S_ISGID; |
---|
2150 | | - else if ((mode & (S_ISGID | S_IXGRP)) == (S_ISGID | S_IXGRP) && |
---|
2151 | | - !in_group_p(inode->i_gid) && |
---|
2152 | | - !capable_wrt_inode_uidgid(dir, CAP_FSETID)) |
---|
2153 | | - mode &= ~S_ISGID; |
---|
2154 | 2163 | } else |
---|
2155 | 2164 | inode->i_gid = current_fsgid(); |
---|
2156 | 2165 | inode->i_mode = mode; |
---|
.. | .. |
---|
2382 | 2391 | return 0; |
---|
2383 | 2392 | } |
---|
2384 | 2393 | EXPORT_SYMBOL(vfs_ioc_fssetxattr_check); |
---|
| 2394 | + |
---|
| 2395 | +/** |
---|
| 2396 | + * in_group_or_capable - check whether caller is CAP_FSETID privileged |
---|
| 2397 | + * @inode: inode to check |
---|
| 2398 | + * @gid: the new/current gid of @inode |
---|
| 2399 | + * |
---|
| 2400 | + * Check wether @gid is in the caller's group list or if the caller is |
---|
| 2401 | + * privileged with CAP_FSETID over @inode. This can be used to determine |
---|
| 2402 | + * whether the setgid bit can be kept or must be dropped. |
---|
| 2403 | + * |
---|
| 2404 | + * Return: true if the caller is sufficiently privileged, false if not. |
---|
| 2405 | + */ |
---|
| 2406 | +bool in_group_or_capable(const struct inode *inode, kgid_t gid) |
---|
| 2407 | +{ |
---|
| 2408 | + if (in_group_p(gid)) |
---|
| 2409 | + return true; |
---|
| 2410 | + if (capable_wrt_inode_uidgid(inode, CAP_FSETID)) |
---|
| 2411 | + return true; |
---|
| 2412 | + return false; |
---|
| 2413 | +} |
---|
| 2414 | + |
---|
| 2415 | +/** |
---|
| 2416 | + * mode_strip_sgid - handle the sgid bit for non-directories |
---|
| 2417 | + * @dir: parent directory inode |
---|
| 2418 | + * @mode: mode of the file to be created in @dir |
---|
| 2419 | + * |
---|
| 2420 | + * If the @mode of the new file has both the S_ISGID and S_IXGRP bit |
---|
| 2421 | + * raised and @dir has the S_ISGID bit raised ensure that the caller is |
---|
| 2422 | + * either in the group of the parent directory or they have CAP_FSETID |
---|
| 2423 | + * in their user namespace and are privileged over the parent directory. |
---|
| 2424 | + * In all other cases, strip the S_ISGID bit from @mode. |
---|
| 2425 | + * |
---|
| 2426 | + * Return: the new mode to use for the file |
---|
| 2427 | + */ |
---|
| 2428 | +umode_t mode_strip_sgid(const struct inode *dir, umode_t mode) |
---|
| 2429 | +{ |
---|
| 2430 | + if ((mode & (S_ISGID | S_IXGRP)) != (S_ISGID | S_IXGRP)) |
---|
| 2431 | + return mode; |
---|
| 2432 | + if (S_ISDIR(mode) || !dir || !(dir->i_mode & S_ISGID)) |
---|
| 2433 | + return mode; |
---|
| 2434 | + if (in_group_or_capable(dir, dir->i_gid)) |
---|
| 2435 | + return mode; |
---|
| 2436 | + return mode & ~S_ISGID; |
---|
| 2437 | +} |
---|
| 2438 | +EXPORT_SYMBOL(mode_strip_sgid); |
---|