mseal: add mseal syscall
[linux-2.6-block.git] / mm / madvise.c
index c8ba3f3eb54d75870bfe864abf62408d654179aa..a77893462b92449c29616aa7553ba172c8b9836f 100644 (file)
@@ -1401,6 +1401,7 @@ int madvise_set_anon_name(struct mm_struct *mm, unsigned long start,
  *  -EIO    - an I/O error occurred while paging in data.
  *  -EBADF  - map exists, but area maps something that isn't a file.
  *  -EAGAIN - a kernel resource was temporarily unavailable.
+ *  -EPERM  - memory is sealed.
  */
 int do_madvise(struct mm_struct *mm, unsigned long start, size_t len_in, int behavior)
 {
@@ -1444,6 +1445,15 @@ int do_madvise(struct mm_struct *mm, unsigned long start, size_t len_in, int beh
        start = untagged_addr_remote(mm, start);
        end = start + len;
 
+       /*
+        * Check if the address range is sealed for do_madvise().
+        * can_modify_mm_madv assumes we have acquired the lock on MM.
+        */
+       if (unlikely(!can_modify_mm_madv(mm, start, end, behavior))) {
+               error = -EPERM;
+               goto out;
+       }
+
        blk_start_plug(&plug);
        switch (behavior) {
        case MADV_POPULATE_READ:
@@ -1456,6 +1466,8 @@ int do_madvise(struct mm_struct *mm, unsigned long start, size_t len_in, int beh
                break;
        }
        blk_finish_plug(&plug);
+
+out:
        if (write)
                mmap_write_unlock(mm);
        else