All of lore.kernel.org
 help / color / mirror / Atom feed
From: NeilBrown <neilb@suse.de>
To: Nicolas Schichan <nschichan@freebox.fr>
Cc: linux-raid@vger.kernel.org, linux-kernel@vger.kernel.org
Subject: Re: [PATCH] md: check command validity early in md_ioctl().
Date: Thu, 16 Jan 2014 08:55:36 +1100	[thread overview]
Message-ID: <20140116085536.54a3f56a@notabene.brown> (raw)
In-Reply-To: <1389801532-25567-1-git-send-email-nschichan@freebox.fr>

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

On Wed, 15 Jan 2014 16:58:52 +0100 Nicolas Schichan <nschichan@freebox.fr>
wrote:

> Verify that the cmd parameter passed to md_ioctl() is valid before
> doing anything.
> 
> This fixes mddev->hold_active being set to 0 when an invalid ioctl
> command is passed to md_ioctl() before the array has been configured.
> 
> Clearing mddev->hold_active in that case can lead to a livelock
> situation when an invalid ioctl number is given to md_ioctl() by a
> process when the mddev is currently being opened by another process:
> 
> Process 1				Process 2
> ---------				---------
> 
> md_alloc()
>   mddev_find()
>   -> returns a new mddev with
>      hold_active == UNTIL_IOCTL
>   add_disk()
>   -> sends KOBJ_ADD uevent
> 
> 					(sees KOBJ_ADD uevent for device)
>                     			md_open()
>                     			md_ioctl(INVALID_IOCTL)
>                     			-> returns ENODEV and clears
>                        			   mddev->hold_active
>                     			md_release()
>                       			md_put()
>                       			-> deletes the mddev as
>                          		   hold_active is 0
> 
> md_open()
>   mddev_find()
>   -> returns a newly
>     allocated mddev with
>     mddev->gendisk == NULL
> -> returns with ERESTARTSYS
>    (kernel restarts the open syscall)
> 
> Signed-off-by: Nicolas Schichan <nschichan@freebox.fr>
> ---
> 
> A couple of notes:
> 
> This patch is based on linux 3.13-rc8.
> 
> The following  MD ioctl constants are  defined in md_u.h  but not used
> anywhere else, so are not accepted as valid ioctl commands:
> 
> CLEAR_ARRAY
> SET_DISK_INFO
> WRITE_RAID_INFO
> UNPROTECT_ARRAY
> PROTECT_ARRAY
> 
> 
>  drivers/md/md.c | 29 +++++++++++++++++++++++++++++
>  1 file changed, 29 insertions(+)
> 
> diff --git a/drivers/md/md.c b/drivers/md/md.c
> index 21f4d7f..941ac65 100644
> --- a/drivers/md/md.c
> +++ b/drivers/md/md.c
> @@ -6328,6 +6328,32 @@ static int md_getgeo(struct block_device *bdev, struct hd_geometry *geo)
>  	return 0;
>  }
>  
> +static inline bool md_ioctl_valid(unsigned int cmd)
> +{
> +	switch (cmd) {
> +	case ADD_NEW_DISK:
> +	case BLKROSET:
> +	case GET_ARRAY_INFO:
> +	case GET_BITMAP_FILE:
> +	case GET_DISK_INFO:
> +	case HOT_ADD_DISK:
> +	case HOT_REMOVE_DISK:
> +	case PRINT_RAID_DEBUG:
> +	case RAID_AUTORUN:
> +	case RAID_VERSION:
> +	case RESTART_ARRAY_RW:
> +	case RUN_ARRAY:
> +	case SET_ARRAY_INFO:
> +	case SET_BITMAP_FILE:
> +	case SET_DISK_FAULTY:
> +	case STOP_ARRAY:
> +	case STOP_ARRAY_RO:
> +		return true;
> +	default:
> +		return false;
> +	}
> +}
> +
>  static int md_ioctl(struct block_device *bdev, fmode_t mode,
>  			unsigned int cmd, unsigned long arg)
>  {
> @@ -6336,6 +6362,9 @@ static int md_ioctl(struct block_device *bdev, fmode_t mode,
>  	struct mddev *mddev = NULL;
>  	int ro;
>  
> +	if (!md_ioctl_valid(cmd))
> +		return -ENOTTY;
> +
>  	switch (cmd) {
>  	case RAID_VERSION:
>  	case GET_ARRAY_INFO:


Patch applied - thanks!

NeilBrown

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 828 bytes --]

      reply	other threads:[~2014-01-15 21:55 UTC|newest]

Thread overview: 5+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2014-01-14 17:14 livelock during MD device open Nicolas Schichan
2014-01-15  1:57 ` NeilBrown
2014-01-15 13:11   ` Nicolas Schichan
2014-01-15 15:58   ` [PATCH] md: check command validity early in md_ioctl() Nicolas Schichan
2014-01-15 21:55     ` NeilBrown [this message]

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=20140116085536.54a3f56a@notabene.brown \
    --to=neilb@suse.de \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-raid@vger.kernel.org \
    --cc=nschichan@freebox.fr \
    /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.