linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [Patch 4/6] Bind Mount Extensions 0.06
@ 2005-02-22 12:12 Herbert Poetzl
  2005-02-22 14:45 ` Trond Myklebust
  2005-02-23  0:29 ` Ingo Oeser
  0 siblings, 2 replies; 6+ messages in thread
From: Herbert Poetzl @ 2005-02-22 12:12 UTC (permalink / raw)
  To: Andrew Morton, Al Viro; +Cc: Linux Kernel ML



;
; Bind Mount Extensions
;
; This part adds mnt_may_create() and mnt_may_unlink() checks
; and uses them in lookup_create(), sys_rmdir() and sys_unlink()
; it also adds a RDONLY check to generic_write_checks() and
; for pipe_writev()
;
; Copyright (C) 2003-2005 Herbert Pötzl <herbert@13thfloor.at>
;
; Changelog:
;
;   0.01  - broken out part from bme0.05
;
; this patch is free software; you can redistribute it and/or
; modify it under the terms of the GNU General Public License
; as published by the Free Software Foundation; either version 2
; of the License, or (at your option) any later version.
;
; this patch is distributed in the hope that it will be useful,
; but WITHOUT ANY WARRANTY; without even the implied warranty of
; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
; GNU General Public License for more details.
;

diff -NurpP --minimal linux-2.6.11-rc4-bme0.06-bm0.01-at0.01-cc0.01/fs/namei.c linux-2.6.11-rc4-bme0.06-bm0.01-at0.01-cc0.01-co0.01/fs/namei.c
--- linux-2.6.11-rc4-bme0.06-bm0.01-at0.01-cc0.01/fs/namei.c	2005-02-13 17:16:55 +0100
+++ linux-2.6.11-rc4-bme0.06-bm0.01-at0.01-cc0.01-co0.01/fs/namei.c	2005-02-19 06:31:50 +0100
@@ -1168,6 +1168,24 @@ static inline int may_create(struct inod
 	return permission(dir,MAY_WRITE | MAY_EXEC, nd);
 }
 
+static inline int mnt_may_create(struct vfsmount *mnt, struct inode *dir, struct dentry *child) {
+       if (child->d_inode)
+               return -EEXIST;
+       if (IS_DEADDIR(dir))
+               return -ENOENT;
+       if (MNT_IS_RDONLY(mnt))
+               return -EROFS;
+       return 0;
+}
+
+static inline int mnt_may_unlink(struct vfsmount *mnt, struct inode *dir, struct dentry *child) {
+       if (!child->d_inode)
+               return -ENOENT;
+       if (MNT_IS_RDONLY(mnt))
+               return -EROFS;
+       return 0;
+}
+
 /* 
  * Special case: O_CREAT|O_EXCL implies O_NOFOLLOW for security
  * reasons.
@@ -1518,23 +1536,28 @@ do_link:
 struct dentry *lookup_create(struct nameidata *nd, int is_dir)
 {
 	struct dentry *dentry;
+	int error;
 
 	down(&nd->dentry->d_inode->i_sem);
-	dentry = ERR_PTR(-EEXIST);
+	error = -EEXIST;
 	if (nd->last_type != LAST_NORM)
-		goto fail;
+		goto out;
 	nd->flags &= ~LOOKUP_PARENT;
 	dentry = lookup_hash(&nd->last, nd->dentry);
 	if (IS_ERR(dentry))
+		goto ret;
+	error = mnt_may_create(nd->mnt, nd->dentry->d_inode, dentry);
+	if (error)
 		goto fail;
+	error = -ENOENT;
 	if (!is_dir && nd->last.name[nd->last.len] && !dentry->d_inode)
-		goto enoent;
+		goto fail;
+ret:
 	return dentry;
-enoent:
-	dput(dentry);
-	dentry = ERR_PTR(-ENOENT);
 fail:
-	return dentry;
+	dput(dentry);
+out:
+	return ERR_PTR(error);
 }
 
 int vfs_mknod(struct inode *dir, struct dentry *dentry, int mode, dev_t dev)
@@ -1763,7 +1786,11 @@ asmlinkage long sys_rmdir(const char __u
 	dentry = lookup_hash(&nd.last, nd.dentry);
 	error = PTR_ERR(dentry);
 	if (!IS_ERR(dentry)) {
+		error = mnt_may_unlink(nd.mnt, nd.dentry->d_inode, dentry);
+		if (error)
+			goto exit2;
 		error = vfs_rmdir(nd.dentry->d_inode, dentry);
+	exit2:
 		dput(dentry);
 	}
 	up(&nd.dentry->d_inode->i_sem);
@@ -1835,6 +1862,9 @@ asmlinkage long sys_unlink(const char __
 		/* Why not before? Because we want correct error value */
 		if (nd.last.name[nd.last.len])
 			goto slashes;
