aboutsummaryrefslogtreecommitdiffstats
path: root/fs/proc/base.c
diff options
context:
space:
mode:
authorEric W. Biederman <ebiederm@xmission.com>2017-01-02 16:23:11 -0500
committerEric W. Biederman <ebiederm@xmission.com>2017-01-23 18:03:09 -0500
commit68eb94f16227336a5773b83ecfa8290f1d6b78ce (patch)
tree2dfcf480bbfce233747c6d7d40a120850f1256a2 /fs/proc/base.c
parent9227dd2a84a765fcfef1677ff17de0958b192eda (diff)
proc: Better ownership of files for non-dumpable tasks in user namespaces
Instead of making the files owned by the GLOBAL_ROOT_USER. Make non-dumpable files whose mm has always lived in a user namespace owned by the user namespace root. This allows the container root to have things work as expected in a container. Signed-off-by: "Eric W. Biederman" <ebiederm@xmission.com>
Diffstat (limited to 'fs/proc/base.c')
-rw-r--r--fs/proc/base.c102
1 files changed, 58 insertions, 44 deletions
diff --git a/fs/proc/base.c b/fs/proc/base.c
index 8e7e61b28f31..ad98d883847a 100644
--- a/fs/proc/base.c
+++ b/fs/proc/base.c
@@ -1667,12 +1667,63 @@ const struct inode_operations proc_pid_link_inode_operations = {
1667 1667
1668/* building an inode */ 1668/* building an inode */
1669 1669
1670void task_dump_owner(struct task_struct *task, mode_t mode,
1671 kuid_t *ruid, kgid_t *rgid)
1672{
1673 /* Depending on the state of dumpable compute who should own a
1674 * proc file for a task.
1675 */
1676 const struct cred *cred;
1677 kuid_t uid;
1678 kgid_t gid;
1679
1680 /* Default to the tasks effective ownership */
1681 rcu_read_lock();
1682 cred = __task_cred(task);
1683 uid = cred->euid;
1684 gid = cred->egid;
1685 rcu_read_unlock();
1686
1687 /*
1688 * Before the /proc/pid/status file was created the only way to read
1689 * the effective uid of a /process was to stat /proc/pid. Reading
1690 * /proc/pid/status is slow enough that procps and other packages
1691 * kept stating /proc/pid. To keep the rules in /proc simple I have
1692 * made this apply to all per process world readable and executable
1693 * directories.
1694 */
1695 if (mode != (S_IFDIR|S_IRUGO|S_IXUGO)) {
1696 struct mm_struct *mm;
1697 task_lock(task);
1698 mm = task->mm;
1699 /* Make non-dumpable tasks owned by some root */
1700 if (mm) {
1701 if (get_dumpable(mm) != SUID_DUMP_USER) {
1702 struct user_namespace *user_ns = mm->user_ns;
1703
1704 uid = make_kuid(user_ns, 0);
1705 if (!uid_valid(uid))
1706 uid = GLOBAL_ROOT_UID;
1707
1708 gid = make_kgid(user_ns, 0);
1709 if (!gid_valid(gid))
1710 gid = GLOBAL_ROOT_GID;
1711 }
1712 } else {
1713 uid = GLOBAL_ROOT_UID;
1714 gid = GLOBAL_ROOT_GID;
1715 }
1716 task_unlock(task);
1717 }
1718 *ruid = uid;
1719 *rgid = gid;
1720}
1721
1670struct inode *proc_pid_make_inode(struct super_block * sb, 1722struct inode *proc_pid_make_inode(struct super_block * sb,
1671 struct task_struct *task, umode_t mode) 1723 struct task_struct *task, umode_t mode)
1672{ 1724{
1673 struct inode * inode; 1725 struct inode * inode;
1674 struct proc_inode *ei; 1726 struct proc_inode *ei;
1675 const struct cred *cred;
1676 1727
1677 /* We need a new inode */ 1728 /* We need a new inode */
1678 1729
@@ -1694,13 +1745,7 @@ struct inode *proc_pid_make_inode(struct super_block * sb,
1694 if (!ei->pid) 1745 if (!ei->pid)
1695 goto out_unlock; 1746 goto out_unlock;
1696 1747
1697 if (task_dumpable(task)) { 1748 task_dump_owner(task, 0, &inode->i_uid, &inode->i_gid);
1698 rcu_read_lock();
1699 cred = __task_cred(task);
1700 inode->i_uid = cred->euid;
1701 inode->i_gid = cred->egid;
1702 rcu_read_unlock();
1703 }
1704 security_task_to_inode(task, inode); 1749 security_task_to_inode(task, inode);
1705 1750
1706out: 1751out:
@@ -1715,7 +1760,6 @@ int pid_getattr(struct vfsmount *mnt, struct dentry *dentry, struct kstat *stat)
1715{ 1760{
1716 struct inode *inode = d_inode(dentry); 1761 struct inode *inode = d_inode(dentry);
1717 struct task_struct *task; 1762 struct task_struct *task;
1718 const struct cred *cred;
1719 struct pid_namespace *pid = dentry->d_sb->s_fs_info; 1763 struct pid_namespace *pid = dentry->d_sb->s_fs_info;
1720 1764
1721 generic_fillattr(inode, stat); 1765 generic_fillattr(inode, stat);
@@ -1733,12 +1777,7 @@ int pid_getattr(struct vfsmount *mnt, struct dentry *dentry, struct kstat *stat)
1733 */ 1777 */
1734 return -ENOENT; 1778 return -ENOENT;
1735 } 1779 }
1736 if ((inode->i_mode == (S_IFDIR|S_IRUGO|S_IXUGO)) || 1780 task_dump_owner(task, inode->i_mode, &stat->uid, &stat->gid);
1737 task_dumpable(task)) {
1738 cred = __task_cred(task);
1739 stat->uid = cred->euid;
1740 stat->gid = cred->egid;
1741 }
1742 } 1781 }
1743 rcu_read_unlock(); 1782 rcu_read_unlock();
1744 return 0; 1783 return 0;
@@ -1754,18 +1793,11 @@ int pid_getattr(struct vfsmount *mnt, struct dentry *dentry, struct kstat *stat)
1754 * Rewrite the inode's ownerships here because the owning task may have 1793 * Rewrite the inode's ownerships here because the owning task may have
1755 * performed a setuid(), etc. 1794 * performed a setuid(), etc.
1756 * 1795 *
1757 * Before the /proc/pid/status file was created the only way to read
1758 * the effective uid of a /process was to stat /proc/pid. Reading
1759 * /proc/pid/status is slow enough that procps and other packages
1760 * kept stating /proc/pid. To keep the rules in /proc simple I have
1761 * made this apply to all per process world readable and executable
1762 * directories.
1763 */ 1796 */
1764int pid_revalidate(struct dentry *dentry, unsigned int flags) 1797int pid_revalidate(struct dentry *dentry, unsigned int flags)
1765{ 1798{
1766 struct inode *inode; 1799 struct inode *inode;
1767 struct task_struct *task; 1800 struct task_struct *task;
1768 const struct cred *cred;
1769 1801
1770 if (flags & LOOKUP_RCU) 1802 if (flags & LOOKUP_RCU)
1771 return -ECHILD; 1803 return -ECHILD;
@@ -1774,17 +1806,8 @@ int pid_revalidate(struct dentry *dentry, unsigned int flags)
1774 task = get_proc_task(inode); 1806 task = get_proc_task(inode);
1775 1807
1776 if (task) { 1808 if (task) {
1777 if ((inode->i_mode == (S_IFDIR|S_IRUGO|S_IXUGO)) || 1809 task_dump_owner(task, inode->i_mode, &inode->i_uid, &inode->i_gid);
1778 task_dumpable(task)) { 1810
1779 rcu_read_lock();
1780 cred = __task_cred(task);
1781 inode->i_uid = cred->euid;
1782 inode->i_gid = cred->egid;
1783 rcu_read_unlock();
1784 } else {
1785 inode->i_uid = GLOBAL_ROOT_UID;
1786 inode->i_gid = GLOBAL_ROOT_GID;
1787 }
1788 inode->i_mode &= ~(S_ISUID | S_ISGID); 1811 inode->i_mode &= ~(S_ISUID | S_ISGID);
1789 security_task_to_inode(task, inode); 1812 security_task_to_inode(task, inode);
1790 put_task_struct(task); 1813 put_task_struct(task);
@@ -1881,7 +1904,6 @@ static int map_files_d_revalidate(struct dentry *dentry, unsigned int flags)
1881 bool exact_vma_exists = false; 1904 bool exact_vma_exists = false;
1882 struct mm_struct *mm = NULL; 1905 struct mm_struct *mm = NULL;
1883 struct task_struct *task; 1906 struct task_struct *task;
1884 const struct cred *cred;
1885 struct inode *inode; 1907 struct inode *inode;
1886 int status = 0; 1908 int status = 0;
1887 1909
@@ -1906,16 +1928,8 @@ static int map_files_d_revalidate(struct dentry *dentry, unsigned int flags)
1906 mmput(mm); 1928 mmput(mm);
1907 1929
1908 if (exact_vma_exists) { 1930 if (exact_vma_exists) {
1909 if (task_dumpable(task)) { 1931 task_dump_owner(task, 0, &inode->i_uid, &inode->i_gid);
1910 rcu_read_lock(); 1932
1911 cred = __task_cred(task);
1912 inode->i_uid = cred->euid;
1913 inode->i_gid = cred->egid;
1914 rcu_read_unlock();
1915 } else {
1916 inode->i_uid = GLOBAL_ROOT_UID;
1917 inode->i_gid = GLOBAL_ROOT_GID;
1918 }
1919 security_task_to_inode(task, inode); 1933 security_task_to_inode(task, inode);
1920 status = 1; 1934 status = 1;
1921 } 1935 }