From mboxrd@z Thu Jan 1 00:00:00 1970 From: Dave Hansen Subject: [RFC][PATCH 27/27] create and pass read-only mnt flag into do_loopback() Date: Wed, 07 Jun 2006 17:10:39 -0700 Message-ID: <20060608001039.0CE3F5F2@localhost.localdomain> References: <20060608001013.0D041507@localhost.localdomain> Cc: herbert@13thfloor.at, viro@ftp.linux.org.uk, hch@infradead.org, trond.myklebust@fys.uio.no, Dave Hansen Return-path: Received: from e35.co.us.ibm.com ([32.97.110.153]:9436 "EHLO e35.co.us.ibm.com") by vger.kernel.org with ESMTP id S932505AbWFHAKr (ORCPT ); Wed, 7 Jun 2006 20:10:47 -0400 Received: from westrelay02.boulder.ibm.com (westrelay02.boulder.ibm.com [9.17.195.11]) by e35.co.us.ibm.com (8.12.11.20060308/8.12.11) with ESMTP id k580AiuB017091 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=OK) for ; Wed, 7 Jun 2006 20:10:44 -0400 Received: from d03av02.boulder.ibm.com (d03av02.boulder.ibm.com [9.17.195.168]) by westrelay02.boulder.ibm.com (8.13.6/NCO/VER7.0) with ESMTP id k580AdIF262232 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=NO) for ; Wed, 7 Jun 2006 18:10:40 -0600 Received: from d03av02.boulder.ibm.com (loopback [127.0.0.1]) by d03av02.boulder.ibm.com (8.12.11.20060308/8.13.3) with ESMTP id k580AhX9009220 for ; Wed, 7 Jun 2006 18:10:44 -0600 To: linux-fsdevel@vger.kernel.org In-Reply-To: <20060608001013.0D041507@localhost.localdomain> Sender: linux-fsdevel-owner@vger.kernel.org List-Id: linux-fsdevel.vger.kernel.org Originally from: Herbert Poetzl This is the core of the read-only bind mount patch set. This patch introduces MNT_RDONLY and ensures that it is checked before any users may obtain write permissions for a file through any mount. Signed-off-by: Dave Hansen --- lxc-dave/fs/file.c | 1 + lxc-dave/fs/inode.c | 2 +- lxc-dave/fs/namespace.c | 8 ++++++-- lxc-dave/include/linux/mount.h | 3 +++ lxc-dave/mm/filemap.c | 3 +++ 5 files changed, 14 insertions(+), 3 deletions(-) diff -puN fs/file.c~D8-actually-add-flags fs/file.c --- lxc/fs/file.c~D8-actually-add-flags 2006-06-07 16:53:29.000000000 -0700 +++ lxc-dave/fs/file.c 2006-06-07 16:53:29.000000000 -0700 @@ -12,6 +12,7 @@ #include #include #include +#include #include #include #include diff -puN fs/inode.c~D8-actually-add-flags fs/inode.c --- lxc/fs/inode.c~D8-actually-add-flags 2006-06-07 16:53:29.000000000 -0700 +++ lxc-dave/fs/inode.c 2006-06-07 16:53:29.000000000 -0700 @@ -1185,7 +1185,7 @@ void touch_atime(struct vfsmount *mnt, s struct inode *inode = dentry->d_inode; struct timespec now; - if (IS_RDONLY(inode)) + if (IS_RDONLY(inode) || (mnt->mnt_flags & MNT_RDONLY)) return; if ((inode->i_flags & S_NOATIME) || diff -puN fs/namespace.c~D8-actually-add-flags fs/namespace.c --- lxc/fs/namespace.c~D8-actually-add-flags 2006-06-07 16:53:29.000000000 -0700 +++ lxc-dave/fs/namespace.c 2006-06-07 16:53:29.000000000 -0700 @@ -905,7 +905,8 @@ static int do_change_type(struct nameida /* * do loopback mount. */ -static int do_loopback(struct nameidata *nd, char *old_name, int recurse) +static int do_loopback(struct nameidata *nd, char *old_name, + int recurse, int mnt_flags) { struct nameidata old_nd; struct vfsmount *mnt = NULL; @@ -943,6 +944,7 @@ static int do_loopback(struct nameidata spin_unlock(&vfsmount_lock); release_mounts(&umount_list); } + mnt->mnt_flags = mnt_flags; out: up_write(&namespace_sem); @@ -1403,6 +1405,8 @@ long do_mount(char *dev_name, char *dir_ ((char *)data_page)[PAGE_SIZE - 1] = 0; /* Separate the per-mountpoint flags */ + if (flags & MS_RDONLY) + mnt_flags |= MNT_RDONLY; if (flags & MS_NOSUID) mnt_flags |= MNT_NOSUID; if (flags & MS_NODEV) @@ -1430,7 +1434,7 @@ long do_mount(char *dev_name, char *dir_ retval = do_remount(&nd, flags & ~MS_REMOUNT, mnt_flags, data_page); else if (flags & MS_BIND) - retval = do_loopback(&nd, dev_name, flags & MS_REC); + retval = do_loopback(&nd, dev_name, flags & MS_REC, mnt_flags); else if (flags & (MS_SHARED | MS_PRIVATE | MS_SLAVE | MS_UNBINDABLE)) retval = do_change_type(&nd, flags); else if (flags & MS_MOVE) diff -puN include/linux/mount.h~D8-actually-add-flags include/linux/mount.h --- lxc/include/linux/mount.h~D8-actually-add-flags 2006-06-07 16:53:29.000000000 -0700 +++ lxc-dave/include/linux/mount.h 2006-06-07 16:53:29.000000000 -0700 @@ -24,6 +24,7 @@ #define MNT_NOEXEC 0x04 #define MNT_NOATIME 0x08 #define MNT_NODIRATIME 0x10 +#define MNT_RDONLY 0x20 #define MNT_SHRINKABLE 0x100 @@ -63,6 +64,8 @@ static inline struct vfsmount *mntget(st static inline int mnt_want_write(struct vfsmount *mnt) { + if (mnt->mnt_flags & MNT_RDONLY) + return -EROFS; atomic_inc(&mnt->mnt_writers); return 0; } diff -puN mm/filemap.c~D8-actually-add-flags mm/filemap.c --- lxc/mm/filemap.c~D8-actually-add-flags 2006-06-07 16:53:29.000000000 -0700 +++ lxc-dave/mm/filemap.c 2006-06-07 16:53:29.000000000 -0700 @@ -23,6 +23,7 @@ #include #include #include +#include #include #include #include @@ -1960,6 +1961,8 @@ inline int generic_write_checks(struct f return -EINVAL; if (!isblk) { + if (file->f_vfsmnt->mnt_flags & MNT_RDONLY) + return -EROFS; /* FIXME: this is for backwards compatibility with 2.4 */ if (file->f_flags & O_APPEND) *pos = i_size_read(inode); _