+		error = mnt_may_unlink(nd.mnt, nd.dentry->d_inode, dentry);
+		if (error)
+			goto exit2;
 		inode = dentry->d_inode;
 		if (inode)
 			atomic_inc(&inode->i_count);
diff -NurpP --minimal linux-2.6.11-rc4-bme0.06-bm0.01-at0.01-cc0.01/fs/pipe.c linux-2.6.11-rc4-bme0.06-bm0.01-at0.01-cc0.01-co0.01/fs/pipe.c
--- linux-2.6.11-rc4-bme0.06-bm0.01-at0.01-cc0.01/fs/pipe.c	2005-02-13 17:16:58 +0100
+++ linux-2.6.11-rc4-bme0.06-bm0.01-at0.01-cc0.01-co0.01/fs/pipe.c	2005-02-19 06:31:50 +0100
@@ -334,7 +334,7 @@ out:
 		wake_up_interruptible(PIPE_WAIT(*inode));
 		kill_fasync(PIPE_FASYNC_READERS(*inode), SIGIO, POLL_IN);
 	}
-	if (ret > 0)
+	if ((ret > 0) && !MNT_IS_RDONLY(filp->f_vfsmnt))
 		inode_update_time(inode, 1);	/* mtime and ctime */
 	return ret;
 }
diff -NurpP --minimal linux-2.6.11-rc4-bme0.06-bm0.01-at0.01-cc0.01/mm/filemap.c linux-2.6.11-rc4-bme0.06-bm0.01-at0.01-cc0.01-co0.01/mm/filemap.c
--- linux-2.6.11-rc4-bme0.06-bm0.01-at0.01-cc0.01/mm/filemap.c	2005-02-13 17:17:15 +0100
+++ linux-2.6.11-rc4-bme0.06-bm0.01-at0.01-cc0.01-co0.01/mm/filemap.c	2005-02-19 06:31:50 +0100
@@ -1810,6 +1810,8 @@ inline int generic_write_checks(struct f
         }
 
 	if (!isblk) {
+		if (MNT_IS_RDONLY(file->f_vfsmnt))
+			return -EROFS;
 		/* FIXME: this is for backwards compatibility with 2.4 */
 		if (file->f_flags & O_APPEND)
                         *pos = i_size_read(inode);

^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: [Patch 4/6] Bind Mount Extensions 0.06
  2005-02-22 12:12 [Patch 4/6] Bind Mount Extensions 0.06 Herbert Poetzl
@ 2005-02-22 14:45 ` Trond Myklebust
  2005-02-23 22:48   ` Herbert Poetzl
  2005-02-26 18:38   ` Herbert Poetzl
  2005-02-23  0:29 ` Ingo Oeser
  1 sibling, 2 replies; 6+ messages in thread
From: Trond Myklebust @ 2005-02-22 14:45 UTC (permalink / raw)
  To: Herbert Poetzl; +Cc: Andrew Morton, Al Viro, Linux Kernel ML

ty den 22.02.2005 Klokka 13:12 (+0100) skreiv Herbert Poetzl:

> diff -NurpP --minimal linux-2.6.11-rc4-bme0.06-bm0.01-at0.01-cc0.01/fs/namei.c linux-2.6.11-rc4-bme0.06-bm0.01-at0.01-cc0.01-co0.01/fs/namei.c
> --- linux-2.6.11-rc4-bme0.06-bm0.01-at0.01-cc0.01/fs/namei.c	2005-02-13 17:16:55 +0100
> +++ linux-2.6.11-rc4-bme0.06-bm0.01-at0.01-cc0.01-co0.01/fs/namei.c	2005-02-19 06:31:50 +0100
> @@ -1168,6 +1168,24 @@ static inline int may_create(struct inod
>  	return permission(dir,MAY_WRITE | MAY_EXEC, nd);
>  }
>  
> +static inline int mnt_may_create(struct vfsmount *mnt, struct inode *dir, struct dentry *child) {
> +       if (child->d_inode)
> +               return -EEXIST;
> +       if (IS_DEADDIR(dir))
> +               return -ENOENT;
> +       if (MNT_IS_RDONLY(mnt))
> +               return -EROFS;
> +       return 0;
> +}
> +
> +static inline int mnt_may_unlink(struct vfsmount *mnt, struct inode *dir, struct dentry *child) {
> +       if (!child->d_inode)
> +               return -ENOENT;
> +       if (MNT_IS_RDONLY(mnt))
> +               return -EROFS;
> +       return 0;
> +}

Most of these checks are redundant, since they are already being done
elsewhere in the code.
child->d_inode is, for instance checked in may_delete() and in
may_create.
IS_DEADDIR is also checked in may_create.

>  /* 
>   * Special case: O_CREAT|O_EXCL implies O_NOFOLLOW for security
>   * reasons.
> @@ -1518,23 +1536,28 @@ do_link:
>  struct dentry *lookup_create(struct nameidata *nd, int is_dir)
>  {
>  	struct dentry *dentry;
> +	int error;
>  
>  	down(&nd->dentry->d_inode->i_sem);
> -	dentry = ERR_PTR(-EEXIST);
> +	error = -EEXIST;
>  	if (nd->last_type != LAST_NORM)
> -		goto fail;
> +		goto out;
>  	nd->flags &= ~LOOKUP_PARENT;
>  	dentry = lookup_hash(&nd->last, nd->dentry);
>  	if (IS_ERR(dentry))
> +		goto ret;
> +	error = mnt_may_create(nd->mnt, nd->dentry->d_inode, dentry);
> +	if (error)
>  		goto fail;
> +	error = -ENOENT;
>  	if (!is_dir && nd->last.name[nd->last.len] && !dentry->d_inode)
> -		goto enoent;
> +		goto fail;
> +ret:
>  	return dentry;
> -enoent:
> -	dput(dentry);
> -	dentry = ERR_PTR(-ENOENT);
>  fail:
> -	return dentry;
> +	dput(dentry);
> +out:
> +	return ERR_PTR(error);
>  }

What is the value of adding "error"? The current code is more efficient,
and just as readable.

Cheers,
  Trond

-- 
Trond Myklebust <trond.myklebust@fys.uio.no>


^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: [Patch 4/6] Bind Mount Extensions 0.06
  2005-02-22 12:12 [Patch 4/6] Bind Mount Extensions 0.06 Herbert Poetzl
  2005-02-22 14:45 ` Trond Myklebust
@ 2005-02-23  0:29 ` Ingo Oeser
  2005-02-24 21:22   ` Herbert Poetzl
  1 sibling, 1 reply; 6+ messages in thread
From: Ingo Oeser @ 2005-02-23  0:29 UTC (permalink / raw)
  To: Linux Kernel ML; +Cc: Andrew Morton, Al Viro

Hi,

Herbert Poetzl wrote:
> +static inline int mnt_may_unlink(struct vfsmount *mnt, struct inode *dir,
> struct dentry *child) { +       if (!child->d_inode)
> +               return -ENOENT;
> +       if (MNT_IS_RDONLY(mnt))
> +               return -EROFS;
> +       return 0;
> +}

The argument "dir" is not used. Please remove it and fix the callers.


Regards

Ingo Oeser


^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: [Patch 4/6] Bind Mount Extensions 0.06
  2005-02-22 14:45 ` Trond Myklebust
@ 2005-02-23 22:48   ` Herbert Poetzl
  2005-02-26 18:38   ` Herbert Poetzl
  1 sibling, 0 replies; 6+ messages in thread
From: Herbert Poetzl @ 2005-02-23 22:48 UTC (permalink / raw)
  To: Trond Myklebust; +Cc: Andrew Morton, Al Viro, Linux Kernel ML

On Tue, Feb 22, 2005 at 09:45:37AM -0500, Trond Myklebust wrote:
> ty den 22.02.2005 Klokka 13:12 (+0100) skreiv Herbert Poetzl:
> 
> > diff -NurpP --minimal linux-2.6.11-rc4-bme0.06-bm0.01-at0.01-cc0.01/fs/namei.c linux-2.6.11-rc4-bme0.06-bm0.01-at0.01-cc0.01-co0.01/fs/namei.c
> > --- linux-2.6.11-rc4-bme0.06-bm0.01-at0.01-cc0.01/fs/namei.c	2005-02-13 17:16:55 +0100
> > +++ linux-2.6.11-rc4-bme0.06-bm0.01-at0.01-cc0.01-co0.01/fs/namei.c	2005-02-19 06:31:50 +0100
> > @@ -1168,6 +1168,24 @@ static inline int may_create(struct inod
> >  	return permission(dir,MAY_WRITE | MAY_EXEC, nd);
> >  }
> >  
> > +static inline int mnt_may_create(struct vfsmount *mnt, struct inode *dir, struct dentry *child) {
> > +       if (child->d_inode)
> > +               return -EEXIST;
> > +       if (IS_DEADDIR(dir))
> > +               return -ENOENT;
> > +       if (MNT_IS_RDONLY(mnt))
> > +               return -EROFS;
> > +       return 0;
> > +}
> > +
> > +static inline int mnt_may_unlink(struct vfsmount *mnt, struct inode *dir, struct dentry *child) {
> > +       if (!child->d_inode)
> > +               return -ENOENT;
> > +       if (MNT_IS_RDONLY(mnt))
> > +               return -EROFS;
> > +       return 0;
> > +}
> 
> Most of these checks are redundant, since they are already being done
> elsewhere in the code.
> child->d_inode is, for instance checked in may_delete() and in
> may_create.

well, but mnt_may_create() for example is called from 
lookup_create() which in turn is (for example) called
from sys_mknod() which doesn't call may_delete() or
may_create() ... did I miss something?

> IS_DEADDIR is also checked in may_create.

ditto ...

> >  /* 
> >   * Special case: O_CREAT|O_EXCL implies O_NOFOLLOW for security
> >   * reasons.
> > @@ -1518,23 +1536,28 @@ do_link:
> >  struct dentry *lookup_create(struct nameidata *nd, int is_dir)
> >  {
> >  	struct dentry *dentry;
> > +	int error;
> >  
> >  	down(&nd->dentry->d_inode->i_sem);
> > -	dentry = ERR_PTR(-EEXIST);
> > +	error = -EEXIST;
> >  	if (nd->last_type != LAST_NORM)
> > -		goto fail;
> > +		goto out;
> >  	nd->flags &= ~LOOKUP_PARENT;
> >  	dentry = lookup_hash(&nd->last, nd->dentry);
> >  	if (IS_ERR(dentry))
> > +		goto ret;
> > +	error = mnt_may_create(nd->mnt, nd->dentry->d_inode, dentry);
> > +	if (error)
> >  		goto fail;
> > +	error = -ENOENT;
> >  	if (!is_dir && nd->last.name[nd->last.len] && !dentry->d_inode)
> > -		goto enoent;
> > +		goto fail;
> > +ret:
> >  	return dentry;
> > -enoent:
> > -	dput(dentry);
> > -	dentry = ERR_PTR(-ENOENT);
> >  fail:
> > -	return dentry;
> > +	dput(dentry);
> > +out:
> > +	return ERR_PTR(error);
> >  }
> 
> What is the value of adding "error"? 
> The current code is more efficient, and just as readable.

hmm, a compile test resulted in almost
identical code, but maybe I did miss some
aspect of the efficiency ...

anyway, thanks for the feedback,
Herbert

> Cheers,
>   Trond
> 
> -- 
> Trond Myklebust <trond.myklebust@fys.uio.no>

^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: [Patch 4/6] Bind Mount Extensions 0.06
  2005-02-23  0:29 ` Ingo Oeser
@ 2005-02-24 21:22   ` Herbert Poetzl
  0 siblings, 0 replies; 6+ messages in thread
From: Herbert Poetzl @ 2005-02-24 21:22 UTC (permalink / raw)
  To: Ingo Oeser; +Cc: Linux Kernel ML, Andrew Morton, Al Viro

On Wed, Feb 23, 2005 at 01:29:30AM +0100, Ingo Oeser wrote:
> Hi,
> 
> Herbert Poetzl wrote:
> > +static inline int mnt_may_unlink(struct vfsmount *mnt, struct inode *dir,
> > struct dentry *child) { +       if (!child->d_inode)
> > +               return -ENOENT;
> > +       if (MNT_IS_RDONLY(mnt))
> > +               return -EROFS;
> > +       return 0;
> > +}
> 
> The argument "dir" is not used. Please remove it and fix the callers.

hmm, yes, just saw that the mnt_may*() functions 
are not according to the 'current' coding style for 
that section/file, so I'll rework that anyway ...

thanks a lot for the input,
Herbert

> Regards
> 
> Ingo Oeser
> 
> -
> To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html
> Please read the FAQ at  http://www.tux.org/lkml/

^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: [Patch 4/6] Bind Mount Extensions 0.06
  2005-02-22 14:45 ` Trond Myklebust
  2005-02-23 22:48   ` Herbert Poetzl
@ 2005-02-26 18:38   ` Herbert Poetzl
  1 sibling, 0 replies; 6+ messages in thread
From: Herbert Poetzl @ 2005-02-26 18:38 UTC (permalink / raw)
  To: Trond Myklebust; +Cc: Andrew Morton, Al Viro, Linux Kernel ML

On Tue, Feb 22, 2005 at 09:45:37AM -0500, Trond Myklebust wrote:
> ty den 22.02.2005 Klokka 13:12 (+0100) skreiv Herbert Poetzl:
> 
> >   * Special case: O_CREAT|O_EXCL implies O_NOFOLLOW for security
> >   * reasons.
> > @@ -1518,23 +1536,28 @@ do_link:
> >  struct dentry *lookup_create(struct nameidata *nd, int is_dir)
> >  {
> >  	struct dentry *dentry;
> > +	int error;
> >  
> >  	down(&nd->dentry->d_inode->i_sem);
> > -	dentry = ERR_PTR(-EEXIST);
> > +	error = -EEXIST;
> >  	if (nd->last_type != LAST_NORM)
> > -		goto fail;
> > +		goto out;
> >  	nd->flags &= ~LOOKUP_PARENT;
> >  	dentry = lookup_hash(&nd->last, nd->dentry);
> >  	if (IS_ERR(dentry))
> > +		goto ret;
> > +	error = mnt_may_create(nd->mnt, nd->dentry->d_inode, dentry);
> > +	if (error)
> >  		goto fail;
> > +	error = -ENOENT;
> >  	if (!is_dir && nd->last.name[nd->last.len] && !dentry->d_inode)
> > -		goto enoent;
> > +		goto fail;
> > +ret:
> >  	return dentry;
> > -enoent:
> > -	dput(dentry);
> > -	dentry = ERR_PTR(-ENOENT);
> >  fail:
> > -	return dentry;
> > +	dput(dentry);
> > +out:
> > +	return ERR_PTR(error);
> >  }
> 
> What is the value of adding "error"? The current code is more efficient,
> and just as readable.

okay, had a deeper look at this and now I remember
why I added 'error' in the first place (quite some
time ago ;)

basically we need to check for RO in lookup_create()
now to give the same (error) results than a 'normal'
ro mounted filesystem, it is required to do the
dentry lookup and check the dentry->d_inode to return
EEXIST before returning EROFS ...

something like this would be the result:

        if (dentry->d_inode) {
                dput(dentry);
                dentry = ERR_PTR(-EEXIST);
                goto fail;
        }
        if (MNT_IS_RDONLY(nd->mnt)) {
                dput(dentry);
                dentry = ERR_PTR(-EROFS);
                goto fail;
        }

I'm currently looking into moving that check upwards
so that it will happen _after_ the EEXIST one ...

best,
Herbert

> Cheers,
>   Trond
> 
> -- 
> Trond Myklebust <trond.myklebust@fys.uio.no>

^ permalink raw reply	[flat|nested] 6+ messages in thread

end of thread, other threads:[~2005-02-26 18:38 UTC | newest]

Thread overview: 6+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2005-02-22 12:12 [Patch 4/6] Bind Mount Extensions 0.06 Herbert Poetzl
2005-02-22 14:45 ` Trond Myklebust
2005-02-23 22:48   ` Herbert Poetzl
2005-02-26 18:38   ` Herbert Poetzl
2005-02-23  0:29 ` Ingo Oeser
2005-02-24 21:22   ` Herbert Poetzl

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).