]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
5.4-stable patches
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Tue, 6 Dec 2022 11:43:23 +0000 (12:43 +0100)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Tue, 6 Dec 2022 11:43:23 +0000 (12:43 +0100)
added patches:
v4l2-don-t-fall-back-to-follow_pfn-if-pin_user_pages_fast-fails.patch

queue-5.4/series
queue-5.4/v4l2-don-t-fall-back-to-follow_pfn-if-pin_user_pages_fast-fails.patch [new file with mode: 0644]

index 720e73398385fa33dee43a88e305deb458fade34..7d31e7b3f1eb83658680a2712b11eec705a32248 100644 (file)
@@ -153,3 +153,4 @@ mmc-sdhci-use-field_get-for-preset-value-bit-masks.patch
 mmc-sdhci-fix-voltage-switch-delay.patch
 proc-avoid-integer-type-confusion-in-get_proc_long.patch
 proc-proc_skip_spaces-shouldn-t-think-it-is-working-on-c-strings.patch
+v4l2-don-t-fall-back-to-follow_pfn-if-pin_user_pages_fast-fails.patch
diff --git a/queue-5.4/v4l2-don-t-fall-back-to-follow_pfn-if-pin_user_pages_fast-fails.patch b/queue-5.4/v4l2-don-t-fall-back-to-follow_pfn-if-pin_user_pages_fast-fails.patch
new file mode 100644 (file)
index 0000000..6ae8e7d
--- /dev/null
@@ -0,0 +1,114 @@
+From 6647e76ab623b2b3fb2efe03a86e9c9046c52c33 Mon Sep 17 00:00:00 2001
+From: Linus Torvalds <torvalds@linux-foundation.org>
+Date: Wed, 30 Nov 2022 16:10:52 -0800
+Subject: v4l2: don't fall back to follow_pfn() if pin_user_pages_fast() fails
+
+From: Linus Torvalds <torvalds@linux-foundation.org>
+
+commit 6647e76ab623b2b3fb2efe03a86e9c9046c52c33 upstream.
+
+The V4L2_MEMORY_USERPTR interface is long deprecated and shouldn't be
+used (and is discouraged for any modern v4l drivers).  And Seth Jenkins
+points out that the fallback to VM_PFNMAP/VM_IO is fundamentally racy
+and dangerous.
+
+Note that it's not even a case that should trigger, since any normal
+user pointer logic ends up just using the pin_user_pages_fast() call
+that does the proper page reference counting.  That's not the problem
+case, only if you try to use special device mappings do you have any
+issues.
+
+Normally I'd just remove this during the merge window, but since Seth
+pointed out the problem cases, we really want to know as soon as
+possible if there are actually any users of this odd special case of a
+legacy interface.  Neither Hans nor Mauro seem to think that such
+mis-uses of the old legacy interface should exist.  As Mauro says:
+
+ "See, V4L2 has actually 4 streaming APIs:
+        - Kernel-allocated mmap (usually referred simply as just mmap);
+        - USERPTR mmap;
+        - read();
+        - dmabuf;
+
+  The USERPTR is one of the oldest way to use it, coming from V4L
+  version 1 times, and by far the least used one"
+
+And Hans chimed in on the USERPTR interface:
+
+ "To be honest, I wouldn't mind if it goes away completely, but that's a
+  bit of a pipe dream right now"
+
+but while removing this legacy interface entirely may be a pipe dream we
+can at least try to remove the unlikely (and actively broken) case of
+using special device mappings for USERPTR accesses.
+
+This replaces it with a WARN_ONCE() that we can remove once we've
+hopefully confirmed that no actual users exist.
+
+NOTE! Longer term, this means that a 'struct frame_vector' only ever
+contains proper page pointers, and all the games we have with converting
+them to pages can go away (grep for 'frame_vector_to_pages()' and the
+uses of 'vec->is_pfns').  But this is just the first step, to verify
+that this code really is all dead, and do so as quickly as possible.
+
+Reported-by: Seth Jenkins <sethjenkins@google.com>
+Acked-by: Hans Verkuil <hverkuil@xs4all.nl>
+Acked-by: Mauro Carvalho Chehab <mchehab@kernel.org>
+Cc: David Hildenbrand <david@redhat.com>
+Cc: Jan Kara <jack@suse.cz>
+Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
+Signed-off-by: Sergey Senozhatsky <senozhatsky@chromium.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ mm/frame_vector.c |   31 ++++++-------------------------
+ 1 file changed, 6 insertions(+), 25 deletions(-)
+
+--- a/mm/frame_vector.c
++++ b/mm/frame_vector.c
+@@ -37,7 +37,6 @@ int get_vaddr_frames(unsigned long start
+       struct mm_struct *mm = current->mm;
+       struct vm_area_struct *vma;
+       int ret = 0;
+-      int err;
+       int locked;
+       if (nr_frames == 0)
+@@ -74,32 +73,14 @@ int get_vaddr_frames(unsigned long start
+               vec->is_pfns = false;
+               ret = get_user_pages_locked(start, nr_frames,
+                       gup_flags, (struct page **)(vec->ptrs), &locked);
+-              goto out;
++              if (likely(ret > 0))
++                      goto out;
+       }
+-      vec->got_ref = false;
+-      vec->is_pfns = true;
+-      do {
+-              unsigned long *nums = frame_vector_pfns(vec);
+-
+-              while (ret < nr_frames && start + PAGE_SIZE <= vma->vm_end) {
+-                      err = follow_pfn(vma, start, &nums[ret]);
+-                      if (err) {
+-                              if (ret == 0)
+-                                      ret = err;
+-                              goto out;
+-                      }
+-                      start += PAGE_SIZE;
+-                      ret++;
+-              }
+-              /*
+-               * We stop if we have enough pages or if VMA doesn't completely
+-               * cover the tail page.
+-               */
+-              if (ret >= nr_frames || start < vma->vm_end)
+-                      break;
+-              vma = find_vma_intersection(mm, start, start + 1);
+-      } while (vma && vma->vm_flags & (VM_IO | VM_PFNMAP));
++      /* This used to (racily) return non-refcounted pfns. Let people know */
++      WARN_ONCE(1, "get_vaddr_frames() cannot follow VM_IO mapping");
++      vec->nr_frames = 0;
++
+ out:
+       if (locked)
+               up_read(&mm->mmap_sem);