Branch data Line data Source code
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 : 0 : static inline void compat_nfs_string(struct nfs_string *dst, 28 : : struct compat_nfs_string *src) 29 : : { 30 : 0 : dst->data = compat_ptr(src->data); 31 : 0 : 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 : 0 : static int do_nfs4_super_data_conv(void *raw_data) 56 : : { 57 : 0 : int version = *(compat_uint_t *) raw_data; 58 : : 59 : 0 : if (version == 1) { 60 : 0 : struct compat_nfs4_mount_data_v1 *raw = raw_data; 61 : 0 : struct nfs4_mount_data *real = raw_data; 62 : : 63 : : /* copy the fields backwards */ 64 : 0 : real->auth_flavours = compat_ptr(raw->auth_flavours); 65 : 0 : real->auth_flavourlen = raw->auth_flavourlen; 66 : 0 : real->proto = raw->proto; 67 : 0 : real->host_addr = compat_ptr(raw->host_addr); 68 : 0 : real->host_addrlen = raw->host_addrlen; 69 : 0 : compat_nfs_string(&real->hostname, &raw->hostname); 70 : 0 : compat_nfs_string(&real->mnt_path, &raw->mnt_path); 71 : 0 : compat_nfs_string(&real->client_addr, &raw->client_addr); 72 : 0 : real->acdirmax = raw->acdirmax; 73 : 0 : real->acdirmin = raw->acdirmin; 74 : 0 : real->acregmax = raw->acregmax; 75 : 0 : real->acregmin = raw->acregmin; 76 : 0 : real->retrans = raw->retrans; 77 : 0 : real->timeo = raw->timeo; 78 : 0 : real->wsize = raw->wsize; 79 : 0 : real->rsize = raw->rsize; 80 : 0 : real->flags = raw->flags; 81 : 0 : real->version = raw->version; 82 : : } 83 : : 84 : : return 0; 85 : : } 86 : : 87 : : #define NFS4_NAME "nfs4" 88 : : 89 : 0 : 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 : 0 : char *kernel_type; 95 : 0 : void *options; 96 : 0 : char *kernel_dev; 97 : 0 : int retval; 98 : : 99 : 0 : kernel_type = copy_mount_string(type); 100 [ # # ]: 0 : retval = PTR_ERR(kernel_type); 101 [ # # ]: 0 : if (IS_ERR(kernel_type)) 102 : 0 : goto out; 103 : : 104 : 0 : kernel_dev = copy_mount_string(dev_name); 105 [ # # ]: 0 : retval = PTR_ERR(kernel_dev); 106 [ # # ]: 0 : if (IS_ERR(kernel_dev)) 107 : 0 : goto out1; 108 : : 109 : 0 : options = copy_mount_options(data); 110 [ # # ]: 0 : retval = PTR_ERR(options); 111 [ # # ]: 0 : if (IS_ERR(options)) 112 : 0 : goto out2; 113 : : 114 [ # # ]: 0 : if (kernel_type && options) { 115 [ # # ]: 0 : if (!strcmp(kernel_type, NFS4_NAME)) { 116 : 0 : retval = -EINVAL; 117 [ # # ]: 0 : if (do_nfs4_super_data_conv(options)) 118 : : goto out3; 119 : : } 120 : : } 121 : : 122 : 0 : retval = do_mount(kernel_dev, dir_name, kernel_type, flags, options); 123 : : 124 : : out3: 125 : 0 : kfree(options); 126 : 0 : out2: 127 : 0 : kfree(kernel_dev); 128 : 0 : out1: 129 : 0 : kfree(kernel_type); 130 : 0 : out: 131 : 0 : return retval; 132 : : }