Commit 593d1ce8 authored by Eric W. Biederman's avatar Eric W. Biederman

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: default avatarSeth Forshee <seth.forshee@canonical.com>
Signed-off-by: default avatar"Eric W. Biederman" <ebiederm@xmission.com>
parent a3a5c966
...@@ -984,13 +984,15 @@ static bool safe_hardlink_source(struct inode *inode) ...@@ -984,13 +984,15 @@ static bool safe_hardlink_source(struct inode *inode)
*/ */
static int may_linkat(struct path *link) static int may_linkat(struct path *link)
{ {
struct inode *inode; struct inode *inode = link->dentry->d_inode;
/* Inode writeback is not safe when the uid or gid are invalid. */
if (!uid_valid(inode->i_uid) || !gid_valid(inode->i_gid))
return -EOVERFLOW;
if (!sysctl_protected_hardlinks) if (!sysctl_protected_hardlinks)
return 0; return 0;
inode = link->dentry->d_inode;
/* Source inode owner (or CAP_FOWNER) can hardlink all they like, /* Source inode owner (or CAP_FOWNER) can hardlink all they like,
* otherwise, it must be a safe source. * otherwise, it must be a safe source.
*/ */
...@@ -2749,6 +2751,11 @@ static int may_delete(struct inode *dir, struct dentry *victim, bool isdir) ...@@ -2749,6 +2751,11 @@ static int may_delete(struct inode *dir, struct dentry *victim, bool isdir)
BUG_ON(!inode); BUG_ON(!inode);
BUG_ON(victim->d_parent->d_inode != dir); BUG_ON(victim->d_parent->d_inode != dir);
/* Inode writeback is not safe when the uid or gid are invalid. */
if (!uid_valid(inode->i_uid) || !gid_valid(inode->i_gid))
return -EOVERFLOW;
audit_inode_child(dir, victim, AUDIT_TYPE_CHILD_DELETE); audit_inode_child(dir, victim, AUDIT_TYPE_CHILD_DELETE);
error = inode_permission(dir, MAY_WRITE | MAY_EXEC); error = inode_permission(dir, MAY_WRITE | MAY_EXEC);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment