All of lore.kernel.org
 help / color / mirror / Atom feed
From: Boqun Feng <boqun.feng@gmail.com>
To: Al Viro <viro@ZenIV.linux.org.uk>
Cc: linux-fsdevel@vger.kernel.org, linux-kernel@vger.kernel.org
Subject: Re: Is it OK to export symbols 'getname' and 'putname'?
Date: Sat, 18 Apr 2015 08:20:13 +0800	[thread overview]
Message-ID: <20150418002012.GA6341@fixme-laptop> (raw)
In-Reply-To: <20150417123530.GA4249@fixme-laptop.cn.ibm.com>

[-- Attachment #1: Type: text/plain, Size: 5317 bytes --]

On Fri, Apr 17, 2015 at 08:35:30PM +0800, Boqun Feng wrote:
> Hi Al,
> 
> On Sun, Apr 12, 2015 at 02:13:18AM +0100, Al Viro wrote:
> > 
> > BTW, looking at the __getname() callers...  Lustre one sure as hell looks
> > bogus:
> >         char *tmp = __getname();
> > 
> >         if (!tmp)
> >                 return ERR_PTR(-ENOMEM);
> > 
> >         len = strncpy_from_user(tmp, filename, PATH_MAX);
> >         if (len == 0)
> >                 ret = -ENOENT;
> >         else if (len > PATH_MAX)
> >                 ret = -ENAMETOOLONG;
> > 
> >         if (ret) {
> >                 __putname(tmp);
> >                 tmp =  ERR_PTR(ret);
> >         }
> >         return tmp;
> > 
> > Note that
> > 	* strncpy_from_user(p, u, n) can return a negative (-EFAULT)
> > 	* strncpy_from_user(p, u, n) cannot return a positive greater than
> > n.  In case of missing NUL among the n bytes starting at u (and no faults
> > accessing those) we get exactly n bytes copied and n returned.  In case
> > when NUL is there, we copy everything up to and including that NUL and
> > return number of non-NUL bytes copied.
> > 
> > IOW, these failure cases had never been tested.  Name being too long ends up
> > with non-NUL-terminated array of characters returned, and the very first
> > caller of ll_getname() feeds it to strlen().  Fault ends up with uninitialized
> > array...
> > 
> > AFAICS, the damn thing should just use getname() and quit reinventing the
> > wheel, badly.
> > 
> 
> I'm trying to clean that part of code you mentioned, and I found I have
> to export the symbols 'getname' and 'putname' as follow to replace that
> __getname() caller:
> 
> diff --git a/drivers/staging/lustre/lustre/llite/dir.c b/drivers/staging/lustre/lustre/llite/dir.c
> index a182019..014f51a 100644
> --- a/drivers/staging/lustre/lustre/llite/dir.c
> +++ b/drivers/staging/lustre/lustre/llite/dir.c
> @@ -1216,29 +1216,8 @@ out:
>  	return rc;
>  }
>  
> -static char *
> -ll_getname(const char __user *filename)
> -{
> -	int ret = 0, len;
> -	char *tmp = __getname();
> -
> -	if (!tmp)
> -		return ERR_PTR(-ENOMEM);
> -
> -	len = strncpy_from_user(tmp, filename, PATH_MAX);
> -	if (len == 0)
> -		ret = -ENOENT;
> -	else if (len > PATH_MAX)
> -		ret = -ENAMETOOLONG;
> -
> -	if (ret) {
> -		__putname(tmp);
> -		tmp =  ERR_PTR(ret);
> -	}
> -	return tmp;
> -}
> -
> -#define ll_putname(filename) __putname(filename)
> +#define ll_getname(filename) getname(filename)
> +#define ll_putname(name) putname(name)
>  
>  static long ll_dir_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
>  {
> @@ -1441,6 +1420,7 @@ free_lmv:
>  		return rc;
>  	}
>  	case LL_IOC_REMOVE_ENTRY: {
> +		struct filename *name = NULL;
>  		char		*filename = NULL;
>  		int		 namelen = 0;
>  		int		 rc;
> @@ -1453,20 +1433,17 @@ free_lmv:
>  		if (!(exp_connect_flags(sbi->ll_md_exp) & OBD_CONNECT_LVB_TYPE))
>  			return -ENOTSUPP;
>  
> -		filename = ll_getname((const char *)arg);
> -		if (IS_ERR(filename))
> -			return PTR_ERR(filename);
> +		name = ll_getname((const char *)arg);
> +		if (IS_ERR(name))
> +			return PTR_ERR(name);
>  
> +		filename = name->name;
>  		namelen = strlen(filename);
> -		if (namelen < 1) {
> -			rc = -EINVAL;
> -			goto out_rmdir;
> -		}
>  
>  		rc = ll_rmdir_entry(inode, filename, namelen);
>  out_rmdir:
> -		if (filename)
> -			ll_putname(filename);
> +		if (name)
> +			ll_putname(name);
>  		return rc;
>  	}
>  	case LL_IOC_LOV_SWAP_LAYOUTS:
> @@ -1481,15 +1458,17 @@ out_rmdir:
>  		struct lov_user_md *lump;
>  		struct lov_mds_md *lmm = NULL;
>  		struct mdt_body *body;
> +		struct filename *name;
>  		char *filename = NULL;
>  		int lmmsize;
>  
>  		if (cmd == IOC_MDC_GETFILEINFO ||
>  		    cmd == IOC_MDC_GETFILESTRIPE) {
> -			filename = ll_getname((const char *)arg);
> -			if (IS_ERR(filename))
> -				return PTR_ERR(filename);
> +			name = ll_getname((const char *)arg);
> +			if (IS_ERR(name))
> +				return PTR_ERR(name);
>  
> +			filename = name->name;
>  			rc = ll_lov_getstripe_ea_info(inode, filename, &lmm,
>  						      &lmmsize, &request);
>  		} else {

Sorry.. one modification is missing here:

@@ -1535,8 +1535,8 @@ skip_lmm:
 
 out_req:
                ptlrpc_req_finished(request);
-               if (filename)
-                       ll_putname(filename);
+               if (name)
+                       ll_putname(name);
                return rc;
        }
        case IOC_LOV_GETINFO: {

Regards,
Boqun

> diff --git a/fs/namei.c b/fs/namei.c
> index ffab2e0..7a0948c 100644
> --- a/fs/namei.c
> +++ b/fs/namei.c
> @@ -205,6 +205,7 @@ getname(const char __user * filename)
>  {
>  	return getname_flags(filename, 0, NULL);
>  }
> +EXPORT_SYMBOL(getname);
>  
>  struct filename *
>  getname_kernel(const char * filename)
> @@ -254,6 +255,7 @@ void putname(struct filename *name)
>  	} else
>  		__putname(name);
>  }
> +EXPORT_SYMBOL(putname);
>  
>  static int check_acl(struct inode *inode, int mask)
>  {
> 
> 
> 
> Is that a good idea to export these symbols, given that lustre may be
> the only user? 
> 
> Looking forward to your insight.
> 
> Thanks,
> Boqun



[-- Attachment #2: Type: application/pgp-signature, Size: 473 bytes --]

  reply	other threads:[~2015-04-18  0:20 UTC|newest]

Thread overview: 17+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2015-03-25 18:45 [PATCH v2] vfs: avoid recopying file names in getname_flags Boqun Feng
2015-03-29  4:27 ` Boqun Feng
2015-03-29 10:14   ` Richard Weinberger
2015-03-29 15:23     ` Boqun Feng
2015-04-07  8:38   ` Boqun Feng
2015-04-11 23:56     ` Al Viro
2015-04-12  1:13       ` Al Viro
2015-04-13  7:34         ` Boqun Feng
2015-04-17 12:35         ` Is it OK to export symbols 'getname' and 'putname'? Boqun Feng
2015-04-18  0:20           ` Boqun Feng [this message]
2015-04-20 15:55           ` Jan Kara
2015-04-22  2:38             ` Boqun Feng
2015-04-22  5:50             ` Christoph Hellwig
2015-04-23  5:32               ` Boqun Feng
2015-04-13  6:33       ` [PATCH v2] vfs: avoid recopying file names in getname_flags Boqun Feng
2015-03-29 10:13 ` Richard Weinberger
2015-03-29 15:10   ` Boqun Feng

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20150418002012.GA6341@fixme-laptop \
    --to=boqun.feng@gmail.com \
    --cc=linux-fsdevel@vger.kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=viro@ZenIV.linux.org.uk \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.