Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 676758bd authored by Andrew Morton's avatar Andrew Morton Committed by Linus Torvalds
Browse files

[PATCH] msync: fix return value



msync() does a strange thing.  Essentially:

	vma = find_vma();
	for ( ; ; ) {
		if (!vma)
			return -ENOMEM;
		...
		vma = vma->vm_next;
	}

so an msync() request which starts within or before a valid VMA and which ends
within or beyond the final VMA will incorrectly return -ENOMEM.

Fix.

Cc: Hugh Dickins <hugh@veritas.com>
Cc: Nick Piggin <nickpiggin@yahoo.com.au>
Signed-off-by: default avatarAndrew Morton <akpm@osdl.org>
Signed-off-by: default avatarLinus Torvalds <torvalds@osdl.org>
parent 707c21c8
Loading
Loading
Loading
Loading
+7 −7
Original line number Diff line number Diff line
@@ -146,7 +146,8 @@ asmlinkage long sys_msync(unsigned long start, size_t len, int flags)
{
	unsigned long end;
	struct vm_area_struct *vma;
	int unmapped_error, error = -EINVAL;
	int unmapped_error = 0;
	int error = -EINVAL;
	int done = 0;

	if (flags & ~(MS_ASYNC | MS_INVALIDATE | MS_SYNC))
@@ -171,15 +172,14 @@ asmlinkage long sys_msync(unsigned long start, size_t len, int flags)
	if (flags & MS_SYNC)
		current->flags |= PF_SYNCWRITE;
	vma = find_vma(current->mm, start);
	unmapped_error = 0;
	if (!vma) {
		error = -ENOMEM;
		goto out_unlock;
	}
	do {
		unsigned long nr_pages_dirtied = 0;
		struct file *file;

		/* Still start < end. */
		error = -ENOMEM;
		if (!vma)
			goto out_unlock;
		/* Here start < vma->vm_end. */
		if (start < vma->vm_start) {
			unmapped_error = -ENOMEM;
@@ -239,7 +239,7 @@ asmlinkage long sys_msync(unsigned long start, size_t len, int flags)
		} else {
			vma = vma->vm_next;
		}
	} while (!done);
	} while (vma && !done);
out_unlock:
	current->flags &= ~PF_SYNCWRITE;
	up_read(&current->mm->mmap_sem);