dir.c (a09f99eddef44035ec764075a37bace8181bec38) | dir.c (5e940c1dd3c1f7561924954eecee956ec277a79b) |
---|---|
1/* 2 FUSE: Filesystem in Userspace 3 Copyright (C) 2001-2008 Miklos Szeredi <miklos@szeredi.hu> 4 5 This program can be distributed under the terms of the GNU GPL. 6 See the file COPYING. 7*/ 8 --- 1689 unchanged lines hidden (view full) --- 1698 1699 clear_bit(FUSE_I_SIZE_UNSTABLE, &fi->state); 1700 return err; 1701} 1702 1703static int fuse_setattr(struct dentry *entry, struct iattr *attr) 1704{ 1705 struct inode *inode = d_inode(entry); | 1/* 2 FUSE: Filesystem in Userspace 3 Copyright (C) 2001-2008 Miklos Szeredi <miklos@szeredi.hu> 4 5 This program can be distributed under the terms of the GNU GPL. 6 See the file COPYING. 7*/ 8 --- 1689 unchanged lines hidden (view full) --- 1698 1699 clear_bit(FUSE_I_SIZE_UNSTABLE, &fi->state); 1700 return err; 1701} 1702 1703static int fuse_setattr(struct dentry *entry, struct iattr *attr) 1704{ 1705 struct inode *inode = d_inode(entry); |
1706 struct fuse_conn *fc = get_fuse_conn(inode); |
|
1706 struct file *file = (attr->ia_valid & ATTR_FILE) ? attr->ia_file : NULL; 1707 int ret; 1708 1709 if (!fuse_allow_current_process(get_fuse_conn(inode))) 1710 return -EACCES; 1711 1712 if (attr->ia_valid & (ATTR_KILL_SUID | ATTR_KILL_SGID)) { | 1707 struct file *file = (attr->ia_valid & ATTR_FILE) ? attr->ia_file : NULL; 1708 int ret; 1709 1710 if (!fuse_allow_current_process(get_fuse_conn(inode))) 1711 return -EACCES; 1712 1713 if (attr->ia_valid & (ATTR_KILL_SUID | ATTR_KILL_SGID)) { |
1713 int kill; 1714 | |
1715 attr->ia_valid &= ~(ATTR_KILL_SUID | ATTR_KILL_SGID | 1716 ATTR_MODE); | 1714 attr->ia_valid &= ~(ATTR_KILL_SUID | ATTR_KILL_SGID | 1715 ATTR_MODE); |
1716 |
|
1717 /* | 1717 /* |
1718 * ia_mode calculation may have used stale i_mode. Refresh and 1719 * recalculate. | 1718 * The only sane way to reliably kill suid/sgid is to do it in 1719 * the userspace filesystem 1720 * 1721 * This should be done on write(), truncate() and chown(). |
1720 */ | 1722 */ |
1721 ret = fuse_do_getattr(inode, NULL, file); 1722 if (ret) 1723 return ret; | 1723 if (!fc->handle_killpriv) { 1724 int kill; |
1724 | 1725 |
1725 attr->ia_mode = inode->i_mode; 1726 kill = should_remove_suid(entry); 1727 if (kill & ATTR_KILL_SUID) { 1728 attr->ia_valid |= ATTR_MODE; 1729 attr->ia_mode &= ~S_ISUID; | 1726 /* 1727 * ia_mode calculation may have used stale i_mode. 1728 * Refresh and recalculate. 1729 */ 1730 ret = fuse_do_getattr(inode, NULL, file); 1731 if (ret) 1732 return ret; 1733 1734 attr->ia_mode = inode->i_mode; 1735 kill = should_remove_suid(entry); 1736 if (kill & ATTR_KILL_SUID) { 1737 attr->ia_valid |= ATTR_MODE; 1738 attr->ia_mode &= ~S_ISUID; 1739 } 1740 if (kill & ATTR_KILL_SGID) { 1741 attr->ia_valid |= ATTR_MODE; 1742 attr->ia_mode &= ~S_ISGID; 1743 } |
1730 } | 1744 } |
1731 if (kill & ATTR_KILL_SGID) { 1732 attr->ia_valid |= ATTR_MODE; 1733 attr->ia_mode &= ~S_ISGID; 1734 } | |
1735 } 1736 if (!attr->ia_valid) 1737 return 0; 1738 1739 ret = fuse_do_setattr(inode, attr, file); 1740 if (!ret) { 1741 /* Directory mode changed, may need to revalidate access */ 1742 if (d_is_dir(entry) && (attr->ia_valid & ATTR_MODE)) --- 84 unchanged lines hidden --- | 1745 } 1746 if (!attr->ia_valid) 1747 return 0; 1748 1749 ret = fuse_do_setattr(inode, attr, file); 1750 if (!ret) { 1751 /* Directory mode changed, may need to revalidate access */ 1752 if (d_is_dir(entry) && (attr->ia_valid & ATTR_MODE)) --- 84 unchanged lines hidden --- |