LCOV - code coverage report
Current view: top level - mm - memfd.c (source / functions) Hit Total Coverage
Test: landlock.info Lines: 30 139 21.6 %
Date: 2021-04-22 12:43:58 Functions: 2 8 25.0 %

          Line data    Source code
       1             : /*
       2             :  * memfd_create system call and file sealing support
       3             :  *
       4             :  * Code was originally included in shmem.c, and broken out to facilitate
       5             :  * use by hugetlbfs as well as tmpfs.
       6             :  *
       7             :  * This file is released under the GPL.
       8             :  */
       9             : 
      10             : #include <linux/fs.h>
      11             : #include <linux/vfs.h>
      12             : #include <linux/pagemap.h>
      13             : #include <linux/file.h>
      14             : #include <linux/mm.h>
      15             : #include <linux/sched/signal.h>
      16             : #include <linux/khugepaged.h>
      17             : #include <linux/syscalls.h>
      18             : #include <linux/hugetlb.h>
      19             : #include <linux/shmem_fs.h>
      20             : #include <linux/memfd.h>
      21             : #include <uapi/linux/memfd.h>
      22             : 
      23             : /*
      24             :  * We need a tag: a new tag would expand every xa_node by 8 bytes,
      25             :  * so reuse a tag which we firmly believe is never set or cleared on tmpfs
      26             :  * or hugetlbfs because they are memory only filesystems.
      27             :  */
      28             : #define MEMFD_TAG_PINNED        PAGECACHE_TAG_TOWRITE
      29             : #define LAST_SCAN               4       /* about 150ms max */
      30             : 
      31           0 : static void memfd_tag_pins(struct xa_state *xas)
      32             : {
      33           0 :         struct page *page;
      34           0 :         unsigned int tagged = 0;
      35             : 
      36           0 :         lru_add_drain();
      37             : 
      38           0 :         xas_lock_irq(xas);
      39           0 :         xas_for_each(xas, page, ULONG_MAX) {
      40           0 :                 if (xa_is_value(page))
      41           0 :                         continue;
      42           0 :                 page = find_subpage(page, xas->xa_index);
      43           0 :                 if (page_count(page) - page_mapcount(page) > 1)
      44           0 :                         xas_set_mark(xas, MEMFD_TAG_PINNED);
      45             : 
      46           0 :                 if (++tagged % XA_CHECK_SCHED)
      47           0 :                         continue;
      48             : 
      49           0 :                 xas_pause(xas);
      50           0 :                 xas_unlock_irq(xas);
      51           0 :                 cond_resched();
      52           0 :                 xas_lock_irq(xas);
      53             :         }
      54           0 :         xas_unlock_irq(xas);
      55           0 : }
      56             : 
      57             : /*
      58             :  * Setting SEAL_WRITE requires us to verify there's no pending writer. However,
      59             :  * via get_user_pages(), drivers might have some pending I/O without any active
      60             :  * user-space mappings (eg., direct-IO, AIO). Therefore, we look at all pages
      61             :  * and see whether it has an elevated ref-count. If so, we tag them and wait for
      62             :  * them to be dropped.
      63             :  * The caller must guarantee that no new user will acquire writable references
      64             :  * to those pages to avoid races.
      65             :  */
      66           0 : static int memfd_wait_for_pins(struct address_space *mapping)
      67             : {
      68           0 :         XA_STATE(xas, &mapping->i_pages, 0);
      69           0 :         struct page *page;
      70           0 :         int error, scan;
      71             : 
      72           0 :         memfd_tag_pins(&xas);
      73             : 
      74           0 :         error = 0;
      75           0 :         for (scan = 0; scan <= LAST_SCAN; scan++) {
      76           0 :                 unsigned int tagged = 0;
      77             : 
      78           0 :                 if (!xas_marked(&xas, MEMFD_TAG_PINNED))
      79             :                         break;
      80             : 
      81           0 :                 if (!scan)
      82           0 :                         lru_add_drain_all();
      83           0 :                 else if (schedule_timeout_killable((HZ << scan) / 200))
      84           0 :                         scan = LAST_SCAN;
      85             : 
      86           0 :                 xas_set(&xas, 0);
      87           0 :                 xas_lock_irq(&xas);
      88           0 :                 xas_for_each_marked(&xas, page, ULONG_MAX, MEMFD_TAG_PINNED) {
      89           0 :                         bool clear = true;
      90           0 :                         if (xa_is_value(page))
      91           0 :                                 continue;
      92           0 :                         page = find_subpage(page, xas.xa_index);
      93           0 :                         if (page_count(page) - page_mapcount(page) != 1) {
      94             :                                 /*
      95             :                                  * On the last scan, we clean up all those tags
      96             :                                  * we inserted; but make a note that we still
      97             :                                  * found pages pinned.
      98             :                                  */
      99           0 :                                 if (scan == LAST_SCAN)
     100             :                                         error = -EBUSY;
     101             :                                 else
     102             :                                         clear = false;
     103             :                         }
     104             :                         if (clear)
     105           0 :                                 xas_clear_mark(&xas, MEMFD_TAG_PINNED);
     106           0 :                         if (++tagged % XA_CHECK_SCHED)
     107           0 :                                 continue;
     108             : 
     109           0 :                         xas_pause(&xas);
     110           0 :                         xas_unlock_irq(&xas);
     111           0 :                         cond_resched();
     112           0 :                         xas_lock_irq(&xas);
     113             :                 }
     114           0 :                 xas_unlock_irq(&xas);
     115             :         }
     116             : 
     117           0 :         return error;
     118             : }
     119             : 
     120           0 : static unsigned int *memfd_file_seals_ptr(struct file *file)
     121             : {
     122           0 :         if (shmem_file(file))
     123           0 :                 return &SHMEM_I(file_inode(file))->seals;
     124             : 
     125             : #ifdef CONFIG_HUGETLBFS
     126             :         if (is_file_hugepages(file))
     127             :                 return &HUGETLBFS_I(file_inode(file))->seals;
     128             : #endif
     129             : 
     130             :         return NULL;
     131             : }
     132             : 
     133             : #define F_ALL_SEALS (F_SEAL_SEAL | \
     134             :                      F_SEAL_SHRINK | \
     135             :                      F_SEAL_GROW | \
     136             :                      F_SEAL_WRITE | \
     137             :                      F_SEAL_FUTURE_WRITE)
     138             : 
     139           0 : static int memfd_add_seals(struct file *file, unsigned int seals)
     140             : {
     141           0 :         struct inode *inode = file_inode(file);
     142           0 :         unsigned int *file_seals;
     143           0 :         int error;
     144             : 
     145             :         /*
     146             :          * SEALING
     147             :          * Sealing allows multiple parties to share a tmpfs or hugetlbfs file
     148             :          * but restrict access to a specific subset of file operations. Seals
     149             :          * can only be added, but never removed. This way, mutually untrusted
     150             :          * parties can share common memory regions with a well-defined policy.
     151             :          * A malicious peer can thus never perform unwanted operations on a
     152             :          * shared object.
     153             :          *
     154             :          * Seals are only supported on special tmpfs or hugetlbfs files and
     155             :          * always affect the whole underlying inode. Once a seal is set, it
     156             :          * may prevent some kinds of access to the file. Currently, the
     157             :          * following seals are defined:
     158             :          *   SEAL_SEAL: Prevent further seals from being set on this file
     159             :          *   SEAL_SHRINK: Prevent the file from shrinking
     160             :          *   SEAL_GROW: Prevent the file from growing
     161             :          *   SEAL_WRITE: Prevent write access to the file
     162             :          *
     163             :          * As we don't require any trust relationship between two parties, we
     164             :          * must prevent seals from being removed. Therefore, sealing a file
     165             :          * only adds a given set of seals to the file, it never touches
     166             :          * existing seals. Furthermore, the "setting seals"-operation can be
     167             :          * sealed itself, which basically prevents any further seal from being
     168             :          * added.
     169             :          *
     170             :          * Semantics of sealing are only defined on volatile files. Only
     171             :          * anonymous tmpfs and hugetlbfs files support sealing. More
     172             :          * importantly, seals are never written to disk. Therefore, there's
     173             :          * no plan to support it on other file types.
     174             :          */
     175             : 
     176           0 :         if (!(file->f_mode & FMODE_WRITE))
     177             :                 return -EPERM;
     178           0 :         if (seals & ~(unsigned int)F_ALL_SEALS)
     179             :                 return -EINVAL;
     180             : 
     181           0 :         inode_lock(inode);
     182             : 
     183           0 :         file_seals = memfd_file_seals_ptr(file);
     184           0 :         if (!file_seals) {
     185           0 :                 error = -EINVAL;
     186           0 :                 goto unlock;
     187             :         }
     188             : 
     189           0 :         if (*file_seals & F_SEAL_SEAL) {
     190           0 :                 error = -EPERM;
     191           0 :                 goto unlock;
     192             :         }
     193             : 
     194           0 :         if ((seals & F_SEAL_WRITE) && !(*file_seals & F_SEAL_WRITE)) {
     195           0 :                 error = mapping_deny_writable(file->f_mapping);
     196           0 :                 if (error)
     197           0 :                         goto unlock;
     198             : 
     199           0 :                 error = memfd_wait_for_pins(file->f_mapping);
     200           0 :                 if (error) {
     201           0 :                         mapping_allow_writable(file->f_mapping);
     202           0 :                         goto unlock;
     203             :                 }
     204             :         }
     205             : 
     206           0 :         *file_seals |= seals;
     207           0 :         error = 0;
     208             : 
     209           0 : unlock:
     210           0 :         inode_unlock(inode);
     211           0 :         return error;
     212             : }
     213             : 
     214           0 : static int memfd_get_seals(struct file *file)
     215             : {
     216           0 :         unsigned int *seals = memfd_file_seals_ptr(file);
     217             : 
     218           0 :         return seals ? *seals : -EINVAL;
     219             : }
     220             : 
     221           0 : long memfd_fcntl(struct file *file, unsigned int cmd, unsigned long arg)
     222             : {
     223           0 :         long error;
     224             : 
     225           0 :         switch (cmd) {
     226           0 :         case F_ADD_SEALS:
     227             :                 /* disallow upper 32bit */
     228           0 :                 if (arg > UINT_MAX)
     229             :                         return -EINVAL;
     230             : 
     231           0 :                 error = memfd_add_seals(file, arg);
     232           0 :                 break;
     233           0 :         case F_GET_SEALS:
     234           0 :                 error = memfd_get_seals(file);
     235           0 :                 break;
     236             :         default:
     237             :                 error = -EINVAL;
     238             :                 break;
     239             :         }
     240             : 
     241             :         return error;
     242             : }
     243             : 
     244             : #define MFD_NAME_PREFIX "memfd:"
     245             : #define MFD_NAME_PREFIX_LEN (sizeof(MFD_NAME_PREFIX) - 1)
     246             : #define MFD_NAME_MAX_LEN (NAME_MAX - MFD_NAME_PREFIX_LEN)
     247             : 
     248             : #define MFD_ALL_FLAGS (MFD_CLOEXEC | MFD_ALLOW_SEALING | MFD_HUGETLB)
     249             : 
     250           6 : SYSCALL_DEFINE2(memfd_create,
     251             :                 const char __user *, uname,
     252             :                 unsigned int, flags)
     253             : {
     254           3 :         unsigned int *file_seals;
     255           3 :         struct file *file;
     256           3 :         int fd, error;
     257           3 :         char *name;
     258           3 :         long len;
     259             : 
     260           3 :         if (!(flags & MFD_HUGETLB)) {
     261           3 :                 if (flags & ~(unsigned int)MFD_ALL_FLAGS)
     262             :                         return -EINVAL;
     263             :         } else {
     264             :                 /* Allow huge page size encoding in flags. */
     265           0 :                 if (flags & ~(unsigned int)(MFD_ALL_FLAGS |
     266             :                                 (MFD_HUGE_MASK << MFD_HUGE_SHIFT)))
     267             :                         return -EINVAL;
     268             :         }
     269             : 
     270             :         /* length includes terminating zero */
     271           3 :         len = strnlen_user(uname, MFD_NAME_MAX_LEN + 1);
     272           3 :         if (len <= 0)
     273             :                 return -EFAULT;
     274           3 :         if (len > MFD_NAME_MAX_LEN + 1)
     275             :                 return -EINVAL;
     276             : 
     277           3 :         name = kmalloc(len + MFD_NAME_PREFIX_LEN, GFP_KERNEL);
     278           3 :         if (!name)
     279             :                 return -ENOMEM;
     280             : 
     281           3 :         strcpy(name, MFD_NAME_PREFIX);
     282           6 :         if (copy_from_user(&name[MFD_NAME_PREFIX_LEN], uname, len)) {
     283           0 :                 error = -EFAULT;
     284           0 :                 goto err_name;
     285             :         }
     286             : 
     287             :         /* terminating-zero may have changed after strnlen_user() returned */
     288           3 :         if (name[len + MFD_NAME_PREFIX_LEN - 1]) {
     289           0 :                 error = -EFAULT;
     290           0 :                 goto err_name;
     291             :         }
     292             : 
     293           3 :         fd = get_unused_fd_flags((flags & MFD_CLOEXEC) ? O_CLOEXEC : 0);
     294           3 :         if (fd < 0) {
     295           0 :                 error = fd;
     296           0 :                 goto err_name;
     297             :         }
     298             : 
     299           3 :         if (flags & MFD_HUGETLB) {
     300           3 :                 struct user_struct *user = NULL;
     301             : 
     302           3 :                 file = hugetlb_file_setup(name, 0, VM_NORESERVE, &user,
     303             :                                         HUGETLB_ANONHUGE_INODE,
     304           3 :                                         (flags >> MFD_HUGE_SHIFT) &
     305             :                                         MFD_HUGE_MASK);
     306             :         } else
     307           3 :                 file = shmem_file_setup(name, 0, VM_NORESERVE);
     308           3 :         if (IS_ERR(file)) {
     309           0 :                 error = PTR_ERR(file);
     310           0 :                 goto err_fd;
     311             :         }
     312           3 :         file->f_mode |= FMODE_LSEEK | FMODE_PREAD | FMODE_PWRITE;
     313           3 :         file->f_flags |= O_LARGEFILE;
     314             : 
     315           3 :         if (flags & MFD_ALLOW_SEALING) {
     316           0 :                 file_seals = memfd_file_seals_ptr(file);
     317           0 :                 *file_seals &= ~F_SEAL_SEAL;
     318             :         }
     319             : 
     320           3 :         fd_install(fd, file);
     321           3 :         kfree(name);
     322           3 :         return fd;
     323             : 
     324           0 : err_fd:
     325           0 :         put_unused_fd(fd);
     326           0 : err_name:
     327           0 :         kfree(name);
     328           0 :         return error;
     329             : }

Generated by: LCOV version 1.14