mirror of https://github.com/OpenIPC/firmware.git
163 lines
5.7 KiB
Diff
163 lines
5.7 KiB
Diff
diff -drupN a/mm/mmap.c b/mm/mmap.c
|
|
--- a/mm/mmap.c 2018-08-06 17:23:04.000000000 +0300
|
|
+++ b/mm/mmap.c 2022-06-12 05:28:14.000000000 +0300
|
|
@@ -970,7 +970,8 @@ again:
|
|
*/
|
|
static inline int is_mergeable_vma(struct vm_area_struct *vma,
|
|
struct file *file, unsigned long vm_flags,
|
|
- struct vm_userfaultfd_ctx vm_userfaultfd_ctx)
|
|
+ struct vm_userfaultfd_ctx vm_userfaultfd_ctx,
|
|
+ const char __user *anon_name)
|
|
{
|
|
/*
|
|
* VM_SOFTDIRTY should not prevent from VMA merging, if we
|
|
@@ -988,6 +989,8 @@ static inline int is_mergeable_vma(struc
|
|
return 0;
|
|
if (!is_mergeable_vm_userfaultfd_ctx(vma, vm_userfaultfd_ctx))
|
|
return 0;
|
|
+ if (vma_get_anon_name(vma) != anon_name)
|
|
+ return 0;
|
|
return 1;
|
|
}
|
|
|
|
@@ -1020,9 +1023,10 @@ static int
|
|
can_vma_merge_before(struct vm_area_struct *vma, unsigned long vm_flags,
|
|
struct anon_vma *anon_vma, struct file *file,
|
|
pgoff_t vm_pgoff,
|
|
- struct vm_userfaultfd_ctx vm_userfaultfd_ctx)
|
|
+ struct vm_userfaultfd_ctx vm_userfaultfd_ctx,
|
|
+ const char __user *anon_name)
|
|
{
|
|
- if (is_mergeable_vma(vma, file, vm_flags, vm_userfaultfd_ctx) &&
|
|
+ if (is_mergeable_vma(vma, file, vm_flags, vm_userfaultfd_ctx, anon_name) &&
|
|
is_mergeable_anon_vma(anon_vma, vma->anon_vma, vma)) {
|
|
if (vma->vm_pgoff == vm_pgoff)
|
|
return 1;
|
|
@@ -1041,9 +1045,10 @@ static int
|
|
can_vma_merge_after(struct vm_area_struct *vma, unsigned long vm_flags,
|
|
struct anon_vma *anon_vma, struct file *file,
|
|
pgoff_t vm_pgoff,
|
|
- struct vm_userfaultfd_ctx vm_userfaultfd_ctx)
|
|
+ struct vm_userfaultfd_ctx vm_userfaultfd_ctx,
|
|
+ const char __user *anon_name)
|
|
{
|
|
- if (is_mergeable_vma(vma, file, vm_flags, vm_userfaultfd_ctx) &&
|
|
+ if (is_mergeable_vma(vma, file, vm_flags, vm_userfaultfd_ctx, anon_name) &&
|
|
is_mergeable_anon_vma(anon_vma, vma->anon_vma, vma)) {
|
|
pgoff_t vm_pglen;
|
|
vm_pglen = vma_pages(vma);
|
|
@@ -1054,9 +1059,9 @@ can_vma_merge_after(struct vm_area_struc
|
|
}
|
|
|
|
/*
|
|
- * Given a mapping request (addr,end,vm_flags,file,pgoff), figure out
|
|
- * whether that can be merged with its predecessor or its successor.
|
|
- * Or both (it neatly fills a hole).
|
|
+ * Given a mapping request (addr,end,vm_flags,file,pgoff,anon_name),
|
|
+ * figure out whether that can be merged with its predecessor or its
|
|
+ * successor. Or both (it neatly fills a hole).
|
|
*
|
|
* In most cases - when called for mmap, brk or mremap - [addr,end) is
|
|
* certain not to be mapped by the time vma_merge is called; but when
|
|
@@ -1098,7 +1103,8 @@ struct vm_area_struct *vma_merge(struct
|
|
unsigned long end, unsigned long vm_flags,
|
|
struct anon_vma *anon_vma, struct file *file,
|
|
pgoff_t pgoff, struct mempolicy *policy,
|
|
- struct vm_userfaultfd_ctx vm_userfaultfd_ctx)
|
|
+ struct vm_userfaultfd_ctx vm_userfaultfd_ctx,
|
|
+ const char __user *anon_name)
|
|
{
|
|
pgoff_t pglen = (end - addr) >> PAGE_SHIFT;
|
|
struct vm_area_struct *area, *next;
|
|
@@ -1131,7 +1137,8 @@ struct vm_area_struct *vma_merge(struct
|
|
mpol_equal(vma_policy(prev), policy) &&
|
|
can_vma_merge_after(prev, vm_flags,
|
|
anon_vma, file, pgoff,
|
|
- vm_userfaultfd_ctx)) {
|
|
+ vm_userfaultfd_ctx,
|
|
+ anon_name)) {
|
|
/*
|
|
* OK, it can. Can we now merge in the successor as well?
|
|
*/
|
|
@@ -1140,7 +1147,8 @@ struct vm_area_struct *vma_merge(struct
|
|
can_vma_merge_before(next, vm_flags,
|
|
anon_vma, file,
|
|
pgoff+pglen,
|
|
- vm_userfaultfd_ctx) &&
|
|
+ vm_userfaultfd_ctx,
|
|
+ anon_name) &&
|
|
is_mergeable_anon_vma(prev->anon_vma,
|
|
next->anon_vma, NULL)) {
|
|
/* cases 1, 6 */
|
|
@@ -1163,7 +1171,8 @@ struct vm_area_struct *vma_merge(struct
|
|
mpol_equal(policy, vma_policy(next)) &&
|
|
can_vma_merge_before(next, vm_flags,
|
|
anon_vma, file, pgoff+pglen,
|
|
- vm_userfaultfd_ctx)) {
|
|
+ vm_userfaultfd_ctx,
|
|
+ anon_name)) {
|
|
if (prev && addr < prev->vm_end) /* case 4 */
|
|
err = __vma_adjust(prev, prev->vm_start,
|
|
addr, prev->vm_pgoff, NULL, next);
|
|
@@ -1673,7 +1682,7 @@ unsigned long mmap_region(struct file *f
|
|
* Can we just expand an old mapping?
|
|
*/
|
|
vma = vma_merge(mm, prev, addr, addr + len, vm_flags,
|
|
- NULL, file, pgoff, NULL, NULL_VM_UFFD_CTX);
|
|
+ NULL, file, pgoff, NULL, NULL_VM_UFFD_CTX, NULL);
|
|
if (vma)
|
|
goto out;
|
|
|
|
@@ -1696,6 +1705,9 @@ unsigned long mmap_region(struct file *f
|
|
vma->vm_pgoff = pgoff;
|
|
INIT_LIST_HEAD(&vma->anon_vma_chain);
|
|
|
|
+ vma->aw_alloc_pid = current->pid;
|
|
+ vma->aw_alloc_comm = current->comm;
|
|
+
|
|
if (file) {
|
|
if (vm_flags & VM_DENYWRITE) {
|
|
error = deny_write_access(file);
|
|
@@ -2345,12 +2357,11 @@ int expand_downwards(struct vm_area_stru
|
|
struct mm_struct *mm = vma->vm_mm;
|
|
struct vm_area_struct *prev;
|
|
unsigned long gap_addr;
|
|
- int error;
|
|
+ int error = 0;
|
|
|
|
address &= PAGE_MASK;
|
|
- error = security_mmap_addr(address);
|
|
- if (error)
|
|
- return error;
|
|
+ if (address < mmap_min_addr)
|
|
+ return -EPERM;
|
|
|
|
/* Enforce stack_guard_gap */
|
|
gap_addr = address - stack_guard_gap;
|
|
@@ -2733,6 +2744,7 @@ int do_munmap(struct mm_struct *mm, unsi
|
|
|
|
return 0;
|
|
}
|
|
+EXPORT_SYMBOL(do_munmap);
|
|
|
|
int vm_munmap(unsigned long start, size_t len)
|
|
{
|
|
@@ -2928,7 +2940,7 @@ static int do_brk(unsigned long addr, un
|
|
|
|
/* Can we just expand an old private anonymous mapping? */
|
|
vma = vma_merge(mm, prev, addr, addr + len, flags,
|
|
- NULL, NULL, pgoff, NULL, NULL_VM_UFFD_CTX);
|
|
+ NULL, NULL, pgoff, NULL, NULL_VM_UFFD_CTX, NULL);
|
|
if (vma)
|
|
goto out;
|
|
|
|
@@ -3089,7 +3101,7 @@ struct vm_area_struct *copy_vma(struct v
|
|
return NULL; /* should never get here */
|
|
new_vma = vma_merge(mm, prev, addr, addr + len, vma->vm_flags,
|
|
vma->anon_vma, vma->vm_file, pgoff, vma_policy(vma),
|
|
- vma->vm_userfaultfd_ctx);
|
|
+ vma->vm_userfaultfd_ctx, vma_get_anon_name(vma));
|
|
if (new_vma) {
|
|
/*
|
|
* Source vma may have been merged into new_vma
|