From: Michal Piotrowski <michal.k.k.piotrowski@gmail.com>
To: "Eric W. Biederman" <ebiederm@xmission.com>
Cc: Michal Piotrowski <michal.k.k.piotrowski@gmail.com>,
Andrew Morton <akpm@linux-foundation.org>,
linux-kernel@vger.kernel.org
Subject: Re: [PATCH] shm: Fix the locking and cleanup error handling in do_shmat.
Date: Fri, 16 Feb 2007 01:16:44 +0100 [thread overview]
Message-ID: <45D4F7EC.90908@googlemail.com> (raw)
In-Reply-To: <m1r6srhsrt.fsf_-_@ebiederm.dsl.xmission.com>
Eric W. Biederman napisał(a):
> When enhancing do_shmat I forgot to take into account that shm_lock
> is a spinlock, and was allocating memory with the lock held.
>
> This patch fixes that by grabbing a reference to the dentry and
> mounts of shm_file before we drop the shm_lock and then performing
> the memory allocations.
>
> This is also a bit of a general scrub on the error handling.
> Everything is now forced through the single return statement
> for clarity, and the handling of the return address now uses
> fewer casts.
>
> Signed-off-by: Eric W. Biederman <ebiederm@xmission.com>
> ---
> ipc/shm.c | 56 ++++++++++++++++++++++++++++++++------------------------
> 1 files changed, 32 insertions(+), 24 deletions(-)
>
> diff --git a/ipc/shm.c b/ipc/shm.c
> index e0b6544..26b935b 100644
> --- a/ipc/shm.c
> +++ b/ipc/shm.c
> @@ -815,15 +815,16 @@ long do_shmat(int shmid, char __user *shmaddr, int shmflg, ulong *raddr)
> unsigned long flags;
> unsigned long prot;
> int acc_mode;
> - void *user_addr;
> + unsigned long user_addr;
> struct ipc_namespace *ns;
> struct shm_file_data *sfd;
> + struct path path;
> mode_t f_mode;
>
> - if (shmid < 0) {
> - err = -EINVAL;
> + err = -EINVAL;
> + if (shmid < 0)
> goto out;
> - } else if ((addr = (ulong)shmaddr)) {
> + else if ((addr = (ulong)shmaddr)) {
> if (addr & (SHMLBA-1)) {
> if (shmflg & SHM_RND)
> addr &= ~(SHMLBA-1); /* round down */
> @@ -831,12 +832,12 @@ long do_shmat(int shmid, char __user *shmaddr, int shmflg, ulong *raddr)
> #ifndef __ARCH_FORCE_SHMLBA
> if (addr & ~PAGE_MASK)
> #endif
> - return -EINVAL;
> + goto out;
> }
> flags = MAP_SHARED | MAP_FIXED;
> } else {
> if ((shmflg & SHM_REMAP))
> - return -EINVAL;
> + goto out;
>
> flags = MAP_SHARED;
> }
> @@ -860,7 +861,6 @@ long do_shmat(int shmid, char __user *shmaddr, int shmflg, ulong *raddr)
> * additional creator id...
> */
> ns = current->nsproxy->ipc_ns;
> - err = -EINVAL;
> shp = shm_lock(ns, shmid);
> if(shp == NULL)
> goto out;
> @@ -877,19 +877,25 @@ long do_shmat(int shmid, char __user *shmaddr, int shmflg, ulong *raddr)
> if (err)
> goto out_unlock;
>
> + path.dentry = dget(shp->shm_file->f_path.dentry);
> + path.mnt = mntget(shp->shm_file->f_path.mnt);
> + shp->shm_nattch++;
> + size = i_size_read(path.dentry->d_inode);
> + shm_unlock(shp);
> +
> err = -ENOMEM;
> sfd = kzalloc(sizeof(*sfd), GFP_KERNEL);
> if (!sfd)
> - goto out_unlock;
> + goto out_put_path;
>
> + err = -ENOMEM;
> file = get_empty_filp();
> if (!file)
> goto out_free;
>
> file->f_op = &shm_file_operations;
> file->private_data = sfd;
> - file->f_path.dentry = dget(shp->shm_file->f_path.dentry);
> - file->f_path.mnt = mntget(shp->shm_file->f_path.mnt);
> + file->f_path = path;
> file->f_mapping = shp->shm_file->f_mapping;
> file->f_mode = f_mode;
> sfd->id = shp->id;
> @@ -897,13 +903,9 @@ long do_shmat(int shmid, char __user *shmaddr, int shmflg, ulong *raddr)
> sfd->file = shp->shm_file;
> sfd->vm_ops = NULL;
>
> - size = i_size_read(file->f_path.dentry->d_inode);
> - shp->shm_nattch++;
> - shm_unlock(shp);
> -
> down_write(¤t->mm->mmap_sem);
> if (addr && !(shmflg & SHM_REMAP)) {
> - user_addr = ERR_PTR(-EINVAL);
> + err = -EINVAL;
> if (find_vma_intersection(current->mm, addr, addr + size))
> goto invalid;
> /*
> @@ -915,13 +917,17 @@ long do_shmat(int shmid, char __user *shmaddr, int shmflg, ulong *raddr)
> goto invalid;
> }
>
> - user_addr = (void*) do_mmap (file, addr, size, prot, flags, 0);
> -
> + user_addr = do_mmap (file, addr, size, prot, flags, 0);
> + *raddr = user_addr;
> + err = 0;
> + if (IS_ERR_VALUE(user_addr))
> + err = (long)user_addr;
> invalid:
> up_write(¤t->mm->mmap_sem);
> -
> +
> fput(file);
>
> +out_nattch:
> mutex_lock(&shm_ids(ns).mutex);
> shp = shm_lock(ns, shmid);
> BUG_ON(!shp);
> @@ -933,17 +939,19 @@ invalid:
^^^^
???
> shm_unlock(shp);
> mutex_unlock(&shm_ids(ns).mutex);
>
> - *raddr = (unsigned long) user_addr;
> - err = 0;
> - if (IS_ERR(user_addr))
> - err = PTR_ERR(user_addr);
> out:
> return err;
> -out_free:
> - kfree(sfd);
> +
> out_unlock:
> shm_unlock(shp);
> goto out;
> +
> +out_free:
> + kfree(sfd);
> +out_put_path:
> + dput(path.dentry);
> + mntput(path.mnt);
> + goto out_nattch;
>
^^^^ tabs
> }
>
Regards,
Michal
--
Michal K. K. Piotrowski
LTG - Linux Testers Group (PL)
(http://www.stardust.webpages.pl/ltg/)
LTG - Linux Testers Group (EN)
(http://www.stardust.webpages.pl/linux_testers_group_en/)
next prev parent reply other threads:[~2007-02-16 0:16 UTC|newest]
Thread overview: 81+ messages / expand[flat|nested] mbox.gz Atom feed top
2007-02-15 13:14 2.6.20-mm1 Andrew Morton
2007-02-15 14:28 ` 2.6.20-mm1 [kernel BUG at mm/swap.c:442] James Morris
2007-02-15 14:37 ` James Morris
2007-02-15 21:51 ` Andrew Morton
2007-02-15 22:39 ` Christoph Lameter
2007-02-16 14:30 ` James Morris
2007-02-16 14:59 ` James Morris
2007-02-16 15:57 ` Christoph Lameter
2007-02-16 21:28 ` James Morris
2007-02-15 14:37 ` 2.6.20-mm1 Michal Piotrowski
2007-02-15 22:02 ` 2.6.20-mm1 Andrew Morton
2007-02-15 22:38 ` 2.6.20-mm1 Eric W. Biederman
2007-02-15 23:24 ` 2.6.20-mm1 Michal Piotrowski
2007-02-16 0:04 ` [PATCH] shm: Fix the locking and cleanup error handling in do_shmat Eric W. Biederman
2007-02-16 0:16 ` Michal Piotrowski [this message]
2007-02-16 0:21 ` Michal Piotrowski
2007-02-16 3:34 ` Eric W. Biederman
2007-02-16 4:10 ` Wu, Bryan
2007-02-16 0:16 ` 2.6.20-mm1 Andrew Morton
2007-02-15 15:01 ` [-mm patch] MARKERS should depend on, not select MODULES Adrian Bunk
2007-02-15 19:27 ` Mathieu Desnoyers
2007-02-15 16:01 ` sparse chokes on arch/i386/kernel/i8253.c (was: 2.6.20-mm1) Tilman Schmidt
2007-02-15 22:41 ` Andrew Morton
2007-02-15 22:46 ` Mathieu Desnoyers
2007-02-15 23:44 ` Andrew Morton
2007-02-16 0:37 ` Mathieu Desnoyers
2007-02-16 1:22 ` Andrew Morton
2007-02-16 18:05 ` [PATCH] Move include linux/marker.h to kernel.h Mathieu Desnoyers
2007-02-16 18:43 ` Andrew Morton
2007-02-16 18:52 ` [PATCH] Move include linux/marker.h from Makefile Mathieu Desnoyers
2007-02-17 12:50 ` [PATCH] Move include linux/marker.h to kernel.h Tim Schmielau
2007-02-16 0:23 ` [PATCH] sparse chokes on arch/i386/kernel/i8253.c Mathieu Desnoyers
2007-02-16 0:37 ` Andrew Morton
2007-02-16 0:58 ` Mathieu Desnoyers
2007-02-16 1:31 ` Andrew Morton
2007-02-15 16:27 ` 2.6.20-mm1 Artem Bityutskiy
2007-02-15 17:33 ` 2.6.20-mm1 Valdis.Kletnieks
2007-02-15 18:00 ` 2.6.20-mm1 Marcin Juszkiewicz
2007-02-15 18:27 ` 2.6.20-mm1 Richard Purdie
2007-02-15 19:29 ` 2.6.20-mm1 Mattia Dongili
2007-02-15 19:39 ` 2.6.20-mm1 Richard Purdie
2007-02-15 21:30 ` 2.6.20-mm1 J.A. Magallón
2007-02-15 23:31 ` 2.6.20-mm1 Andrew Morton
2007-02-15 23:39 ` 2.6.20-mm1 J.A. Magallón
2007-02-16 5:30 ` 2.6.20-mm1 Andrew Morton
2007-02-16 23:50 ` 2.6.20-mm1 J.A. Magallón
2007-02-15 22:51 ` 2.6.20-mm1 Bartlomiej Zolnierkiewicz
2007-02-15 23:56 ` [PATCH 1/1] unify queue_delayed_work and queue_delayed_work_on fix Jiri Slaby
2007-02-16 0:10 ` Jiri Slaby
2007-02-16 13:55 ` Oleg Nesterov
2007-02-16 16:37 ` 2.6.20-mm1 Steve Fox
2007-02-16 16:55 ` 2.6.20-mm1 Randy Dunlap
2007-02-19 16:10 ` 2.6.20-mm1 Steve Fox
2007-02-16 16:41 ` [-mm patch] pci_iomap_regions error handling fix (was Re: 2.6.20-mm1) Frederik Deweerdt
2007-02-15 23:50 ` Andrew Morton
2007-02-16 17:14 ` 2.6.20-mm1 - undefined reference to `delete_module' on x86 Steve Fox
2007-02-16 18:37 ` Andrew Morton
2007-02-20 0:02 ` [-mm patch] make struct vmi_ops static Adrian Bunk
2007-02-20 0:02 ` [-mm patch] marker exports must be EXPORT_SYMBOL_GPL Adrian Bunk
2007-02-20 23:15 ` Mathieu Desnoyers
2007-02-20 0:07 ` [-mm patch] {rd,wr}msr_on_cpu SMP=n optimization Adrian Bunk
2007-02-20 0:14 ` Dave Jones
2007-02-20 0:21 ` Adrian Bunk
2007-02-20 0:29 ` Dave Jones
2007-02-20 13:50 ` Alexey Dobriyan
2007-02-20 19:25 ` Dave Jones
2007-02-20 0:07 ` [-mm patch] drivers/net/vioc/: possible cleanups Adrian Bunk
2007-02-20 0:07 ` [-mm patch] make dvb_usb_gl861_debug static Adrian Bunk
2007-02-20 16:13 ` [v4l-dvb-maintainer] " Michael Krufky
2007-02-20 0:07 ` [-mm patch] make pvr2_encoder_prep_config() static Adrian Bunk
2007-02-20 0:07 ` [-mm patch] make drivers/usb/misc/iowarrior.c:iowarrior_ids[] static Adrian Bunk
2007-02-20 0:07 ` [-mm patch] make fs/partitions/msdos.c:check_sane_values() static Adrian Bunk
2007-02-20 0:07 ` [-mm patch] make kernel/kmod.c:kmod_mk static Adrian Bunk
2007-02-20 0:07 ` [-mm patch] make ipc/shm.c:shm_nopage() static Adrian Bunk
2007-02-20 2:13 ` Eric W. Biederman
2007-02-20 0:07 ` [-mm patch] mm/{,tiny-}shmem.c cleanups Adrian Bunk
2007-02-20 0:08 ` 2.6.20-mm1: PTRACE=y, PROC_FS=n compile error Adrian Bunk
2007-02-21 10:15 ` Roland McGrath
2007-02-22 3:35 ` Christoph Hellwig
2007-02-20 0:08 ` [-mm patch] include/linux/ptrace.h must #include <linux/errno.h> Adrian Bunk
2007-02-21 9:57 ` Roland McGrath
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=45D4F7EC.90908@googlemail.com \
--to=michal.k.k.piotrowski@gmail.com \
--cc=akpm@linux-foundation.org \
--cc=ebiederm@xmission.com \
--cc=linux-kernel@vger.kernel.org \
/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.