root/fs/compat.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. compat_nfs_string
  2. do_nfs4_super_data_conv
  3. COMPAT_SYSCALL_DEFINE5

   1 // SPDX-License-Identifier: GPL-2.0-only
   2 /*
   3  *  linux/fs/compat.c
   4  *
   5  *  Kernel compatibililty routines for e.g. 32 bit syscall support
   6  *  on 64 bit kernels.
   7  *
   8  *  Copyright (C) 2002       Stephen Rothwell, IBM Corporation
   9  *  Copyright (C) 1997-2000  Jakub Jelinek  (jakub@redhat.com)
  10  *  Copyright (C) 1998       Eddie C. Dost  (ecd@skynet.be)
  11  *  Copyright (C) 2001,2002  Andi Kleen, SuSE Labs 
  12  *  Copyright (C) 2003       Pavel Machek (pavel@ucw.cz)
  13  */
  14 
  15 #include <linux/compat.h>
  16 #include <linux/nfs4_mount.h>
  17 #include <linux/syscalls.h>
  18 #include <linux/slab.h>
  19 #include <linux/uaccess.h>
  20 #include "internal.h"
  21 
  22 struct compat_nfs_string {
  23         compat_uint_t len;
  24         compat_uptr_t data;
  25 };
  26 
  27 static inline void compat_nfs_string(struct nfs_string *dst,
  28                                      struct compat_nfs_string *src)
  29 {
  30         dst->data = compat_ptr(src->data);
  31         dst->len = src->len;
  32 }
  33 
  34 struct compat_nfs4_mount_data_v1 {
  35         compat_int_t version;
  36         compat_int_t flags;
  37         compat_int_t rsize;
  38         compat_int_t wsize;
  39         compat_int_t timeo;
  40         compat_int_t retrans;
  41         compat_int_t acregmin;
  42         compat_int_t acregmax;
  43         compat_int_t acdirmin;
  44         compat_int_t acdirmax;
  45         struct compat_nfs_string client_addr;
  46         struct compat_nfs_string mnt_path;
  47         struct compat_nfs_string hostname;
  48         compat_uint_t host_addrlen;
  49         compat_uptr_t host_addr;
  50         compat_int_t proto;
  51         compat_int_t auth_flavourlen;
  52         compat_uptr_t auth_flavours;
  53 };
  54 
  55 static int do_nfs4_super_data_conv(void *raw_data)
  56 {
  57         int version = *(compat_uint_t *) raw_data;
  58 
  59         if (version == 1) {
  60                 struct compat_nfs4_mount_data_v1 *raw = raw_data;
  61                 struct nfs4_mount_data *real = raw_data;
  62 
  63                 /* copy the fields backwards */
  64                 real->auth_flavours = compat_ptr(raw->auth_flavours);
  65                 real->auth_flavourlen = raw->auth_flavourlen;
  66                 real->proto = raw->proto;
  67                 real->host_addr = compat_ptr(raw->host_addr);
  68                 real->host_addrlen = raw->host_addrlen;
  69                 compat_nfs_string(&real->hostname, &raw->hostname);
  70                 compat_nfs_string(&real->mnt_path, &raw->mnt_path);
  71                 compat_nfs_string(&real->client_addr, &raw->client_addr);
  72                 real->acdirmax = raw->acdirmax;
  73                 real->acdirmin = raw->acdirmin;
  74                 real->acregmax = raw->acregmax;
  75                 real->acregmin = raw->acregmin;
  76                 real->retrans = raw->retrans;
  77                 real->timeo = raw->timeo;
  78                 real->wsize = raw->wsize;
  79                 real->rsize = raw->rsize;
  80                 real->flags = raw->flags;
  81                 real->version = raw->version;
  82         }
  83 
  84         return 0;
  85 }
  86 
  87 #define NFS4_NAME       "nfs4"
  88 
  89 COMPAT_SYSCALL_DEFINE5(mount, const char __user *, dev_name,
  90                        const char __user *, dir_name,
  91                        const char __user *, type, compat_ulong_t, flags,
  92                        const void __user *, data)
  93 {
  94         char *kernel_type;
  95         void *options;
  96         char *kernel_dev;
  97         int retval;
  98 
  99         kernel_type = copy_mount_string(type);
 100         retval = PTR_ERR(kernel_type);
 101         if (IS_ERR(kernel_type))
 102                 goto out;
 103 
 104         kernel_dev = copy_mount_string(dev_name);
 105         retval = PTR_ERR(kernel_dev);
 106         if (IS_ERR(kernel_dev))
 107                 goto out1;
 108 
 109         options = copy_mount_options(data);
 110         retval = PTR_ERR(options);
 111         if (IS_ERR(options))
 112                 goto out2;
 113 
 114         if (kernel_type && options) {
 115                 if (!strcmp(kernel_type, NFS4_NAME)) {
 116                         retval = -EINVAL;
 117                         if (do_nfs4_super_data_conv(options))
 118                                 goto out3;
 119                 }
 120         }
 121 
 122         retval = do_mount(kernel_dev, dir_name, kernel_type, flags, options);
 123 
 124  out3:
 125         kfree(options);
 126  out2:
 127         kfree(kernel_dev);
 128  out1:
 129         kfree(kernel_type);
 130  out:
 131         return retval;
 132 }

/* [<][>][^][v][top][bottom][index][help] */