Skip to content
Snippets Groups Projects
  1. Sep 04, 2024
    • Liam R. Howlett's avatar
      ipc/shm, mm: drop do_vma_munmap() · 63fc66f5
      Liam R. Howlett authored
      The do_vma_munmap() wrapper existed for callers that didn't have a vma
      iterator and needed to check the vma mseal status prior to calling the
      underlying munmap().  All callers now use a vma iterator and since the
      mseal check has been moved to do_vmi_align_munmap() and the vmas are
      aligned, this function can just be called instead.
      
      do_vmi_align_munmap() can no longer be static as ipc/shm is using it and
      it is exported via the mm.h header.
      
      Link: https://lkml.kernel.org/r/20240830040101.822209-19-Liam.Howlett@oracle.com
      
      
      Signed-off-by: default avatarLiam R. Howlett <Liam.Howlett@Oracle.com>
      Reviewed-by: default avatarLorenzo Stoakes <lorenzo.stoakes@oracle.com>
      Cc: Bert Karwatzki <spasswolf@web.de>
      Cc: Jeff Xu <jeffxu@chromium.org>
      Cc: Jiri Olsa <olsajiri@gmail.com>
      Cc: Kees Cook <kees@kernel.org>
      Cc: Lorenzo Stoakes <lstoakes@gmail.com>
      Cc: Mark Brown <broonie@kernel.org>
      Cc: Matthew Wilcox <willy@infradead.org>
      Cc: "Paul E. McKenney" <paulmck@kernel.org>
      Cc: Paul Moore <paul@paul-moore.com>
      Cc: Sidhartha Kumar <sidhartha.kumar@oracle.com>
      Cc: Suren Baghdasaryan <surenb@google.com>
      Cc: Vlastimil Babka <vbabka@suse.cz>
      Signed-off-by: default avatarAndrew Morton <akpm@linux-foundation.org>
      63fc66f5
  2. Apr 09, 2024
  3. Dec 21, 2023
  4. Oct 25, 2023
    • Hugh Dickins's avatar
      mempolicy: alloc_pages_mpol() for NUMA policy without vma · ddc1a5cb
      Hugh Dickins authored
      Shrink shmem's stack usage by eliminating the pseudo-vma from its folio
      allocation.  alloc_pages_mpol(gfp, order, pol, ilx, nid) becomes the
      principal actor for passing mempolicy choice down to __alloc_pages(),
      rather than vma_alloc_folio(gfp, order, vma, addr, hugepage).
      
      vma_alloc_folio() and alloc_pages() remain, but as wrappers around
      alloc_pages_mpol().  alloc_pages_bulk_*() untouched, except to provide the
      additional args to policy_nodemask(), which subsumes policy_node(). 
      Cleanup throughout, cutting out some unhelpful "helpers".
      
      It would all be much simpler without MPOL_INTERLEAVE, but that adds a
      dynamic to the constant mpol: complicated by v3.6 commit 09c231cb
      ("tmpfs: distribute interleave better across nodes"), which added ino bias
      to the interleave, hidden from mm/mempolicy.c until this commit.
      
      Hence "ilx" throughout, the "interleave index".  Originally I thought it
      could be done just with nid, but that's wrong: the nodemask may come from
      the shared policy layer below a shmem vma, or it may come from the task
      layer above a shmem vma; and without the final nodemask then nodeid cannot
      be decided.  And how ilx is applied depends also on page order.
      
      The interleave index is almost always irrelevant unless MPOL_INTERLEAVE:
      with one exception in alloc_pages_mpol(), where the NO_INTERLEAVE_INDEX
      passed down from vma-less alloc_pages() is also used as hint not to use
      THP-style hugepage allocation - to avoid the overhead of a hugepage arg
      (though I don't understand why we never just added a GFP bit for THP - if
      it actually needs a different allocation strategy from other pages of the
      same order).  vma_alloc_folio() still carries its hugepage arg here, but
      it is not used, and should be removed when agreed.
      
      get_vma_policy() no longer allows a NULL vma: over time I believe we've
      eradicated all the places which used to need it e.g.  swapoff and madvise
      used to pass NULL vma to read_swap_cache_async(), but now know the vma.
      
      [hughd@google.com: handle NULL mpol being passed to __read_swap_cache_async()]
        Link: https://lkml.kernel.org/r/ea419956-4751-0102-21f7-9c93cb957892@google.com
      Link: https://lkml.kernel.org/r/74e34633-6060-f5e3-aee-7040d43f2e93@google.com
      Link: https://lkml.kernel.org/r/1738368e-bac0-fd11-ed7f-b87142a939fe@google.com
      
      
      Signed-off-by: default avatarHugh Dickins <hughd@google.com>
      Cc: Andi Kleen <ak@linux.intel.com>
      Cc: Christoph Lameter <cl@linux.com>
      Cc: David Hildenbrand <david@redhat.com>
      Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
      Cc: Huang Ying <ying.huang@intel.com>
      Cc: Kefeng Wang <wangkefeng.wang@huawei.com>
      Cc: Matthew Wilcox (Oracle) <willy@infradead.org>
      Cc: Mel Gorman <mgorman@techsingularity.net>
      Cc: Michal Hocko <mhocko@suse.com>
      Cc: Mike Kravetz <mike.kravetz@oracle.com>
      Cc: Nhat Pham <nphamcs@gmail.com>
      Cc: Sidhartha Kumar <sidhartha.kumar@oracle.com>
      Cc: Suren Baghdasaryan <surenb@google.com>
      Cc: Tejun heo <tj@kernel.org>
      Cc: Vishal Moola (Oracle) <vishal.moola@gmail.com>
      Cc: Yang Shi <shy828301@gmail.com>
      Cc: Yosry Ahmed <yosryahmed@google.com>
      Cc: Domenico Cerasuolo <mimmocerasuolo@gmail.com>
      Cc: Johannes Weiner <hannes@cmpxchg.org>
      Signed-off-by: default avatarAndrew Morton <akpm@linux-foundation.org>
      ddc1a5cb
  5. Jul 11, 2023
  6. Feb 10, 2023
  7. Nov 23, 2022
    • Mike Kravetz's avatar
      ipc/shm: call underlying open/close vm_ops · b6305049
      Mike Kravetz authored
      Shared memory segments can be created that are backed by hugetlb pages. 
      When this happens, the vmas associated with any mappings (shmat) are
      marked VM_HUGETLB, yet the vm_ops for such mappings are provided by
      ipc/shm (shm_vm_ops).  There is a mechanism to call the underlying hugetlb
      vm_ops, and this is done for most operations.  However, it is not done for
      open and close.
      
      This was not an issue until the introduction of the hugetlb vma_lock. 
      This lock structure is pointed to by vm_private_data and the open/close
      vm_ops help maintain this structure.  The special hugetlb routine called
      at fork took care of structure updates at fork time.  However,
      vma_splitting is not properly handled for ipc shared memory mappings
      backed by hugetlb pages.  This can result in a "kernel NULL pointer
      dereference" BUG or use after free as two vmas point to the same lock
      structure.
      
      Update the shm open and close routines to always call the underlying open
      and close routines.
      
      Link: https://lkml.kernel.org/r/20221114210018.49346-1-mike.kravetz@oracle.com
      
      
      Fixes: 8d9bfb26 ("hugetlb: add vma based lock for pmd sharing")
      Signed-off-by: default avatarMike Kravetz <mike.kravetz@oracle.com>
      Reported-by: default avatarDoug Nelson <doug.nelson@intel.com>
      Reported-by: default avatar <syzbot+83b4134621b7c326d950@syzkaller.appspotmail.com>
      Cc: Alexander Mikhalitsyn <alexander.mikhalitsyn@virtuozzo.com>
      Cc: "Eric W . Biederman" <ebiederm@xmission.com>
      Cc: Manfred Spraul <manfred@colorfullife.com>
      Cc: Matthew Wilcox <willy@infradead.org>
      Cc: Miaohe Lin <linmiaohe@huawei.com>
      Cc: Michal Hocko <mhocko@suse.com>
      Signed-off-by: default avatarAndrew Morton <akpm@linux-foundation.org>
      b6305049
  8. Sep 27, 2022
  9. Nov 20, 2021
    • Alexander Mikhalitsyn's avatar
      shm: extend forced shm destroy to support objects from several IPC nses · 85b6d246
      Alexander Mikhalitsyn authored
      Currently, the exit_shm() function not designed to work properly when
      task->sysvshm.shm_clist holds shm objects from different IPC namespaces.
      
      This is a real pain when sysctl kernel.shm_rmid_forced = 1, because it
      leads to use-after-free (reproducer exists).
      
      This is an attempt to fix the problem by extending exit_shm mechanism to
      handle shm's destroy from several IPC ns'es.
      
      To achieve that we do several things:
      
      1. add a namespace (non-refcounted) pointer to the struct shmid_kernel
      
      2. during new shm object creation (newseg()/shmget syscall) we
         initialize this pointer by current task IPC ns
      
      3. exit_shm() fully reworked such that it traverses over all shp's in
         task->sysvshm.shm_clist and gets IPC namespace not from current task
         as it was before but from shp's object itself, then call
         shm_destroy(shp, ns).
      
      Note: We need to be really careful here, because as it was said before
      (1), our pointer to IPC ns non-refcnt'ed.  To be on the safe side we
      using special helper get_ipc_ns_not_zero() which allows to get IPC ns
      refcounter only if IPC ns not in the "state of destruction".
      
      Q/A
      
      Q: Why can we access shp->ns memory using non-refcounted pointer?
      A: Because shp object lifetime is always shorther than IPC namespace
         lifetime, so, if we get shp object from the task->sysvshm.shm_clist
         while holding task_lock(task) nobody can steal our namespace.
      
      Q: Does this patch change semantics of unshare/setns/clone syscalls?
      A: No. It's just fixes non-covered case when process may leave IPC
         namespace without getting task->sysvshm.shm_clist list cleaned up.
      
      Link: https://lkml.kernel.org/r/67bb03e5-f79c-1815-e2bf-949c67047418@colorfullife.com
      Link: https://lkml.kernel.org/r/20211109151501.4921-1-manfred@colorfullife.com
      
      
      Fixes: ab602f79 ("shm: make exit_shm work proportional to task activity")
      Co-developed-by: default avatarManfred Spraul <manfred@colorfullife.com>
      Signed-off-by: default avatarManfred Spraul <manfred@colorfullife.com>
      Signed-off-by: default avatarAlexander Mikhalitsyn <alexander.mikhalitsyn@virtuozzo.com>
      Cc: "Eric W. Biederman" <ebiederm@xmission.com>
      Cc: Davidlohr Bueso <dave@stgolabs.net>
      Cc: Greg KH <gregkh@linuxfoundation.org>
      Cc: Andrei Vagin <avagin@gmail.com>
      Cc: Pavel Tikhomirov <ptikhomirov@virtuozzo.com>
      Cc: Vasily Averin <vvs@virtuozzo.com>
      Cc: <stable@vger.kernel.org>
      Signed-off-by: default avatarAndrew Morton <akpm@linux-foundation.org>
      Signed-off-by: default avatarLinus Torvalds <torvalds@linux-foundation.org>
      85b6d246
  10. Nov 09, 2021
  11. Sep 03, 2021
    • Vasily Averin's avatar
      memcg: enable accounting of ipc resources · 18319498
      Vasily Averin authored
      When user creates IPC objects it forces kernel to allocate memory for
      these long-living objects.
      
      It makes sense to account them to restrict the host's memory consumption
      from inside the memcg-limited container.
      
      This patch enables accounting for IPC shared memory segments, messages
      semaphores and semaphore's undo lists.
      
      Link: https://lkml.kernel.org/r/d6507b06-4df6-78f8-6c54-3ae86e3b5339@virtuozzo.com
      
      
      Signed-off-by: default avatarVasily Averin <vvs@virtuozzo.com>
      Reviewed-by: default avatarShakeel Butt <shakeelb@google.com>
      Cc: Alexander Viro <viro@zeniv.linux.org.uk>
      Cc: Alexey Dobriyan <adobriyan@gmail.com>
      Cc: Andrei Vagin <avagin@gmail.com>
      Cc: Borislav Petkov <bp@alien8.de>
      Cc: Borislav Petkov <bp@suse.de>
      Cc: Christian Brauner <christian.brauner@ubuntu.com>
      Cc: Dmitry Safonov <0x7f454c46@gmail.com>
      Cc: "Eric W. Biederman" <ebiederm@xmission.com>
      Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
      Cc: "H. Peter Anvin" <hpa@zytor.com>
      Cc: Ingo Molnar <mingo@redhat.com>
      Cc: "J. Bruce Fields" <bfields@fieldses.org>
      Cc: Jeff Layton <jlayton@kernel.org>
      Cc: Jens Axboe <axboe@kernel.dk>
      Cc: Jiri Slaby <jirislaby@kernel.org>
      Cc: Johannes Weiner <hannes@cmpxchg.org>
      Cc: Kirill Tkhai <ktkhai@virtuozzo.com>
      Cc: Michal Hocko <mhocko@kernel.org>
      Cc: Oleg Nesterov <oleg@redhat.com>
      Cc: Roman Gushchin <guro@fb.com>
      Cc: Serge Hallyn <serge@hallyn.com>
      Cc: Tejun Heo <tj@kernel.org>
      Cc: Thomas Gleixner <tglx@linutronix.de>
      Cc: Vladimir Davydov <vdavydov.dev@gmail.com>
      Cc: Yutian Yang <nglaive@gmail.com>
      Cc: Zefan Li <lizefan.x@bytedance.com>
      Signed-off-by: default avatarAndrew Morton <akpm@linux-foundation.org>
      Signed-off-by: default avatarLinus Torvalds <torvalds@linux-foundation.org>
      18319498
  12. Jul 01, 2021
  13. Apr 30, 2021
  14. Dec 15, 2020
    • Dmitry Safonov's avatar
      vm_ops: rename .split() callback to .may_split() · dd3b614f
      Dmitry Safonov authored
      Rename the callback to reflect that it's not called *on* or *after* split,
      but rather some time before the splitting to check if it's possible.
      
      Link: https://lkml.kernel.org/r/20201013013416.390574-5-dima@arista.com
      
      
      Signed-off-by: default avatarDmitry Safonov <dima@arista.com>
      Cc: Alexander Viro <viro@zeniv.linux.org.uk>
      Cc: Andy Lutomirski <luto@kernel.org>
      Cc: Brian Geffon <bgeffon@google.com>
      Cc: Catalin Marinas <catalin.marinas@arm.com>
      Cc: Dan Carpenter <dan.carpenter@oracle.com>
      Cc: Dan Williams <dan.j.williams@intel.com>
      Cc: Dave Jiang <dave.jiang@intel.com>
      Cc: Hugh Dickins <hughd@google.com>
      Cc: Ingo Molnar <mingo@redhat.com>
      Cc: Jason Gunthorpe <jgg@ziepe.ca>
      Cc: John Hubbard <jhubbard@nvidia.com>
      Cc: "Kirill A. Shutemov" <kirill.shutemov@linux.intel.com>
      Cc: Mike Kravetz <mike.kravetz@oracle.com>
      Cc: Minchan Kim <minchan@kernel.org>
      Cc: Ralph Campbell <rcampbell@nvidia.com>
      Cc: Russell King <linux@armlinux.org.uk>
      Cc: Thomas Bogendoerfer <tsbogend@alpha.franken.de>
      Cc: Thomas Gleixner <tglx@linutronix.de>
      Cc: Vishal Verma <vishal.l.verma@intel.com>
      Cc: Vlastimil Babka <vbabka@suse.cz>
      Cc: Will Deacon <will@kernel.org>
      Signed-off-by: default avatarAndrew Morton <akpm@linux-foundation.org>
      Signed-off-by: default avatarLinus Torvalds <torvalds@linux-foundation.org>
      dd3b614f
  15. Aug 23, 2020
  16. Aug 12, 2020
  17. Aug 07, 2020
  18. Jun 09, 2020
  19. Apr 07, 2020
  20. Jan 25, 2019
    • Arnd Bergmann's avatar
      ipc: rename old-style shmctl/semctl/msgctl syscalls · 275f2214
      Arnd Bergmann authored
      
      The behavior of these system calls is slightly different between
      architectures, as determined by the CONFIG_ARCH_WANT_IPC_PARSE_VERSION
      symbol. Most architectures that implement the split IPC syscalls don't set
      that symbol and only get the modern version, but alpha, arm, microblaze,
      mips-n32, mips-n64 and xtensa expect the caller to pass the IPC_64 flag.
      
      For the architectures that so far only implement sys_ipc(), i.e. m68k,
      mips-o32, powerpc, s390, sh, sparc, and x86-32, we want the new behavior
      when adding the split syscalls, so we need to distinguish between the
      two groups of architectures.
      
      The method I picked for this distinction is to have a separate system call
      entry point: sys_old_*ctl() now uses ipc_parse_version, while sys_*ctl()
      does not. The system call tables of the five architectures are changed
      accordingly.
      
      As an additional benefit, we no longer need the configuration specific
      definition for ipc_parse_version(), it always does the same thing now,
      but simply won't get called on architectures with the modern interface.
      
      A small downside is that on architectures that do set
      ARCH_WANT_IPC_PARSE_VERSION, we now have an extra set of entry points
      that are never called. They only add a few bytes of bloat, so it seems
      better to keep them compared to adding yet another Kconfig symbol.
      I considered adding new syscall numbers for the IPC_64 variants for
      consistency, but decided against that for now.
      
      Signed-off-by: default avatarArnd Bergmann <arnd@arndb.de>
      275f2214
  21. Oct 05, 2018
  22. Sep 04, 2018
  23. Aug 27, 2018
    • Arnd Bergmann's avatar
      y2038: globally rename compat_time to old_time32 · 9afc5eee
      Arnd Bergmann authored
      
      Christoph Hellwig suggested a slightly different path for handling
      backwards compatibility with the 32-bit time_t based system calls:
      
      Rather than simply reusing the compat_sys_* entry points on 32-bit
      architectures unchanged, we get rid of those entry points and the
      compat_time types by renaming them to something that makes more sense
      on 32-bit architectures (which don't have a compat mode otherwise),
      and then share the entry points under the new name with the 64-bit
      architectures that use them for implementing the compatibility.
      
      The following types and interfaces are renamed here, and moved
      from linux/compat_time.h to linux/time32.h:
      
      old				new
      ---				---
      compat_time_t			old_time32_t
      struct compat_timeval		struct old_timeval32
      struct compat_timespec		struct old_timespec32
      struct compat_itimerspec	struct old_itimerspec32
      ns_to_compat_timeval()		ns_to_old_timeval32()
      get_compat_itimerspec64()	get_old_itimerspec32()
      put_compat_itimerspec64()	put_old_itimerspec32()
      compat_get_timespec64()		get_old_timespec32()
      compat_put_timespec64()		put_old_timespec32()
      
      As we already have aliases in place, this patch addresses only the
      instances that are relevant to the system call interface in particular,
      not those that occur in device drivers and other modules. Those
      will get handled separately, while providing the 64-bit version
      of the respective interfaces.
      
      I'm not renaming the timex, rusage and itimerval structures, as we are
      still debating what the new interface will look like, and whether we
      will need a replacement at all.
      
      This also doesn't change the names of the syscall entry points, which can
      be done more easily when we actually switch over the 32-bit architectures
      to use them, at that point we need to change COMPAT_SYSCALL_DEFINEx to
      SYSCALL_DEFINEx with a new name, e.g. with a _time32 suffix.
      
      Suggested-by: default avatarChristoph Hellwig <hch@infradead.org>
      Link: https://lore.kernel.org/lkml/20180705222110.GA5698@infradead.org/
      
      
      Signed-off-by: default avatarArnd Bergmann <arnd@arndb.de>
      9afc5eee
  24. Aug 22, 2018
  25. Aug 02, 2018
    • Jane Chu's avatar
      ipc/shm.c add ->pagesize function to shm_vm_ops · eec3636a
      Jane Chu authored
      Commit 05ea8860 ("mm, hugetlbfs: introduce ->pagesize() to
      vm_operations_struct") adds a new ->pagesize() function to
      hugetlb_vm_ops, intended to cover all hugetlbfs backed files.
      
      With System V shared memory model, if "huge page" is specified, the
      "shared memory" is backed by hugetlbfs files, but the mappings initiated
      via shmget/shmat have their original vm_ops overwritten with shm_vm_ops,
      so we need to add a ->pagesize function to shm_vm_ops.  Otherwise,
      vma_kernel_pagesize() returns PAGE_SIZE given a hugetlbfs backed vma,
      result in below BUG:
      
        fs/hugetlbfs/inode.c
              443             if (unlikely(page_mapped(page))) {
              444                     BUG_ON(truncate_op);
      
      resulting in
      
        hugetlbfs: oracle (4592): Using mlock ulimits for SHM_HUGETLB is deprecated
        ------------[ cut here ]------------
        kernel BUG at fs/hugetlbfs/inode.c:444!
        Modules linked in: nfsv3 rpcsec_gss_krb5 nfsv4 ...
        CPU: 35 PID: 5583 Comm: oracle_5583_sbt Not tainted 4.14.35-1829.el7uek.x86_64 #2
        RIP: 0010:remove_inode_hugepages+0x3db/0x3e2
        ....
        Call Trace:
          hugetlbfs_evict_inode+0x1e/0x3e
          evict+0xdb/0x1af
          iput+0x1a2/0x1f7
          dentry_unlink_inode+0xc6/0xf0
          __dentry_kill+0xd8/0x18d
          dput+0x1b5/0x1ed
          __fput+0x18b/0x216
          ____fput+0xe/0x10
          task_work_run+0x90/0xa7
          exit_to_usermode_loop+0xdd/0x116
          do_syscall_64+0x187/0x1ae
          entry_SYSCALL_64_after_hwframe+0x150/0x0
      
      [jane.chu@oracle.com: relocate comment]
        Link: http://lkml.kernel.org/r/20180731044831.26036-1-jane.chu@oracle.com
      Link: http://lkml.kernel.org/r/20180727211727.5020-1-jane.chu@oracle.com
      
      
      Fixes: 05ea8860 ("mm, hugetlbfs: introduce ->pagesize() to vm_operations_struct")
      Signed-off-by: default avatarJane Chu <jane.chu@oracle.com>
      Suggested-by: default avatarMike Kravetz <mike.kravetz@oracle.com>
      Reviewed-by: default avatarMike Kravetz <mike.kravetz@oracle.com>
      Acked-by: default avatarDavidlohr Bueso <dave@stgolabs.net>
      Acked-by: default avatarMichal Hocko <mhocko@suse.com>
      Cc: Dan Williams <dan.j.williams@intel.com>
      Cc: Jan Kara <jack@suse.cz>
      Cc: Jérôme Glisse <jglisse@redhat.com>
      Cc: Manfred Spraul <manfred@colorfullife.com>
      Cc: <stable@vger.kernel.org>
      Signed-off-by: default avatarAndrew Morton <akpm@linux-foundation.org>
      Signed-off-by: default avatarLinus Torvalds <torvalds@linux-foundation.org>
      eec3636a
  26. Jul 12, 2018
  27. Jun 22, 2018
    • NeilBrown's avatar
      rhashtable: split rhashtable.h · 0eb71a9d
      NeilBrown authored
      
      Due to the use of rhashtables in net namespaces,
      rhashtable.h is included in lots of the kernel,
      so a small changes can required a large recompilation.
      This makes development painful.
      
      This patch splits out rhashtable-types.h which just includes
      the major type declarations, and does not include (non-trivial)
      inline code.  rhashtable.h is no longer included by anything
      in the include/ directory.
      Common include files only include rhashtable-types.h so a large
      recompilation is only triggered when that changes.
      
      Acked-by: default avatarHerbert Xu <herbert@gondor.apana.org.au>
      Signed-off-by: default avatarNeilBrown <neilb@suse.com>
      Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
      0eb71a9d
  28. Jun 14, 2018
  29. May 26, 2018
  30. Apr 20, 2018
    • Arnd Bergmann's avatar
      y2038: ipc: Report long times to user space · c2ab975c
      Arnd Bergmann authored
      
      The shmid64_ds/semid64_ds/msqid64_ds data structures have been extended
      to contain extra fields for storing the upper bits of the time stamps,
      this patch does the other half of the job and and fills the new fields on
      32-bit architectures as well as 32-bit tasks running on a 64-bit kernel
      in compat mode.
      
      There should be no change for native 64-bit tasks.
      
      Signed-off-by: default avatarArnd Bergmann <arnd@arndb.de>
      c2ab975c
  31. Apr 14, 2018
    • Eric Biggers's avatar
      ipc/shm: fix use-after-free of shm file via remap_file_pages() · 3f05317d
      Eric Biggers authored
      syzbot reported a use-after-free of shm_file_data(file)->file->f_op in
      shm_get_unmapped_area(), called via sys_remap_file_pages().
      
      Unfortunately it couldn't generate a reproducer, but I found a bug which
      I think caused it.  When remap_file_pages() is passed a full System V
      shared memory segment, the memory is first unmapped, then a new map is
      created using the ->vm_file.  Between these steps, the shm ID can be
      removed and reused for a new shm segment.  But, shm_mmap() only checks
      whether the ID is currently valid before calling the underlying file's
      ->mmap(); it doesn't check whether it was reused.  Thus it can use the
      wrong underlying file, one that was already freed.
      
      Fix this by making the "outer" shm file (the one that gets put in
      ->vm_file) hold a reference to the real shm file, and by making
      __shm_open() require that the file associated with the shm ID matches
      the one associated with the "outer" file.
      
      Taking the reference to the real shm file is needed to fully solve the
      problem, since otherwise sfd->file could point to a freed file, which
      then could be reallocated for the reused shm ID, causing the wrong shm
      segment to be mapped (and without the required permission checks).
      
      Commit 1ac0b6de ("ipc/shm: handle removed segments gracefully in
      shm_mmap()") almost fixed this bug, but it didn't go far enough because
      it didn't consider the case where the shm ID is reused.
      
      The following program usually reproduces this bug:
      
      	#include <stdlib.h>
      	#include <sys/shm.h>
      	#include <sys/syscall.h>
      	#include <unistd.h>
      
      	int main()
      	{
      		int is_parent = (fork() != 0);
      		srand(getpid());
      		for (;;) {
      			int id = shmget(0xF00F, 4096, IPC_CREAT|0700);
      			if (is_parent) {
      				void *addr = shmat(id, NULL, 0);
      				usleep(rand() % 50);
      				while (!syscall(__NR_remap_file_pages, addr, 4096, 0, 0, 0));
      			} else {
      				usleep(rand() % 50);
      				shmctl(id, IPC_RMID, NULL);
      			}
      		}
      	}
      
      It causes the following NULL pointer dereference due to a 'struct file'
      being used while it's being freed.  (I couldn't actually get a KASAN
      use-after-free splat like in the syzbot report.  But I think it's
      possible with this bug; it would just take a more extraordinary race...)
      
      	BUG: unable to handle kernel NULL pointer dereference at 0000000000000058
      	PGD 0 P4D 0
      	Oops: 0000 [#1] SMP NOPTI
      	CPU: 9 PID: 258 Comm: syz_ipc Not tainted 4.16.0-05140-gf8cf2f16a7c95 #189
      	Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 1.11.0-20171110_100015-anatol 04/01/2014
      	RIP: 0010:d_inode include/linux/dcache.h:519 [inline]
      	RIP: 0010:touch_atime+0x25/0xd0 fs/inode.c:1724
      	[...]
      	Call Trace:
      	 file_accessed include/linux/fs.h:2063 [inline]
      	 shmem_mmap+0x25/0x40 mm/shmem.c:2149
      	 call_mmap include/linux/fs.h:1789 [inline]
      	 shm_mmap+0x34/0x80 ipc/shm.c:465
      	 call_mmap include/linux/fs.h:1789 [inline]
      	 mmap_region+0x309/0x5b0 mm/mmap.c:1712
      	 do_mmap+0x294/0x4a0 mm/mmap.c:1483
      	 do_mmap_pgoff include/linux/mm.h:2235 [inline]
      	 SYSC_remap_file_pages mm/mmap.c:2853 [inline]
      	 SyS_remap_file_pages+0x232/0x310 mm/mmap.c:2769
      	 do_syscall_64+0x64/0x1a0 arch/x86/entry/common.c:287
      	 entry_SYSCALL_64_after_hwframe+0x42/0xb7
      
      [ebiggers@google.com: add comment]
        Link: http://lkml.kernel.org/r/20180410192850.235835-1-ebiggers3@gmail.com
      Link: http://lkml.kernel.org/r/20180409043039.28915-1-ebiggers3@gmail.com
      
      
      Reported-by: default avatar <syzbot+d11f321e7f1923157eac80aa990b446596f46439@syzkaller.appspotmail.com>
      Fixes: c8d78c18 ("mm: replace remap_file_pages() syscall with emulation")
      Signed-off-by: default avatarEric Biggers <ebiggers@google.com>
      Acked-by: default avatarKirill A. Shutemov <kirill.shutemov@linux.intel.com>
      Acked-by: default avatarDavidlohr Bueso <dbueso@suse.de>
      Cc: Manfred Spraul <manfred@colorfullife.com>
      Cc: "Eric W . Biederman" <ebiederm@xmission.com>
      Cc: <stable@vger.kernel.org>
      Signed-off-by: default avatarAndrew Morton <akpm@linux-foundation.org>
      Signed-off-by: default avatarLinus Torvalds <torvalds@linux-foundation.org>
      3f05317d
Loading