Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

Merge branch 'compat.mount' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs

Pull compat mount cleanups from Al Viro:
"The last remnants of mount(2) compat buried by Christoph.

Buried into NFS, that is.

Generally I'm less enthusiastic about "let's use in_compat_syscall()
deep in call chain" kind of approach than Christoph seems to be, but
in this case it's warranted - that had been an NFS-specific wart,
hopefully not to be repeated in any other filesystems (read: any new
filesystem introducing non-text mount options will get NAKed even if
it doesn't mess the layout up).

IOW, not worth trying to grow an infrastructure that would avoid that
use of in_compat_syscall()..."

* 'compat.mount' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs:
fs: remove compat_sys_mount
fs,nfs: lift compat nfs4 mount data handling into the nfs code
nfs: simplify nfs4_parse_monolithic

+141 -230
+1 -1
arch/arm64/include/asm/unistd32.h
··· 53 53 #define __NR_getpid 20 54 54 __SYSCALL(__NR_getpid, sys_getpid) 55 55 #define __NR_mount 21 56 - __SYSCALL(__NR_mount, compat_sys_mount) 56 + __SYSCALL(__NR_mount, sys_mount) 57 57 /* 22 was sys_umount */ 58 58 __SYSCALL(22, sys_ni_syscall) 59 59 #define __NR_setuid 23
+1 -1
arch/mips/kernel/syscalls/syscall_n32.tbl
··· 167 167 157 n32 sync sys_sync 168 168 158 n32 acct sys_acct 169 169 159 n32 settimeofday compat_sys_settimeofday 170 - 160 n32 mount compat_sys_mount 170 + 160 n32 mount sys_mount 171 171 161 n32 umount2 sys_umount 172 172 162 n32 swapon sys_swapon 173 173 163 n32 swapoff sys_swapoff
+1 -1
arch/mips/kernel/syscalls/syscall_o32.tbl
··· 29 29 18 o32 unused18 sys_ni_syscall 30 30 19 o32 lseek sys_lseek 31 31 20 o32 getpid sys_getpid 32 - 21 o32 mount sys_mount compat_sys_mount 32 + 21 o32 mount sys_mount 33 33 22 o32 umount sys_oldumount 34 34 23 o32 setuid sys_setuid 35 35 24 o32 getuid sys_getuid
+1 -1
arch/parisc/kernel/syscalls/syscall.tbl
··· 29 29 18 common stat sys_newstat compat_sys_newstat 30 30 19 common lseek sys_lseek compat_sys_lseek 31 31 20 common getpid sys_getpid 32 - 21 common mount sys_mount compat_sys_mount 32 + 21 common mount sys_mount 33 33 22 common bind sys_bind 34 34 23 common setuid sys_setuid 35 35 24 common getuid sys_getuid
+1 -1
arch/powerpc/kernel/syscalls/syscall.tbl
··· 34 34 18 spu oldstat sys_ni_syscall 35 35 19 common lseek sys_lseek compat_sys_lseek 36 36 20 common getpid sys_getpid 37 - 21 nospu mount sys_mount compat_sys_mount 37 + 21 nospu mount sys_mount 38 38 22 32 umount sys_oldumount 39 39 22 64 umount sys_ni_syscall 40 40 22 spu umount sys_ni_syscall
+1 -1
arch/s390/kernel/syscalls/syscall.tbl
··· 26 26 16 32 lchown - sys_lchown16 27 27 19 common lseek sys_lseek compat_sys_lseek 28 28 20 common getpid sys_getpid sys_getpid 29 - 21 common mount sys_mount compat_sys_mount 29 + 21 common mount sys_mount sys_mount 30 30 22 common umount sys_oldumount sys_oldumount 31 31 23 32 setuid - sys_setuid16 32 32 24 32 getuid - sys_getuid16
+1 -1
arch/sparc/kernel/syscalls/syscall.tbl
··· 201 201 164 64 utrap_install sys_utrap_install 202 202 165 common quotactl sys_quotactl 203 203 166 common set_tid_address sys_set_tid_address 204 - 167 common mount sys_mount compat_sys_mount 204 + 167 common mount sys_mount 205 205 168 common ustat sys_ustat compat_sys_ustat 206 206 169 common setxattr sys_setxattr 207 207 170 common lsetxattr sys_lsetxattr
+1 -1
arch/x86/entry/syscalls/syscall_32.tbl
··· 32 32 18 i386 oldstat sys_stat 33 33 19 i386 lseek sys_lseek compat_sys_lseek 34 34 20 i386 getpid sys_getpid 35 - 21 i386 mount sys_mount compat_sys_mount 35 + 21 i386 mount sys_mount 36 36 22 i386 umount sys_oldumount 37 37 23 i386 setuid sys_setuid16 38 38 24 i386 getuid sys_getuid16
-1
fs/Makefile
··· 37 37 obj-$(CONFIG_FS_ENCRYPTION) += crypto/ 38 38 obj-$(CONFIG_FS_VERITY) += verity/ 39 39 obj-$(CONFIG_FILE_LOCKING) += locks.o 40 - obj-$(CONFIG_COMPAT) += compat.o 41 40 obj-$(CONFIG_BINFMT_AOUT) += binfmt_aout.o 42 41 obj-$(CONFIG_BINFMT_EM86) += binfmt_em86.o 43 42 obj-$(CONFIG_BINFMT_MISC) += binfmt_misc.o
-132
fs/compat.c
··· 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 - }
-3
fs/internal.h
··· 82 82 /* 83 83 * namespace.c 84 84 */ 85 - extern void *copy_mount_options(const void __user *); 86 - extern char *copy_mount_string(const void __user *); 87 - 88 85 extern struct vfsmount *lookup_mnt(const struct path *); 89 86 extern int finish_automount(struct vfsmount *, struct path *); 90 87
+2 -2
fs/namespace.c
··· 3072 3072 } 3073 3073 } 3074 3074 3075 - void *copy_mount_options(const void __user * data) 3075 + static void *copy_mount_options(const void __user * data) 3076 3076 { 3077 3077 char *copy; 3078 3078 unsigned left, offset; ··· 3108 3108 return copy; 3109 3109 } 3110 3110 3111 - char *copy_mount_string(const void __user *data) 3111 + static char *copy_mount_string(const void __user *data) 3112 3112 { 3113 3113 return data ? strndup_user(data, PATH_MAX) : NULL; 3114 3114 }
+127 -74
fs/nfs/fs_context.c
··· 1039 1039 } 1040 1040 1041 1041 #if IS_ENABLED(CONFIG_NFS_V4) 1042 + struct compat_nfs_string { 1043 + compat_uint_t len; 1044 + compat_uptr_t data; 1045 + }; 1046 + 1047 + static inline void compat_nfs_string(struct nfs_string *dst, 1048 + struct compat_nfs_string *src) 1049 + { 1050 + dst->data = compat_ptr(src->data); 1051 + dst->len = src->len; 1052 + } 1053 + 1054 + struct compat_nfs4_mount_data_v1 { 1055 + compat_int_t version; 1056 + compat_int_t flags; 1057 + compat_int_t rsize; 1058 + compat_int_t wsize; 1059 + compat_int_t timeo; 1060 + compat_int_t retrans; 1061 + compat_int_t acregmin; 1062 + compat_int_t acregmax; 1063 + compat_int_t acdirmin; 1064 + compat_int_t acdirmax; 1065 + struct compat_nfs_string client_addr; 1066 + struct compat_nfs_string mnt_path; 1067 + struct compat_nfs_string hostname; 1068 + compat_uint_t host_addrlen; 1069 + compat_uptr_t host_addr; 1070 + compat_int_t proto; 1071 + compat_int_t auth_flavourlen; 1072 + compat_uptr_t auth_flavours; 1073 + }; 1074 + 1075 + static void nfs4_compat_mount_data_conv(struct nfs4_mount_data *data) 1076 + { 1077 + struct compat_nfs4_mount_data_v1 *compat = 1078 + (struct compat_nfs4_mount_data_v1 *)data; 1079 + 1080 + /* copy the fields backwards */ 1081 + data->auth_flavours = compat_ptr(compat->auth_flavours); 1082 + data->auth_flavourlen = compat->auth_flavourlen; 1083 + data->proto = compat->proto; 1084 + data->host_addr = compat_ptr(compat->host_addr); 1085 + data->host_addrlen = compat->host_addrlen; 1086 + compat_nfs_string(&data->hostname, &compat->hostname); 1087 + compat_nfs_string(&data->mnt_path, &compat->mnt_path); 1088 + compat_nfs_string(&data->client_addr, &compat->client_addr); 1089 + data->acdirmax = compat->acdirmax; 1090 + data->acdirmin = compat->acdirmin; 1091 + data->acregmax = compat->acregmax; 1092 + data->acregmin = compat->acregmin; 1093 + data->retrans = compat->retrans; 1094 + data->timeo = compat->timeo; 1095 + data->wsize = compat->wsize; 1096 + data->rsize = compat->rsize; 1097 + data->flags = compat->flags; 1098 + data->version = compat->version; 1099 + } 1100 + 1042 1101 /* 1043 1102 * Validate NFSv4 mount options 1044 1103 */ ··· 1108 1049 struct sockaddr *sap = (struct sockaddr *)&ctx->nfs_server.address; 1109 1050 char *c; 1110 1051 1111 - if (data == NULL) 1112 - goto out_no_data; 1052 + if (!data) { 1053 + if (is_remount_fc(fc)) 1054 + goto done; 1055 + return nfs_invalf(fc, 1056 + "NFS4: mount program didn't pass any mount data"); 1057 + } 1113 1058 1114 1059 ctx->version = 4; 1115 1060 1116 - switch (data->version) { 1117 - case 1: 1118 - if (data->host_addrlen > sizeof(ctx->nfs_server.address)) 1119 - goto out_no_address; 1120 - if (data->host_addrlen == 0) 1121 - goto out_no_address; 1122 - ctx->nfs_server.addrlen = data->host_addrlen; 1123 - if (copy_from_user(sap, data->host_addr, data->host_addrlen)) 1061 + if (data->version != 1) 1062 + return generic_parse_monolithic(fc, data); 1063 + 1064 + if (in_compat_syscall()) 1065 + nfs4_compat_mount_data_conv(data); 1066 + 1067 + if (data->host_addrlen > sizeof(ctx->nfs_server.address)) 1068 + goto out_no_address; 1069 + if (data->host_addrlen == 0) 1070 + goto out_no_address; 1071 + ctx->nfs_server.addrlen = data->host_addrlen; 1072 + if (copy_from_user(sap, data->host_addr, data->host_addrlen)) 1073 + return -EFAULT; 1074 + if (!nfs_verify_server_address(sap)) 1075 + goto out_no_address; 1076 + ctx->nfs_server.port = ntohs(((struct sockaddr_in *)sap)->sin_port); 1077 + 1078 + if (data->auth_flavourlen) { 1079 + rpc_authflavor_t pseudoflavor; 1080 + 1081 + if (data->auth_flavourlen > 1) 1082 + goto out_inval_auth; 1083 + if (copy_from_user(&pseudoflavor, data->auth_flavours, 1084 + sizeof(pseudoflavor))) 1124 1085 return -EFAULT; 1125 - if (!nfs_verify_server_address(sap)) 1126 - goto out_no_address; 1127 - ctx->nfs_server.port = ntohs(((struct sockaddr_in *)sap)->sin_port); 1128 - 1129 - if (data->auth_flavourlen) { 1130 - rpc_authflavor_t pseudoflavor; 1131 - if (data->auth_flavourlen > 1) 1132 - goto out_inval_auth; 1133 - if (copy_from_user(&pseudoflavor, 1134 - data->auth_flavours, 1135 - sizeof(pseudoflavor))) 1136 - return -EFAULT; 1137 - ctx->selected_flavor = pseudoflavor; 1138 - } else 1139 - ctx->selected_flavor = RPC_AUTH_UNIX; 1140 - 1141 - c = strndup_user(data->hostname.data, NFS4_MAXNAMLEN); 1142 - if (IS_ERR(c)) 1143 - return PTR_ERR(c); 1144 - ctx->nfs_server.hostname = c; 1145 - 1146 - c = strndup_user(data->mnt_path.data, NFS4_MAXPATHLEN); 1147 - if (IS_ERR(c)) 1148 - return PTR_ERR(c); 1149 - ctx->nfs_server.export_path = c; 1150 - dfprintk(MOUNT, "NFS: MNTPATH: '%s'\n", c); 1151 - 1152 - c = strndup_user(data->client_addr.data, 16); 1153 - if (IS_ERR(c)) 1154 - return PTR_ERR(c); 1155 - ctx->client_address = c; 1156 - 1157 - /* 1158 - * Translate to nfs_fs_context, which nfs_fill_super 1159 - * can deal with. 1160 - */ 1161 - 1162 - ctx->flags = data->flags & NFS4_MOUNT_FLAGMASK; 1163 - ctx->rsize = data->rsize; 1164 - ctx->wsize = data->wsize; 1165 - ctx->timeo = data->timeo; 1166 - ctx->retrans = data->retrans; 1167 - ctx->acregmin = data->acregmin; 1168 - ctx->acregmax = data->acregmax; 1169 - ctx->acdirmin = data->acdirmin; 1170 - ctx->acdirmax = data->acdirmax; 1171 - ctx->nfs_server.protocol = data->proto; 1172 - nfs_validate_transport_protocol(ctx); 1173 - if (ctx->nfs_server.protocol == XPRT_TRANSPORT_UDP) 1174 - goto out_invalid_transport_udp; 1175 - 1176 - break; 1177 - default: 1178 - goto generic; 1086 + ctx->selected_flavor = pseudoflavor; 1087 + } else { 1088 + ctx->selected_flavor = RPC_AUTH_UNIX; 1179 1089 } 1180 1090 1091 + c = strndup_user(data->hostname.data, NFS4_MAXNAMLEN); 1092 + if (IS_ERR(c)) 1093 + return PTR_ERR(c); 1094 + ctx->nfs_server.hostname = c; 1095 + 1096 + c = strndup_user(data->mnt_path.data, NFS4_MAXPATHLEN); 1097 + if (IS_ERR(c)) 1098 + return PTR_ERR(c); 1099 + ctx->nfs_server.export_path = c; 1100 + dfprintk(MOUNT, "NFS: MNTPATH: '%s'\n", c); 1101 + 1102 + c = strndup_user(data->client_addr.data, 16); 1103 + if (IS_ERR(c)) 1104 + return PTR_ERR(c); 1105 + ctx->client_address = c; 1106 + 1107 + /* 1108 + * Translate to nfs_fs_context, which nfs_fill_super 1109 + * can deal with. 1110 + */ 1111 + 1112 + ctx->flags = data->flags & NFS4_MOUNT_FLAGMASK; 1113 + ctx->rsize = data->rsize; 1114 + ctx->wsize = data->wsize; 1115 + ctx->timeo = data->timeo; 1116 + ctx->retrans = data->retrans; 1117 + ctx->acregmin = data->acregmin; 1118 + ctx->acregmax = data->acregmax; 1119 + ctx->acdirmin = data->acdirmin; 1120 + ctx->acdirmax = data->acdirmax; 1121 + ctx->nfs_server.protocol = data->proto; 1122 + nfs_validate_transport_protocol(ctx); 1123 + if (ctx->nfs_server.protocol == XPRT_TRANSPORT_UDP) 1124 + goto out_invalid_transport_udp; 1125 + done: 1181 1126 ctx->skip_reconfig_option_check = true; 1182 1127 return 0; 1183 - 1184 - generic: 1185 - return generic_parse_monolithic(fc, data); 1186 - 1187 - out_no_data: 1188 - if (is_remount_fc(fc)) { 1189 - ctx->skip_reconfig_option_check = true; 1190 - return 0; 1191 - } 1192 - return nfs_invalf(fc, "NFS4: mount program didn't pass any mount data"); 1193 1128 1194 1129 out_inval_auth: 1195 1130 return nfs_invalf(fc, "NFS4: Invalid number of RPC auth flavours %d",
-6
include/linux/compat.h
··· 516 516 asmlinkage long compat_sys_ioctl(unsigned int fd, unsigned int cmd, 517 517 compat_ulong_t arg); 518 518 519 - /* fs/namespace.c */ 520 - asmlinkage long compat_sys_mount(const char __user *dev_name, 521 - const char __user *dir_name, 522 - const char __user *type, compat_ulong_t flags, 523 - const void __user *data); 524 - 525 519 /* fs/open.c */ 526 520 asmlinkage long compat_sys_statfs(const char __user *pathname, 527 521 struct compat_statfs __user *buf);
+1 -1
include/uapi/asm-generic/unistd.h
··· 140 140 #define __NR_umount2 39 141 141 __SYSCALL(__NR_umount2, sys_umount) 142 142 #define __NR_mount 40 143 - __SC_COMP(__NR_mount, sys_mount, compat_sys_mount) 143 + __SYSCALL(__NR_mount, sys_mount) 144 144 #define __NR_pivot_root 41 145 145 __SYSCALL(__NR_pivot_root, sys_pivot_root) 146 146
+1 -1
tools/include/uapi/asm-generic/unistd.h
··· 140 140 #define __NR_umount2 39 141 141 __SYSCALL(__NR_umount2, sys_umount) 142 142 #define __NR_mount 40 143 - __SC_COMP(__NR_mount, sys_mount, compat_sys_mount) 143 + __SYSCALL(__NR_mount, sys_mount) 144 144 #define __NR_pivot_root 41 145 145 __SYSCALL(__NR_pivot_root, sys_pivot_root) 146 146
+1 -1
tools/perf/arch/powerpc/entry/syscalls/syscall.tbl
··· 32 32 18 spu oldstat sys_ni_syscall 33 33 19 common lseek sys_lseek compat_sys_lseek 34 34 20 common getpid sys_getpid 35 - 21 nospu mount sys_mount compat_sys_mount 35 + 21 nospu mount sys_mount 36 36 22 32 umount sys_oldumount 37 37 22 64 umount sys_ni_syscall 38 38 22 spu umount sys_ni_syscall
+1 -1
tools/perf/arch/s390/entry/syscalls/syscall.tbl
··· 26 26 16 32 lchown - compat_sys_s390_lchown16 27 27 19 common lseek sys_lseek compat_sys_lseek 28 28 20 common getpid sys_getpid sys_getpid 29 - 21 common mount sys_mount compat_sys_mount 29 + 21 common mount sys_mount 30 30 22 common umount sys_oldumount compat_sys_oldumount 31 31 23 32 setuid - compat_sys_s390_setuid16 32 32 24 32 getuid - compat_sys_s390_getuid16