All of lore.kernel.org
 help / color / mirror / Atom feed
From: Johannes Weiner <hannes@cmpxchg.org>
To: Andrea Righi <righi.andrea@gmail.com>
Cc: Dave Jones <davej@redhat.com>,
	Krzysztof Helt <krzysztof.h1@wp.pl>,
	Andrew Morton <akpm@linux-foundation.org>,
	LKML <linux-kernel@vger.kernel.org>
Subject: Re: [PATCH] fbmem: fix copy_from/to_user() with mutex held
Date: Mon, 19 Jan 2009 08:54:41 +0100	[thread overview]
Message-ID: <20090119075440.GA1500@cmpxchg.org> (raw)
In-Reply-To: <49738E4B.1030200@gmail.com>

Hi,

On Sun, Jan 18, 2009 at 09:17:15PM +0100, Andrea Righi wrote:
> Avoid to call copy_from/to_user() with fb_info->lock mutex held in fbmem
> fb_ioctl().
> 
> NOTE: it doesn't push down the fb_info->lock in each driver's fb_ioctl().
> 
> Signed-off-by: Andrea Righi <righi.andrea@gmail.com>

This should probably also include an explanation for WHY doing uaccess
under fb_info->lock is verboten.  Perhaps even a comment because I
don't think it is obvious from the code.

> ---
>  drivers/video/fbcmap.c |   21 +++++--
>  drivers/video/fbmem.c  |  158 ++++++++++++++++++++++++++++--------------------
>  include/linux/fb.h     |    5 +-
>  3 files changed, 112 insertions(+), 72 deletions(-)
> 
> diff --git a/drivers/video/fbcmap.c b/drivers/video/fbcmap.c
> index 91b78e6..b19f12c 100644
> --- a/drivers/video/fbcmap.c
> +++ b/drivers/video/fbcmap.c
> @@ -250,10 +250,6 @@ int fb_set_user_cmap(struct fb_cmap_user *cmap, struct fb_info *info)
>  	int rc, size = cmap->len * sizeof(u16);
>  	struct fb_cmap umap;
>  
> -	if (cmap->start < 0 || (!info->fbops->fb_setcolreg &&
> -			        !info->fbops->fb_setcmap))
> -		return -EINVAL;
> -
>  	memset(&umap, 0, sizeof(struct fb_cmap));
>  	rc = fb_alloc_cmap(&umap, cmap->len, cmap->transp != NULL);
>  	if (rc)
> @@ -262,11 +258,24 @@ int fb_set_user_cmap(struct fb_cmap_user *cmap, struct fb_info *info)
>  	    copy_from_user(umap.green, cmap->green, size) ||
>  	    copy_from_user(umap.blue, cmap->blue, size) ||
>  	    (cmap->transp && copy_from_user(umap.transp, cmap->transp, size))) {
> -		fb_dealloc_cmap(&umap);
> -		return -EFAULT;
> +		rc = -EFAULT;
> +		goto out;
>  	}
>  	umap.start = cmap->start;
> +	info = get_fb_info(info);
> +	if (!info) {
> +		rc = -ENODEV;
> +		goto out;
> +	}
> +	if (cmap->start < 0 || (!info->fbops->fb_setcolreg &&
> +				!info->fbops->fb_setcmap)) {
> +		rc = -EINVAL;
> +		goto out1;
> +	}
>  	rc = fb_set_cmap(&umap, info);
> +out1:
> +	put_fb_info(info);
> +out:
>  	fb_dealloc_cmap(&umap);
>  	return rc;
>  }
> diff --git a/drivers/video/fbmem.c b/drivers/video/fbmem.c
> index 756efeb..e51e9ba 100644
> --- a/drivers/video/fbmem.c
> +++ b/drivers/video/fbmem.c
> @@ -1006,6 +1006,23 @@ fb_blank(struct fb_info *info, int blank)
>   	return ret;
>  }
>  
> +struct fb_info *get_fb_info(struct fb_info *info)
> +__acquires(&info->lock)
> +{
> +	mutex_lock(&info->lock);
> +	if (!info->fbops) {
> +		mutex_unlock(&info->lock);
> +		return NULL;
> +	}
> +	return info;
> +}
> +
> +void put_fb_info(struct fb_info *info)
> +__releases(&info->lock)
> +{
> +	mutex_unlock(&info->lock);
> +}
> +
>  static long do_fb_ioctl(struct fb_info *info, unsigned int cmd,
>  			unsigned long arg)
>  {
> @@ -1013,25 +1030,28 @@ static long do_fb_ioctl(struct fb_info *info, unsigned int cmd,
>  	struct fb_var_screeninfo var;
>  	struct fb_fix_screeninfo fix;
>  	struct fb_con2fbmap con2fb;
> +	struct fb_cmap cmap_from;
>  	struct fb_cmap_user cmap;
>  	struct fb_event event;
>  	void __user *argp = (void __user *)arg;
>  	long ret = 0;
>  
> -	fb = info->fbops;
> -	if (!fb)
> -		return -ENODEV;
> -
>  	switch (cmd) {
>  	case FBIOGET_VSCREENINFO:
> -		ret = copy_to_user(argp, &info->var,
> -				    sizeof(var)) ? -EFAULT : 0;
> +		info = get_fb_info(info);
> +		if (!info)
> +			return -ENODEV;
> +		memcpy(&var, &info->var, sizeof(var));

You don't need these memcpy()s:

		var = info->var

does the same much more readable.

Thanks,
	hannes

  reply	other threads:[~2009-01-19  7:55 UTC|newest]

Thread overview: 9+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2009-01-17 23:19 .29rc2 lockdep report. fb_mmap vs sys_mmap2 Dave Jones
2009-01-18  2:00 ` Johannes Weiner
2009-01-18 19:21   ` Andrea Righi
2009-01-18 20:17   ` [PATCH] fbmem: fix copy_from/to_user() with mutex held Andrea Righi
2009-01-19  7:54     ` Johannes Weiner [this message]
2009-01-19  7:58     ` Stefan Richter
2009-01-19  8:05       ` Stefan Richter
2009-01-19  8:10         ` Harvey Harrison
2009-01-19  8:29           ` Andrea Righi

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=20090119075440.GA1500@cmpxchg.org \
    --to=hannes@cmpxchg.org \
    --cc=akpm@linux-foundation.org \
    --cc=davej@redhat.com \
    --cc=krzysztof.h1@wp.pl \
    --cc=linux-kernel@vger.kernel.org \
    --cc=righi.andrea@gmail.com \
    /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.