aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorEric W. Biederman <ebiederm@xmission.com>2017-09-14 13:07:32 -0400
committerEric W. Biederman <ebiederm@xmission.com>2018-05-24 12:56:18 -0400
commit593d1ce854dff93b3c9066e897192eb676b09c46 (patch)
treebe0a5546be2dd24273dd7bae75b35ffa3e24e855
parenta3a5c966a664dfde0393dd366c2cb916962d164f (diff)
vfs: Don't allow changing the link count of an inode with an invalid uid or gid
Changing the link count of an inode via unlink or link will cause a write back of that inode. If the uids or gids are invalid (aka not known to the kernel) writing the inode back may change the uid or gid in the filesystem. To prevent possible filesystem and to avoid the need for filesystem maintainers to worry about it don't allow operations on inodes with an invalid uid or gid. Acked-by: Seth Forshee <seth.forshee@canonical.com> Signed-off-by: "Eric W. Biederman" <ebiederm@xmission.com>
-rw-r--r--fs/namei.c13
1 files changed, 10 insertions, 3 deletions
diff --git a/fs/namei.c b/fs/namei.c
index 186bd2464fd5..942c1f096f6b 100644
--- a/fs/namei.c
+++ b/fs/namei.c
@@ -984,13 +984,15 @@ static bool safe_hardlink_source(struct inode *inode)
984 */ 984 */
985static int may_linkat(struct path *link) 985static int may_linkat(struct path *link)
986{ 986{
987 struct inode *inode; 987 struct inode *inode = link->dentry->d_inode;
988
989 /* Inode writeback is not safe when the uid or gid are invalid. */
990 if (!uid_valid(inode->i_uid) || !gid_valid(inode->i_gid))
991 return -EOVERFLOW;
988 992
989 if (!sysctl_protected_hardlinks) 993 if (!sysctl_protected_hardlinks)
990 return 0; 994 return 0;
991 995
992 inode = link->dentry->d_inode;
993
994 /* Source inode owner (or CAP_FOWNER) can hardlink all they like, 996 /* Source inode owner (or CAP_FOWNER) can hardlink all they like,
995 * otherwise, it must be a safe source. 997 * otherwise, it must be a safe source.
996 */ 998 */
@@ -2749,6 +2751,11 @@ static int may_delete(struct inode *dir, struct dentry *victim, bool isdir)
2749 BUG_ON(!inode); 2751 BUG_ON(!inode);
2750 2752
2751 BUG_ON(victim->d_parent->d_inode != dir); 2753 BUG_ON(victim->d_parent->d_inode != dir);
2754
2755 /* Inode writeback is not safe when the uid or gid are invalid. */
2756 if (!uid_valid(inode->i_uid) || !gid_valid(inode->i_gid))
2757 return -EOVERFLOW;
2758
2752 audit_inode_child(dir, victim, AUDIT_TYPE_CHILD_DELETE); 2759 audit_inode_child(dir, victim, AUDIT_TYPE_CHILD_DELETE);
2753 2760
2754 error = inode_permission(dir, MAY_WRITE | MAY_EXEC); 2761 error = inode_permission(dir, MAY_WRITE | MAY_EXEC);