Commit 33487c87 authored by Andrew Morton's avatar Andrew Morton Committed by Linus Torvalds

[PATCH] shmdt bugfix

Patch from Hugh Dickins <hugh@veritas.com>

Fixes the Oracle startup problem reported by Alessandro Suardi.

Reverts a "simplification" to shmdt() which was wrong if subsequent
mprotects broke up the original VMA, or if parts of it were munmapped.
parent a838ea3b
...@@ -700,24 +700,18 @@ asmlinkage long sys_shmat (int shmid, char *shmaddr, int shmflg, ulong *raddr) ...@@ -700,24 +700,18 @@ asmlinkage long sys_shmat (int shmid, char *shmaddr, int shmflg, ulong *raddr)
asmlinkage long sys_shmdt (char *shmaddr) asmlinkage long sys_shmdt (char *shmaddr)
{ {
struct mm_struct *mm = current->mm; struct mm_struct *mm = current->mm;
struct vm_area_struct *vma; struct vm_area_struct *shmd, *shmdnext;
unsigned long address = (unsigned long)shmaddr;
int retval = -EINVAL; int retval = -EINVAL;
down_write(&mm->mmap_sem); down_write(&mm->mmap_sem);
vma = find_vma(mm, address); for (shmd = mm->mmap; shmd; shmd = shmdnext) {
if (!vma) shmdnext = shmd->vm_next;
goto out; if ((shmd->vm_ops == &shm_vm_ops || (shmd->vm_flags & VM_HUGETLB))
if (vma->vm_start != address) && shmd->vm_start - (shmd->vm_pgoff << PAGE_SHIFT) == (ulong) shmaddr) {
goto out; do_munmap(mm, shmd->vm_start, shmd->vm_end - shmd->vm_start);
/* ->vm_pgoff is always 0, see do_mmap() in sys_shmat() */
retval = 0; retval = 0;
if (vma->vm_ops == &shm_vm_ops || (vma->vm_flags & VM_HUGETLB)) }
do_munmap(mm, vma->vm_start, vma->vm_end - vma->vm_start); }
else
retval = -EINVAL;
out:
up_write(&mm->mmap_sem); up_write(&mm->mmap_sem);
return retval; return retval;
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment