Commit 676758bdb7bfca8413a85203921746f446e237be

Authored by Andrew Morton
Committed by Linus Torvalds
1 parent 707c21c848

[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: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>

Showing 1 changed file with 7 additions and 7 deletions Side-by-side Diff

... ... @@ -146,7 +146,8 @@
146 146 {
147 147 unsigned long end;
148 148 struct vm_area_struct *vma;
149   - int unmapped_error, error = -EINVAL;
  149 + int unmapped_error = 0;
  150 + int error = -EINVAL;
150 151 int done = 0;
151 152  
152 153 if (flags & ~(MS_ASYNC | MS_INVALIDATE | MS_SYNC))
153 154  
... ... @@ -171,15 +172,14 @@
171 172 if (flags & MS_SYNC)
172 173 current->flags |= PF_SYNCWRITE;
173 174 vma = find_vma(current->mm, start);
174   - unmapped_error = 0;
  175 + if (!vma) {
  176 + error = -ENOMEM;
  177 + goto out_unlock;
  178 + }
175 179 do {
176 180 unsigned long nr_pages_dirtied = 0;
177 181 struct file *file;
178 182  
179   - /* Still start < end. */
180   - error = -ENOMEM;
181   - if (!vma)
182   - goto out_unlock;
183 183 /* Here start < vma->vm_end. */
184 184 if (start < vma->vm_start) {
185 185 unmapped_error = -ENOMEM;
... ... @@ -239,7 +239,7 @@
239 239 } else {
240 240 vma = vma->vm_next;
241 241 }
242   - } while (!done);
  242 + } while (vma && !done);
243 243 out_unlock:
244 244 current->flags &= ~PF_SYNCWRITE;
245 245 up_read(&current->mm->mmap_sem);