mm, mmap: fix vma_merge() case 7 with vma_ops->close
[sfrench/cifs-2.6.git] / mm / mmap.c
index d89770eaab6b6111117783ca7ff532871c1d71a5..3281287771c9c6100ebefde692bca06e247ae0f8 100644 (file)
--- a/mm/mmap.c
+++ b/mm/mmap.c
@@ -954,13 +954,21 @@ static struct vm_area_struct
        } else if (merge_prev) {                        /* case 2 */
                if (curr) {
                        vma_start_write(curr);
-                       err = dup_anon_vma(prev, curr, &anon_dup);
                        if (end == curr->vm_end) {      /* case 7 */
+                               /*
+                                * can_vma_merge_after() assumed we would not be
+                                * removing prev vma, so it skipped the check
+                                * for vm_ops->close, but we are removing curr
+                                */
+                               if (curr->vm_ops && curr->vm_ops->close)
+                                       err = -EINVAL;
                                remove = curr;
                        } else {                        /* case 5 */
                                adjust = curr;
                                adj_start = (end - curr->vm_start);
                        }
+                       if (!err)
+                               err = dup_anon_vma(prev, curr, &anon_dup);
                }
        } else { /* merge_next */
                vma_start_write(next);