s390: get rid of own uid16 compat system calls
Hi all,
I was about to get rid of the compat uid16 system calls we have in s390 arch code and use the common code uid16 ones (see patch below). Since in 64 bit mode we don't have any of the uid16 system calls, these could be used for the compat layer where we need them.
"Only" thing is that we unfortunately have different sizes for __kernel_old_[uid|gid]_t (16 bit on s390, 32 on s390x). I was tempted to change these just to find out that there are other users as well:
include/linux/ncp_fs.h:
#define NCP_IOC_GETMOUNTUID _IOW('n', 2, __kernel_old_uid_t)include/linux/smb_fs.h:
#define SMB_IOC_GETMOUNTUID _IOR('u', 1, __kernel_old_uid_t)
So, this is no option. Would anybody know of something to get this work? Or is this just a stupid idea?
---
arch/s390/kernel/compat_linux.c | 206 -------------------------------------- arch/s390/kernel/compat_wrapper.S | 98 ++++++++---------- arch/s390/kernel/syscalls.S | 38 +++---- init/Kconfig | 2 4 files changed, 65 insertions(+), 279 deletions(-)
arch/s390/kernel/compat_linux.c +0 -206
@@ -15,7 +15,6 @@* */ -#include <linux/kernel.h> #include <linux/sched.h> #include <linux/fs.h>
@@ -69,211 +68,6 @@#include "compat_linux.h" - -/* For this source file, we want overflow handling. */ - -#undef high2lowuid -#undef high2lowgid -#undef low2highuid -#undef low2highgid -#undef SET_UID16 -#undef SET_GID16 -#undef NEW_TO_OLD_UID -#undef NEW_TO_OLD_GID -#undef SET_OLDSTAT_UID -#undef SET_OLDSTAT_GID -#undef SET_STAT_UID -#undef SET_STAT_GID - -#define high2lowuid (uid) ((uid) > 65535) ? (u16)overflowuid : (u16)(uid) -#define high2lowgid (gid) ((gid) > 65535) ? (u16)overflowgid : (u16)(gid) -#define low2highuid (uid) ((uid) == (u16)-1) ? (uid_t)-1 : (uid_t)(uid) -#define low2highgid (gid) ((gid) == (u16)-1) ? (gid_t)-1 : (gid_t)(gid) -#define SET_UID16 (var, uid) var = high2lowuid(uid) -#define SET_GID16 (var, gid) var = high2lowgid(gid) -#define NEW_TO_OLD_UID (uid) high2lowuid(uid) -#define NEW_TO_OLD_GID (gid) high2lowgid(gid) -#define SET_OLDSTAT_UID (stat, uid) (stat).st_uid = high2lowuid(uid) -#define SET_OLDSTAT_GID (stat, gid) (stat).st_gid = high2lowgid(gid) -#define SET_STAT_UID (stat, uid) (stat).st_uid = high2lowuid(uid) -#define SET_STAT_GID (stat, gid) (stat).st_gid = high2lowgid(gid) - -asmlinkage long sys32_chown16 (const char __user * filename,u16 user,u16 group) -{ -return sys_chown (filename,low2highuid (user),low2highgid (group)); -} - -asmlinkage long sys32_lchown16 (const char __user * filename,u16 user,u16 group) -{ -return sys_lchown (filename,low2highuid (user),low2highgid (group)); -} - -asmlinkage long sys32_fchown16 (unsigned int fd,u16 user,u16 group) -{ -return sys_fchown (fd,low2highuid (user),low2highgid (group)); -} - -asmlinkage long sys32_setregid16 (u16 rgid,u16 egid) -{ -return sys_setregid (low2highgid (rgid),low2highgid (egid)); -} - -asmlinkage long sys32_setgid16 (u16 gid) -{ -return sys_setgid ((gid_t )gid); -} - -asmlinkage long sys32_setreuid16 (u16 ruid,u16 euid) -{ -return sys_setreuid (low2highuid (ruid),low2highuid (euid)); -} - -asmlinkage long sys32_setuid16 (u16 uid) -{ -return sys_setuid ((uid_t )uid); -} - -asmlinkage long sys32_setresuid16 (u16 ruid,u16 euid,u16 suid) -{ -return sys_setresuid (low2highuid (ruid),low2highuid (euid), -low2highuid (suid)); -} - -asmlinkage long sys32_getresuid16 (u16 __user *ruid,u16 __user *euid,u16 __user *suid) -{ -int retval; - -if (!(retval =put_user (high2lowuid (current->uid), ruid)) && - !(retval =put_user (high2lowuid (current->euid), euid))) - retval =put_user (high2lowuid (current->suid), suid); - -return retval; -} - -asmlinkage long sys32_setresgid16 (u16 rgid,u16 egid,u16 sgid) -{ -return sys_setresgid (low2highgid (rgid),low2highgid (egid), -low2highgid (sgid)); -} - -asmlinkage long sys32_getresgid16 (u16 __user *rgid,u16 __user *egid,u16 __user *sgid) -{ -int retval; - -if (!(retval =put_user (high2lowgid (current->gid), rgid)) && - !(retval =put_user (high2lowgid (current->egid), egid))) - retval =put_user (high2lowgid (current->sgid), sgid); - -return retval; -} - -asmlinkage long sys32_setfsuid16 (u16 uid) -{ -return sys_setfsuid ((uid_t )uid); -} - -asmlinkage long sys32_setfsgid16 (u16 gid) -{ -return sys_setfsgid ((gid_t )gid); -} - -static int groups16_to_user (u16 __user *grouplist,struct group_info *group_info) -{ -int i; -u16 group; - -for (i =0 ; i < group_info->ngroups; i++) { - group = (u16 )GROUP_AT (group_info, i); -if (put_user (group, grouplist+i)) -return -EFAULT ; - } - -return 0 ; -} - -static int groups16_from_user (struct group_info *group_info,u16 __user *grouplist) -{ -int i; -u16 group; - -for (i =0 ; i < group_info->ngroups; i++) { -if (get_user (group, grouplist+i)) -return -EFAULT ; -GROUP_AT (group_info, i) = (gid_t )group; - } - -return 0 ; -} - -asmlinkage long sys32_getgroups16 (int gidsetsize,u16 __user *grouplist) -{ -int i; - -if (gidsetsize <0 ) -return -EINVAL ; - -get_group_info (current->group_info); - i = current->group_info->ngroups; -if (gidsetsize) { -if (i > gidsetsize) { - i = -EINVAL ; - goto out; - } -if (groups16_to_user (grouplist, current->group_info)) { - i = -EFAULT ; - goto out; - } - } -out: -put_group_info (current->group_info); -return i; -} - -asmlinkage long sys32_setgroups16 (int gidsetsize,u16 __user *grouplist) -{ -struct group_info *group_info; -int retval; - -if (!capable (CAP_SETGID )) -return -EPERM ; -if ((unsigned )gidsetsize >NGROUPS_MAX ) -return -EINVAL ; - - group_info =groups_alloc (gidsetsize); -if (!group_info) -return -ENOMEM ; - retval =groups16_from_user (group_info, grouplist); -if (retval) { -put_group_info (group_info); -return retval; - } - - retval =set_current_groups (group_info); -put_group_info (group_info); - -return retval; -} - -asmlinkage long sys32_getuid16 (void ) -{ -return high2lowuid (current->uid); -} - -asmlinkage long sys32_geteuid16 (void ) -{ -return high2lowuid (current->euid); -} - -asmlinkage long sys32_getgid16 (void ) -{ -return high2lowgid (current->gid); -} - -asmlinkage long sys32_getegid16 (void ) -{ -return high2lowgid (current->egid); -} -/* 32-bit timeval and related flotsam. */ static inline long get_tv32 (struct timeval *o,struct compat_timeval __user *i)
init/Kconfig +1 -1
@@ -239,7 +239,7 @@ source "usr/Kconfig" config UID16 bool "Enable 16-bit UID system calls" if EMBEDDED - depends on ARM || CRIS || FRV || H8300 || X86_32 || M68K || (S390 && !64BIT) || SUPERH || SPARC32 || (SPARC64 && SPARC32_COMPAT) || UML || (X86_64 && IA32_EMULATION) + depends on ARM || CRIS || FRV || H8300 || X86_32 || M68K || (S390 && (!64BIT || COMPAT)) || SUPERH || SPARC32 || (SPARC64 && SPARC32_COMPAT) || UML || (X86_64 && IA32_EMULATION) default y help This enables the legacy 16-bit UID syscall wrappers.
arch/s390/kernel/compat_wrapper.S +45 -53
202 lines not on this page · raw message
arch/s390/kernel/syscalls.S +19 -19
@@ -24,15 +24,15 @@ SYSCALL(sys_chdir,sys_chdir,sys32_chdir_ SYSCALL(sys_time,sys_ni_syscall,sys32_time_wrapper) /* old time syscall */ SYSCALL(sys_mknod,sys_mknod,sys32_mknod_wrapper) SYSCALL(sys_chmod,sys_chmod,sys32_chmod_wrapper) /* 15 */ -SYSCALL(sys_lchown16,sys_ni_syscall,sys32_lchown16_wrapper) /* old lchown16 syscall*/ +SYSCALL(sys_lchown16,sys_ni_syscall,sys_lchown16_wrapper) /* old lchown16 syscall*/ NI_SYSCALL /* old break syscall holder */ NI_SYSCALL /* old stat syscall holder */ SYSCALL(sys_lseek,sys_lseek,sys32_lseek_wrapper) SYSCALL(sys_getpid,sys_getpid,sys_getpid) /* 20 */ SYSCALL(sys_mount,sys_mount,sys32_mount_wrapper) SYSCALL(sys_oldumount,sys_oldumount,sys32_oldumount_wrapper) -SYSCALL(sys_setuid16,sys_ni_syscall,sys32_setuid16_wrapper) /* old setuid16 syscall*/ -SYSCALL(sys_getuid16,sys_ni_syscall,sys32_getuid16) /* old getuid16 syscall*/ +SYSCALL(sys_setuid16,sys_ni_syscall,sys_setuid16_wrapper) /* old setuid16 syscall*/ +SYSCALL(sys_getuid16,sys_ni_syscall,sys_getuid16) /* old getuid16 syscall*/ SYSCALL(sys_stime,sys_ni_syscall,sys32_stime_wrapper) /* 25 old stime syscall */ SYSCALL(sys_ptrace,sys_ptrace,sys32_ptrace_wrapper) SYSCALL(sys_alarm,sys_alarm,sys32_alarm_wrapper)
@@ -54,11 +54,11 @@ SYSCALL(sys_pipe,sys_pipe,sys32_pipe_wra SYSCALL(sys_times,sys_times,compat_sys_times_wrapper) NI_SYSCALL /* old prof syscall */ SYSCALL(sys_brk,sys_brk,sys32_brk_wrapper) /* 45 */ -SYSCALL(sys_setgid16,sys_ni_syscall,sys32_setgid16_wrapper) /* old setgid16 syscall*/ -SYSCALL(sys_getgid16,sys_ni_syscall,sys32_getgid16) /* old getgid16 syscall*/ +SYSCALL(sys_setgid16,sys_ni_syscall,sys_setgid16_wrapper) /* old setgid16 syscall*/ +SYSCALL(sys_getgid16,sys_ni_syscall,sys_getgid16) /* old getgid16 syscall*/ SYSCALL(sys_signal,sys_signal,sys32_signal_wrapper) -SYSCALL(sys_geteuid16,sys_ni_syscall,sys32_geteuid16) /* old geteuid16 syscall */ -SYSCALL(sys_getegid16,sys_ni_syscall,sys32_getegid16) /* 50 old getegid16 syscall */ +SYSCALL(sys_geteuid16,sys_ni_syscall,sys_geteuid16) /* old geteuid16 syscall */ +SYSCALL(sys_getegid16,sys_ni_syscall,sys_getegid16) /* 50 old getegid16 syscall */ SYSCALL(sys_acct,sys_acct,sys32_acct_wrapper) SYSCALL(sys_umount,sys_umount,sys32_umount_wrapper) NI_SYSCALL /* old lock syscall */
@@ -78,8 +78,8 @@ SYSCALL(sys_setsid,sys_setsid,sys_setsid SYSCALL(sys_sigaction,sys_sigaction,sys32_sigaction_wrapper) NI_SYSCALL /* old sgetmask syscall*/ NI_SYSCALL /* old ssetmask syscall*/ -SYSCALL(sys_setreuid16,sys_ni_syscall,sys32_setreuid16_wrapper) /* old setreuid16 syscall */ -SYSCALL(sys_setregid16,sys_ni_syscall,sys32_setregid16_wrapper) /* old setregid16 syscall */ +SYSCALL(sys_setreuid16,sys_ni_syscall,sys_setreuid16_wrapper) /* old setreuid16 syscall */ +SYSCALL(sys_setregid16,sys_ni_syscall,sys_setregid16_wrapper) /* old setregid16 syscall */ SYSCALL(sys_sigsuspend,sys_sigsuspend,sys_sigsuspend_wrapper) SYSCALL(sys_sigpending,sys_sigpending,compat_sys_sigpending_wrapper) SYSCALL(sys_sethostname,sys_sethostname,sys32_sethostname_wrapper)
@@ -88,8 +88,8 @@ SYSCALL(sys_old_getrlimit,sys_getrlimit, SYSCALL(sys_getrusage,sys_getrusage,compat_sys_getrusage_wrapper) SYSCALL(sys_gettimeofday,sys_gettimeofday,sys32_gettimeofday_wrapper) SYSCALL(sys_settimeofday,sys_settimeofday,sys32_settimeofday_wrapper) -SYSCALL(sys_getgroups16,sys_ni_syscall,sys32_getgroups16_wrapper) /* 80 old getgroups16 syscall */ -SYSCALL(sys_setgroups16,sys_ni_syscall,sys32_setgroups16_wrapper) /* old setgroups16 syscall */ +SYSCALL(sys_getgroups16,sys_ni_syscall,sys_getgroups16_wrapper) /* 80 old getgroups16 syscall */ +SYSCALL(sys_setgroups16,sys_ni_syscall,sys_setgroups16_wrapper) /* old setgroups16 syscall */ NI_SYSCALL /* old select syscall */ SYSCALL(sys_symlink,sys_symlink,sys32_symlink_wrapper) NI_SYSCALL /* old lstat syscall */
@@ -103,7 +103,7 @@ SYSCALL(sys_munmap,sys_munmap,sys32_munm SYSCALL(sys_truncate,sys_truncate,sys32_truncate_wrapper) SYSCALL(sys_ftruncate,sys_ftruncate,sys32_ftruncate_wrapper) SYSCALL(sys_fchmod,sys_fchmod,sys32_fchmod_wrapper) -SYSCALL(sys_fchown16,sys_ni_syscall,sys32_fchown16_wrapper) /* 95 old fchown16 syscall*/ +SYSCALL(sys_fchown16,sys_ni_syscall,sys_fchown16_wrapper) /* 95 old fchown16 syscall*/ SYSCALL(sys_getpriority,sys_getpriority,sys32_getpriority_wrapper) SYSCALL(sys_setpriority,sys_setpriority,sys32_setpriority_wrapper) NI_SYSCALL /* old profil syscall */
@@ -146,8 +146,8 @@ SYSCALL(sys_bdflush,sys_bdflush,sys32_bd SYSCALL(sys_sysfs,sys_sysfs,sys32_sysfs_wrapper) /* 135 */ SYSCALL(sys_personality,s390x_personality,sys32_personality_wrapper) NI_SYSCALL /* for afs_syscall */ -SYSCALL(sys_setfsuid16,sys_ni_syscall,sys32_setfsuid16_wrapper) /* old setfsuid16 syscall */ -SYSCALL(sys_setfsgid16,sys_ni_syscall,sys32_setfsgid16_wrapper) /* old setfsgid16 syscall */ +SYSCALL(sys_setfsuid16,sys_ni_syscall,sys_setfsuid16_wrapper) /* old setfsuid16 syscall */ +SYSCALL(sys_setfsgid16,sys_ni_syscall,sys_setfsgid16_wrapper) /* old setfsgid16 syscall */ SYSCALL(sys_llseek,sys_llseek,sys32_llseek_wrapper) /* 140 */ SYSCALL(sys_getdents,sys_getdents,sys32_getdents_wrapper) SYSCALL(sys_select,sys_select,compat_sys_select_wrapper)
@@ -172,14 +172,14 @@ SYSCALL(sys_sched_get_priority_min,sys_s SYSCALL(sys_sched_rr_get_interval,sys_sched_rr_get_interval,sys32_sched_rr_get_interval_wrapper) SYSCALL(sys_nanosleep,sys_nanosleep,compat_sys_nanosleep_wrapper) SYSCALL(sys_mremap,sys_mremap,sys32_mremap_wrapper) -SYSCALL(sys_setresuid16,sys_ni_syscall,sys32_setresuid16_wrapper) /* old setresuid16 syscall */ -SYSCALL(sys_getresuid16,sys_ni_syscall,sys32_getresuid16_wrapper) /* 165 old getresuid16 syscall */ +SYSCALL(sys_setresuid16,sys_ni_syscall,sys_setresuid16_wrapper) /* old setresuid16 syscall */ +SYSCALL(sys_getresuid16,sys_ni_syscall,sys_getresuid16_wrapper) /* 165 old getresuid16 syscall */ NI_SYSCALL /* for vm86 */ NI_SYSCALL /* old sys_query_module */ SYSCALL(sys_poll,sys_poll,sys32_poll_wrapper) SYSCALL(sys_nfsservctl,sys_nfsservctl,compat_sys_nfsservctl_wrapper) -SYSCALL(sys_setresgid16,sys_ni_syscall,sys32_setresgid16_wrapper) /* 170 old setresgid16 syscall */ -SYSCALL(sys_getresgid16,sys_ni_syscall,sys32_getresgid16_wrapper) /* old getresgid16 syscall */ +SYSCALL(sys_setresgid16,sys_ni_syscall,sys_setresgid16_wrapper) /* 170 old setresgid16 syscall */ +SYSCALL(sys_getresgid16,sys_ni_syscall,sys_getresgid16_wrapper) /* old getresgid16 syscall */ SYSCALL(sys_prctl,sys_prctl,sys32_prctl_wrapper) SYSCALL(sys_rt_sigreturn_glue,sys_rt_sigreturn_glue,sys32_rt_sigreturn_glue) SYSCALL(sys_rt_sigaction,sys_rt_sigaction,sys32_rt_sigaction_wrapper)
@@ -190,7 +190,7 @@ SYSCALL(sys_rt_sigqueueinfo,sys_rt_sigqu SYSCALL(sys_rt_sigsuspend,sys_rt_sigsuspend,compat_sys_rt_sigsuspend_wrapper) SYSCALL(sys_pread64,sys_pread64,sys32_pread64_wrapper) /* 180 */ SYSCALL(sys_pwrite64,sys_pwrite64,sys32_pwrite64_wrapper) -SYSCALL(sys_chown16,sys_ni_syscall,sys32_chown16_wrapper) /* old chown16 syscall */ +SYSCALL(sys_chown16,sys_ni_syscall,sys_chown16_wrapper) /* old chown16 syscall */ SYSCALL(sys_getcwd,sys_getcwd,sys32_getcwd_wrapper) SYSCALL(sys_capget,sys_capget,sys32_capget_wrapper) SYSCALL(sys_capset,sys_capset,sys32_capset_wrapper) /* 185 */
Quoted 11 lines · Heiko Carstens
"Only" thing is that we unfortunately have different sizes for __kernel_old_[uid|gid]_t (16 bit on s390, 32 on s390x). I was tempted to change these just to find out that there are other users as well:
include/linux/ncp_fs.h:
#defineNCP_IOC_GETMOUNTUID_IOW('n', 2, __kernel_old_uid_t)include/linux/smb_fs.h:
#defineSMB_IOC_GETMOUNTUID_IOR('u', 1, __kernel_old_uid_t)So, this is no option. Would anybody know of something to get this work? Or is this just a stupid idea?
Ok, I don't know exactly what you're talking about, but I have in the past tried to hack that area as well. It's probably a good idea to pick up my old patch and work from there, by making these two file systems understand all possible ways:
#ifdef __KERNEL__
/* anything the user may be passing to us */
#define NCP_IOC_GETMOUNTUID16 _IOW('n', 2, u16)
#define NCP_IOC_GETMOUNTUID32 _IOW('n', 2, u32)
#define NCP_IOC_GETMOUNTUID64 _IOW('n', 2, u64)
#else
/* what the user is _supposed_ to pass */
#define NCP_IOC_GETMOUNTUID _IOW('n', 2, __kernel_old_uid_t) /* 16/32 bit */ #define NCP_IOC_GETMOUNTUID2 _IOW('n', 2, unsigned long) /* 32 or 64 bit */ #endif
int ncp_ioctl(struct inode *inode, struct file *filp, ...)
{
...
switch (arg) {
...
case NCP_IOC_GETMOUNTUID16:
case NCP_IOC_GETMOUNTUID32:
case NCP_IOC_GETMOUNTUID64:
{
unsigned long tmp = server->m.mounted_uid;
if ((file_permission(filp, MAY_READ) != 0)
&& (current->uid != server->m.mounted_uid)) {
return -EACCES;
}
switch (arg) {
#ifdef CONFIG_UID16
case NCP_IOC_GETMOUNTUID16:
SET_UID(tmp, server->m.mounted_uid);
if (put_user(tmp, (u16 __user *)argp))
return -EFAULT;
#endif
case NCP_IOC_GETMOUNTUID32:
if (put_user(tmp, (u32 __user *)argp))
return -EFAULT;
#ifdef CONFIG_64BIT
case NCP_IOC_GETMOUNTUID64:
if (put_user(tmp, (u64 __user *)argp))
return -EFAULT;
}
#endif
return 0;
}
}
...
}I'm also posting the two patches I made a long time ago as a reference.
Arnd <><
reference: ncpfs: move ioctl32 code to fs/ncpfs/ioctl.c
Quoted 3 lines · Arnd Bergmann
I'm also posting the two patches I made a long time ago as a reference.
Ok, I just realized that this was not using a merged ->compat_ioctl/->unlocked_ioctl function yet, but wth, here it is anyway.
Subject: ncpfs: move ioctl32 code to fs/ncpfs/ioctl.c
The ncp specific compat ioctls are clearly local to one file system, so the code can better live there.
This could be further improved by getting rid of get_fs/set_fs in the future.
fs/compat_ioctl.c +0 -197
@@ -718,193 +718,6 @@ return sys_ioctl(fd, cmd, (unsigned long)tdata); } -#if defined(CONFIG_NCP_FS ) || defined(CONFIG_NCP_FS_MODULE ) -struct ncp_ioctl_request_32 { -u32 function; -u32 size; -compat_caddr_t data; -}; - -struct ncp_fs_info_v2_32 { -s32 version; -u32 mounted_uid; -u32 connection; -u32 buffer_size; - -u32 volume_number; -u32 directory_id; - -u32 dummy1; -u32 dummy2; -u32 dummy3; -}; - -struct ncp_objectname_ioctl_32 -{ -s32 auth_type; -u32 object_name_len; -compat_caddr_t object_name;/* an userspace data, in most cases user name */ -}; - -struct ncp_privatedata_ioctl_32 -{ -u32 len; -compat_caddr_t data;/* ~1000 for NDS */ -}; - -#define NCP_IOC_NCPREQUEST_32 _IOR('n', 1, struct ncp_ioctl_request_32) -#define NCP_IOC_GETMOUNTUID2_32 _IOW('n', 2, u32) -#define NCP_IOC_GET_FS_INFO_V2_32 _IOWR('n', 4, struct ncp_fs_info_v2_32) -#define NCP_IOC_GETOBJECTNAME_32 _IOWR('n', 9, struct ncp_objectname_ioctl_32) -#define NCP_IOC_SETOBJECTNAME_32 _IOR('n', 9, struct ncp_objectname_ioctl_32) -#define NCP_IOC_GETPRIVATEDATA_32 _IOWR('n', 10, struct ncp_privatedata_ioctl_32) -#define NCP_IOC_SETPRIVATEDATA_32 _IOR('n', 10, struct ncp_privatedata_ioctl_32) - -static int do_ncp_ncprequest (unsigned int fd,unsigned int cmd,unsigned long arg) -{ -struct ncp_ioctl_request_32 n32; -struct ncp_ioctl_request __user *p =compat_alloc_user_space (sizeof (*p)); - -if (copy_from_user (&n32,compat_ptr (arg),sizeof (n32)) || -put_user (n32.function, &p->function) || -put_user (n32.size, &p->size) || -put_user (compat_ptr (n32.data), &p->data)) -return -EFAULT ; - -return sys_ioctl (fd,NCP_IOC_NCPREQUEST , (unsigned long )p); -} - -static int do_ncp_getmountuid2 (unsigned int fd,unsigned int cmd,unsigned long arg) -{ -mm_segment_t old_fs =get_fs (); -__kernel_uid_t kuid; -int err; - - cmd =NCP_IOC_GETMOUNTUID2 ; - -set_fs (KERNEL_DS ); - err =sys_ioctl (fd, cmd, (unsigned long )&kuid); -set_fs (old_fs); - -if (!err) - err =put_user (kuid, - (unsigned int __user *)compat_ptr (arg)); - -return err; -} - -static int do_ncp_getfsinfo2 (unsigned int fd,unsigned int cmd,unsigned long arg) -{ -mm_segment_t old_fs =get_fs (); -struct ncp_fs_info_v2_32 n32; -struct ncp_fs_info_v2 n; -int err; - -if (copy_from_user (&n32,compat_ptr (arg),sizeof (n32))) -return -EFAULT ; -if (n32.version !=NCP_GET_FS_INFO_VERSION_V2 ) -return -EINVAL ; - n.version =NCP_GET_FS_INFO_VERSION_V2 ; - -set_fs (KERNEL_DS ); - err =sys_ioctl (fd,NCP_IOC_GET_FS_INFO_V2 , (unsigned long )&n); -set_fs (old_fs); - -if (!err) { - n32.version = n.version; - n32.mounted_uid = n.mounted_uid; - n32.connection = n.connection; - n32.buffer_size = n.buffer_size; - n32.volume_number = n.volume_number; - n32.directory_id = n.directory_id; - n32.dummy1 = n.dummy1; - n32.dummy2 = n.dummy2; - n32.dummy3 = n.dummy3; - err =copy_to_user (compat_ptr (arg), &n32,sizeof (n32)) ? -EFAULT :0 ; - } -return err; -} - -static int do_ncp_getobjectname (unsigned int fd,unsigned int cmd,unsigned long arg) -{ -struct ncp_objectname_ioctl_32 n32,__user *p32 =compat_ptr (arg); -struct ncp_objectname_ioctl __user *p =compat_alloc_user_space (sizeof (*p)); -s32 auth_type; -u32 name_len; -int err; - -if (copy_from_user (&n32, p32,sizeof (n32)) || -put_user (n32.object_name_len, &p->object_name_len) || -put_user (compat_ptr (n32.object_name), &p->object_name)) -return -EFAULT ; - - err =sys_ioctl (fd,NCP_IOC_GETOBJECTNAME , (unsigned long )p); -if (err) -return err; - -if (get_user (auth_type, &p->auth_type) || -put_user (auth_type, &p32->auth_type) || -get_user (name_len, &p->object_name_len) || -put_user (name_len, &p32->object_name_len)) -return -EFAULT ; - -return 0 ; -} - -static int do_ncp_setobjectname (unsigned int fd,unsigned int cmd,unsigned long arg) -{ -struct ncp_objectname_ioctl_32 n32,__user *p32 =compat_ptr (arg); -struct ncp_objectname_ioctl __user *p =compat_alloc_user_space (sizeof (*p)); - -if (copy_from_user (&n32, p32,sizeof (n32)) || -put_user (n32.auth_type, &p->auth_type) || -put_user (n32.object_name_len, &p->object_name_len) || -put_user (compat_ptr (n32.object_name), &p->object_name)) -return -EFAULT ; - -return sys_ioctl (fd,NCP_IOC_SETOBJECTNAME , (unsigned long )p); -} - -static int do_ncp_getprivatedata (unsigned int fd,unsigned int cmd,unsigned long arg) -{ -struct ncp_privatedata_ioctl_32 n32,__user *p32 =compat_ptr (arg); -struct ncp_privatedata_ioctl __user *p = -compat_alloc_user_space (sizeof (*p)); -u32 len; -int err; - -if (copy_from_user (&n32, p32,sizeof (n32)) || -put_user (n32.len, &p->len) || -put_user (compat_ptr (n32.data), &p->data)) -return -EFAULT ; - - err =sys_ioctl (fd,NCP_IOC_GETPRIVATEDATA , (unsigned long )p); -if (err) -return err; - -if (get_user (len, &p->len) || -put_user (len, &p32->len)) -return -EFAULT ; - -return 0 ; -} - -static int do_ncp_setprivatedata (unsigned int fd,unsigned int cmd,unsigned long arg) -{ -struct ncp_privatedata_ioctl_32 n32; -struct ncp_privatedata_ioctl_32 __user *p32 =compat_ptr (arg); -struct ncp_privatedata_ioctl __user *p = -compat_alloc_user_space (sizeof (*p)); - -if (copy_from_user (&n32, p32,sizeof (n32)) || -put_user (n32.len, &p->len) || -put_user (compat_ptr (n32.data), &p->data)) -return -EFAULT ; - -return sys_ioctl (fd,NCP_IOC_SETPRIVATEDATA , (unsigned long )p); -} -#endif -#undef CODE#endif
@@ -937,15 +750,5 @@ HANDLE_IOCTL(I2C_RDWR, do_i2c_rdwr_ioctl) HANDLE_IOCTL(I2C_SMBUS, do_i2c_smbus_ioctl) -#if defined(CONFIG_NCP_FS ) || defined(CONFIG_NCP_FS_MODULE ) -HANDLE_IOCTL(NCP_IOC_NCPREQUEST_32, do_ncp_ncprequest) -HANDLE_IOCTL(NCP_IOC_GETMOUNTUID2_32, do_ncp_getmountuid2) -HANDLE_IOCTL(NCP_IOC_GET_FS_INFO_V2_32, do_ncp_getfsinfo2) -HANDLE_IOCTL(NCP_IOC_GETOBJECTNAME_32, do_ncp_getobjectname) -HANDLE_IOCTL(NCP_IOC_SETOBJECTNAME_32, do_ncp_setobjectname) -HANDLE_IOCTL(NCP_IOC_GETPRIVATEDATA_32, do_ncp_getprivatedata) -HANDLE_IOCTL(NCP_IOC_SETPRIVATEDATA_32, do_ncp_setprivatedata) -#endif -#undef DECLARES#endif
fs/ncpfs/dir.c +3 -0
@@ -54,6 +54,9 @@ .read = generic_read_dir, .readdir = ncp_readdir, .ioctl = ncp_ioctl, +#ifdef CONFIG_COMPAT + .compat_ioctl = ncp_compat_ioctl, +#endif }; struct inode_operations ncp_dir_inode_operations =
fs/ncpfs/file.c +4 -0
@@ -9,6 +9,7 @@#include <asm/uaccess.h> #include <asm/system.h> +#include <linux/config.h> #include <linux/time.h> #include <linux/kernel.h> #include <linux/errno.h>
@@ -289,6 +290,9 @@ .read = ncp_file_read, .write = ncp_file_write, .ioctl = ncp_ioctl, +#ifdef CONFIG_COMPAT + .compat_ioctl = ncp_compat_ioctl, +#endif .mmap = ncp_mmap, .release = ncp_release, .fsync = ncp_fsync,
fs/ncpfs/ioctl.c +239 -2
256 lines not on this page · raw message
include/linux/compat_ioctl.h +0 -12
@@ -368,18 +368,6 @@/* Raw devices */ COMPATIBLE_IOCTL(RAW_SETBIND) COMPATIBLE_IOCTL(RAW_GETBIND) -/* NCP ioctls which do not need any translations */ -COMPATIBLE_IOCTL(NCP_IOC_CONN_LOGGED_IN) -COMPATIBLE_IOCTL(NCP_IOC_SIGN_INIT) -COMPATIBLE_IOCTL(NCP_IOC_SIGN_WANTED) -COMPATIBLE_IOCTL(NCP_IOC_SET_SIGN_WANTED) -COMPATIBLE_IOCTL(NCP_IOC_LOCKUNLOCK) -COMPATIBLE_IOCTL(NCP_IOC_GETROOT) -COMPATIBLE_IOCTL(NCP_IOC_SETROOT) -COMPATIBLE_IOCTL(NCP_IOC_GETCHARSETS) -COMPATIBLE_IOCTL(NCP_IOC_SETCHARSETS) -COMPATIBLE_IOCTL(NCP_IOC_GETDENTRYTTL) -COMPATIBLE_IOCTL(NCP_IOC_SETDENTRYTTL) /* Little a */ COMPATIBLE_IOCTL(ATMSIGD_CTRL) COMPATIBLE_IOCTL(ATMARPD_CTRL)
include/linux/ncp_fs.h +1 -0
@@ -244,6 +244,7 @@/* linux/fs/ncpfs/ioctl.c */ int ncp_ioctl (struct inode *,struct file *,unsigned int ,unsigned long ); +long ncp_compat_ioctl (struct file *,unsigned int ,unsigned long );/* linux/fs/ncpfs/sock.c */ int ncp_request2(struct ncp_server *server, int function,
Re: reference: ncpfs: move ioctl32 code to fs/ncpfs/ioctl.c
Quoted 4 lines · Arnd Bergmann
Ok, I just realized that this was not using a merged ->compat_ioctl/->unlocked_ioctl function yet, but wth, here it is anyway.
Oh well, couldn't resist doing the complete patch now...
Petr, you can find the thread at http://lkml.org/lkml/2006/7/10/49
Arnd <><
reference: smbfs: simplify compat_ioctl handling
In reply to Arnd BergmannQuoted 2 lines · Arnd Bergmann
I'm also posting the two patches I made a long time ago as a reference.
This one is a how the ncpfs patch is supposed to work as well. still needs the UID16/32/64 stuff, I guess....
Arnd <><
Subject: smbfs: simplify compat_ioctl handling
smbfs already handles SMB_IOC_GETMOUNTUID with both 16 and 32 bit arguments, so the compatibility wrapper is not needed any more. The only other ioctl used in smbfs is SMB_IOC_NEWCONN, which is compatible as well.
This simply introduces a new compat_ioctl function that calls the regular smb_ioctl function.
fs/compat_ioctl.c +0 -21
@@ -331,24 +331,6 @@return err; } -static int do_smb_getmountuid (unsigned int fd,unsigned int cmd,unsigned long arg) -{ -mm_segment_t old_fs =get_fs (); -__kernel_uid_t kuid; -int err; - - cmd =SMB_IOC_GETMOUNTUID ; - -set_fs (KERNEL_DS ); - err =sys_ioctl (fd, cmd, (unsigned long )&kuid); -set_fs (old_fs); - -if (err >=0 ) - err =put_user (kuid, (compat_uid_t __user *)compat_ptr (arg)); - -return err; -} - static __attribute_used__ intret_einval (unsigned int fd,unsigned int cmd,unsigned long arg) {
@@ -938,9 +920,6 @@ HANDLE_IOCTL(CDROM_SEND_PACKET, cdrom_ioctl_trans)#define AUTOFS_IOC_SETTIMEOUT32 _IOWR(0x93,0x64,unsigned int)HANDLE_IOCTL (AUTOFS_IOC_SETTIMEOUT32 , ioc_settimeout) -/* One SMB ioctl needs translations. */ -#define SMB_IOC_GETMOUNTUID_32 _IOR('u', 1, compat_uid_t) -HANDLE_IOCTL (SMB_IOC_GETMOUNTUID_32 , do_smb_getmountuid) /* vfat */ HANDLE_IOCTL(VFAT_IOCTL_READDIR_BOTH32, vfat_ioctl32)HANDLE_IOCTL (VFAT_IOCTL_READDIR_SHORT32 , vfat_ioctl32)
fs/smbfs/ioctl.c +16 -0
@@ -7,6 +7,8 @@* Please add a note about your changes to smbfs in the ChangeLog file. */ +#include <linux/config.h> +#include <linux/compat.h> #include <linux/errno.h> #include <linux/fs.h> #include <linux/ioctl.h>
@@ -65,3 +67,17 @@return result; } + +#ifdef CONFIG_COMPAT +/* All three ioctl numbers above are compatible */ +long +smb_compat_ioctl (struct file *file,unsigned int cmd,unsigned long arg) +{ +int result; +lock_kernel (); + arg = (unsigned long )compat_ptr (arg); + result =smb_ioctl (file->f_dentry->d_inode, file, cmd, arg); +unlock_kernel (); +return result; +} +#endif
include/linux/compat_ioctl.h +0 -2
@@ -379,8 +379,6 @@/* Raw devices */ COMPATIBLE_IOCTL(RAW_SETBIND) COMPATIBLE_IOCTL(RAW_GETBIND) -/* SMB ioctls which do not need any translations */ -COMPATIBLE_IOCTL(SMB_IOC_NEWCONN) /* NCP ioctls which do not need any translations */ COMPATIBLE_IOCTL(NCP_IOC_CONN_LOGGED_IN) COMPATIBLE_IOCTL(NCP_IOC_SIGN_INIT)
fs/smbfs/file.c +4 -0
@@ -7,6 +7,7 @@* Please add a note about your changes to smbfs in the ChangeLog file. */ +#include <linux/config.h> #include <linux/time.h> #include <linux/kernel.h> #include <linux/errno.h>
@@ -408,6 +409,9 @@ .read = smb_file_read, .write = smb_file_write, .ioctl = smb_ioctl, +#ifdef CONFIG_COMPAT + .compat_ioctl = smb_compat_ioctl, +#endif .mmap = smb_file_mmap, .open = smb_file_open, .release = smb_file_release,
fs/smbfs/proto.h +1 -0
@@ -68,6 +68,7 @@extern struct inode_operations smb_file_inode_operations;/* ioctl.c */ extern int smb_ioctl (struct inode *inode,struct file *filp,unsigned int cmd,unsigned long arg); +extern long smb_compat_ioctl (struct file *filp,unsigned int cmd,unsigned long arg);/* smbiod.c */ extern void smbiod_wake_up (void );extern int smbiod_register_server (struct smb_sb_info *server);
fs/smbfs/dir.c +4 -0
@@ -7,6 +7,7 @@* Please add a note about your changes to smbfs in the ChangeLog file. */ +#include <linux/config.h> #include <linux/time.h> #include <linux/errno.h> #include <linux/kernel.h>
@@ -39,6 +40,9 @@ .read = generic_read_dir, .readdir = smb_readdir, .ioctl = smb_ioctl, +#ifdef CONFIG_COMPAT + .compat_ioctl = smb_compat_ioctl, +#endif .open = smb_dir_open, };
PATCH 1/1 ncpfs: move ioctl32 code to fs/ncpfs/ioctl.c
The ncp specific compat ioctls are clearly local to one file system, so the code can better live there.
This version of the patch moves everything into the generic ioctl handler and uses it for both 32 and 64 bit calls.
Petr, can you test this patch on a 64 bit system?
fs/compat_ioctl.c +0 -197
@@ -2507,193 +2507,6 @@ } } -#if defined(CONFIG_NCP_FS ) || defined(CONFIG_NCP_FS_MODULE ) -struct ncp_ioctl_request_32 { -u32 function; -u32 size; -compat_caddr_t data; -}; - -struct ncp_fs_info_v2_32 { -s32 version; -u32 mounted_uid; -u32 connection; -u32 buffer_size; - -u32 volume_number; -u32 directory_id; - -u32 dummy1; -u32 dummy2; -u32 dummy3; -}; - -struct ncp_objectname_ioctl_32 -{ -s32 auth_type; -u32 object_name_len; -compat_caddr_t object_name;/* an userspace data, in most cases user name */ -}; - -struct ncp_privatedata_ioctl_32 -{ -u32 len; -compat_caddr_t data;/* ~1000 for NDS */ -}; - -#define NCP_IOC_NCPREQUEST_32 _IOR('n', 1, struct ncp_ioctl_request_32) -#define NCP_IOC_GETMOUNTUID2_32 _IOW('n', 2, u32) -#define NCP_IOC_GET_FS_INFO_V2_32 _IOWR('n', 4, struct ncp_fs_info_v2_32) -#define NCP_IOC_GETOBJECTNAME_32 _IOWR('n', 9, struct ncp_objectname_ioctl_32) -#define NCP_IOC_SETOBJECTNAME_32 _IOR('n', 9, struct ncp_objectname_ioctl_32) -#define NCP_IOC_GETPRIVATEDATA_32 _IOWR('n', 10, struct ncp_privatedata_ioctl_32) -#define NCP_IOC_SETPRIVATEDATA_32 _IOR('n', 10, struct ncp_privatedata_ioctl_32) - -static int do_ncp_ncprequest (unsigned int fd,unsigned int cmd,unsigned long arg) -{ -struct ncp_ioctl_request_32 n32; -struct ncp_ioctl_request __user *p =compat_alloc_user_space (sizeof (*p)); - -if (copy_from_user (&n32,compat_ptr (arg),sizeof (n32)) || -put_user (n32.function, &p->function) || -put_user (n32.size, &p->size) || -put_user (compat_ptr (n32.data), &p->data)) -return -EFAULT ; - -return sys_ioctl (fd,NCP_IOC_NCPREQUEST , (unsigned long )p); -} - -static int do_ncp_getmountuid2 (unsigned int fd,unsigned int cmd,unsigned long arg) -{ -mm_segment_t old_fs =get_fs (); -__kernel_uid_t kuid; -int err; - - cmd =NCP_IOC_GETMOUNTUID2 ; - -set_fs (KERNEL_DS ); - err =sys_ioctl (fd, cmd, (unsigned long )&kuid); -set_fs (old_fs); - -if (!err) - err =put_user (kuid, - (unsigned int __user *)compat_ptr (arg)); - -return err; -} - -static int do_ncp_getfsinfo2 (unsigned int fd,unsigned int cmd,unsigned long arg) -{ -mm_segment_t old_fs =get_fs (); -struct ncp_fs_info_v2_32 n32; -struct ncp_fs_info_v2 n; -int err; - -if (copy_from_user (&n32,compat_ptr (arg),sizeof (n32))) -return -EFAULT ; -if (n32.version !=NCP_GET_FS_INFO_VERSION_V2 ) -return -EINVAL ; - n.version =NCP_GET_FS_INFO_VERSION_V2 ; - -set_fs (KERNEL_DS ); - err =sys_ioctl (fd,NCP_IOC_GET_FS_INFO_V2 , (unsigned long )&n); -set_fs (old_fs); - -if (!err) { - n32.version = n.version; - n32.mounted_uid = n.mounted_uid; - n32.connection = n.connection; - n32.buffer_size = n.buffer_size; - n32.volume_number = n.volume_number; - n32.directory_id = n.directory_id; - n32.dummy1 = n.dummy1; - n32.dummy2 = n.dummy2; - n32.dummy3 = n.dummy3; - err =copy_to_user (compat_ptr (arg), &n32,sizeof (n32)) ? -EFAULT :0 ; - } -return err; -} - -static int do_ncp_getobjectname (unsigned int fd,unsigned int cmd,unsigned long arg) -{ -struct ncp_objectname_ioctl_32 n32,__user *p32 =compat_ptr (arg); -struct ncp_objectname_ioctl __user *p =compat_alloc_user_space (sizeof (*p)); -s32 auth_type; -u32 name_len; -int err; - -if (copy_from_user (&n32, p32,sizeof (n32)) || -put_user (n32.object_name_len, &p->object_name_len) || -put_user (compat_ptr (n32.object_name), &p->object_name)) -return -EFAULT ; - - err =sys_ioctl (fd,NCP_IOC_GETOBJECTNAME , (unsigned long )p); -if (err) -return err; - -if (get_user (auth_type, &p->auth_type) || -put_user (auth_type, &p32->auth_type) || -get_user (name_len, &p->object_name_len) || -put_user (name_len, &p32->object_name_len)) -return -EFAULT ; - -return 0 ; -} - -static int do_ncp_setobjectname (unsigned int fd,unsigned int cmd,unsigned long arg) -{ -struct ncp_objectname_ioctl_32 n32,__user *p32 =compat_ptr (arg); -struct ncp_objectname_ioctl __user *p =compat_alloc_user_space (sizeof (*p)); - -if (copy_from_user (&n32, p32,sizeof (n32)) || -put_user (n32.auth_type, &p->auth_type) || -put_user (n32.object_name_len, &p->object_name_len) || -put_user (compat_ptr (n32.object_name), &p->object_name)) -return -EFAULT ; - -return sys_ioctl (fd,NCP_IOC_SETOBJECTNAME , (unsigned long )p); -} - -static int do_ncp_getprivatedata (unsigned int fd,unsigned int cmd,unsigned long arg) -{ -struct ncp_privatedata_ioctl_32 n32,__user *p32 =compat_ptr (arg); -struct ncp_privatedata_ioctl __user *p = -compat_alloc_user_space (sizeof (*p)); -u32 len; -int err; - -if (copy_from_user (&n32, p32,sizeof (n32)) || -put_user (n32.len, &p->len) || -put_user (compat_ptr (n32.data), &p->data)) -return -EFAULT ; - - err =sys_ioctl (fd,NCP_IOC_GETPRIVATEDATA , (unsigned long )p); -if (err) -return err; - -if (get_user (len, &p->len) || -put_user (len, &p32->len)) -return -EFAULT ; - -return 0 ; -} - -static int do_ncp_setprivatedata (unsigned int fd,unsigned int cmd,unsigned long arg) -{ -struct ncp_privatedata_ioctl_32 n32; -struct ncp_privatedata_ioctl_32 __user *p32 =compat_ptr (arg); -struct ncp_privatedata_ioctl __user *p = -compat_alloc_user_space (sizeof (*p)); - -if (copy_from_user (&n32, p32,sizeof (n32)) || -put_user (n32.len, &p->len) || -put_user (compat_ptr (n32.data), &p->data)) -return -EFAULT ; - -return sys_ioctl (fd,NCP_IOC_SETPRIVATEDATA , (unsigned long )p); -} -#endif -static int lp_timeout_trans (unsigned int fd,unsigned int cmd,unsigned long arg) {
@@ -2920,16 +2733,6 @@ HANDLE_IOCTL(RTC_EPOCH_READ32, rtc_ioctl)HANDLE_IOCTL (RTC_EPOCH_SET32 , rtc_ioctl) -#if defined(CONFIG_NCP_FS ) || defined(CONFIG_NCP_FS_MODULE ) -HANDLE_IOCTL(NCP_IOC_NCPREQUEST_32, do_ncp_ncprequest) -HANDLE_IOCTL(NCP_IOC_GETMOUNTUID2_32, do_ncp_getmountuid2) -HANDLE_IOCTL(NCP_IOC_GET_FS_INFO_V2_32, do_ncp_getfsinfo2) -HANDLE_IOCTL(NCP_IOC_GETOBJECTNAME_32, do_ncp_getobjectname) -HANDLE_IOCTL(NCP_IOC_SETOBJECTNAME_32, do_ncp_setobjectname) -HANDLE_IOCTL(NCP_IOC_GETPRIVATEDATA_32, do_ncp_getprivatedata) -HANDLE_IOCTL(NCP_IOC_SETPRIVATEDATA_32, do_ncp_setprivatedata) -#endif - /* dvb */ HANDLE_IOCTL(VIDEO_GET_EVENT, do_video_get_event)HANDLE_IOCTL (VIDEO_STILLPICTURE , do_video_stillpicture)
fs/ncpfs/dir.c +3 -0
@@ -53,6 +53,9 @@ .read = generic_read_dir, .readdir = ncp_readdir, .ioctl = ncp_ioctl, +#ifdef CONFIG_COMPAT + .compat_ioctl = ncp_compat_ioctl, +#endif }; struct inode_operations ncp_dir_inode_operations =
fs/ncpfs/file.c +4 -0
@@ -9,6 +9,7 @@#include <asm/uaccess.h> #include <asm/system.h> +#include <linux/config.h> #include <linux/time.h> #include <linux/kernel.h> #include <linux/errno.h>
@@ -289,6 +290,9 @@ .read = ncp_file_read, .write = ncp_file_write, .ioctl = ncp_ioctl, +#ifdef CONFIG_COMPAT + .compat_ioctl = ncp_compat_ioctl, +#endif .mmap = ncp_mmap, .release = ncp_release, .fsync = ncp_fsync,
fs/ncpfs/ioctl.c +221 -39
351 lines not on this page · raw message
include/linux/ncp_fs.h +1 -0
@@ -215,6 +215,7 @@/* linux/fs/ncpfs/ioctl.c */ int ncp_ioctl (struct inode *,struct file *,unsigned int ,unsigned long ); +long ncp_compat_ioctl (struct file *,unsigned int ,unsigned long );/* linux/fs/ncpfs/sock.c */ int ncp_request2(struct ncp_server *server, int function,
include/linux/compat_ioctl.h +0 -12
@@ -572,18 +572,6 @@ COMPATIBLE_IOCTL(RAW_GETBIND) /* SMB ioctls which do not need any translations */ COMPATIBLE_IOCTL(SMB_IOC_NEWCONN) -/* NCP ioctls which do not need any translations */ -COMPATIBLE_IOCTL(NCP_IOC_CONN_LOGGED_IN) -COMPATIBLE_IOCTL(NCP_IOC_SIGN_INIT) -COMPATIBLE_IOCTL(NCP_IOC_SIGN_WANTED) -COMPATIBLE_IOCTL(NCP_IOC_SET_SIGN_WANTED) -COMPATIBLE_IOCTL(NCP_IOC_LOCKUNLOCK) -COMPATIBLE_IOCTL(NCP_IOC_GETROOT) -COMPATIBLE_IOCTL(NCP_IOC_SETROOT) -COMPATIBLE_IOCTL(NCP_IOC_GETCHARSETS) -COMPATIBLE_IOCTL(NCP_IOC_SETCHARSETS) -COMPATIBLE_IOCTL(NCP_IOC_GETDENTRYTTL) -COMPATIBLE_IOCTL(NCP_IOC_SETDENTRYTTL) /* Little a */ COMPATIBLE_IOCTL(ATMSIGD_CTRL) COMPATIBLE_IOCTL(ATMARPD_CTRL)
Re: [PATCH] ncpfs: move ioctl32 code to fs/ncpfs/ioctl.c
[removed [email protected] - I believe it is dead...]
Quoted 8 lines · Arnd Bergmann
The ncp specific compat ioctls are clearly local to one file system, so the code can better live there.
This version of the patch moves everything into the generic ioctl handler and uses it for both 32 and 64 bit calls.
Petr, can you test this patch on a 64 bit system?
Yes, tomorrow (on amd64).
Quoted 10 lines
fs/ncpfs/ioctl.c +3
-0@@ -544,6 +691,9 @@kfree (oldname);return 0 ; } +#ifdef CONFIG_COMPAT +case NCP_IOC_GETPRIVATEDATA_32 : +#endif case NCP_IOC_GETPRIVATEDATA :if (current->uid != server->m.mounted_uid) {return -EACCES ;
...
Quoted 10 lines
fs/ncpfs/ioctl.c +4
-2@@ -562,10 +722,23 @@ server->priv.data, outl)) return -EFAULT; } -if (copy_to_user (argp, &user,sizeof (user))) -return -EFAULT ; +if (cmd ==NCP_IOC_GETPRIVATEDATA ) { +if (copy_to_user (argp, &user,sizeof (user))) +return -EFAULT ; + }else {
fs/ncpfs/ioctl.c line 738
Quoted 10 lines
fs/ncpfs/ioctl.c +8
-0+#ifdef CONFIG_COMPAT +struct compat_ncp_privatedata_ioctl user32; + user32.len = user.len; + user32.data = (unsigned long ) user.data; +if (copy_to_user (&user32, argp,sizeof (user32))) +return -EFAULT ; +#endif + }return 0 ; }
Although I understand that this code is correct, what about removing this second
#ifdef ? gcc should realize it anyway that without CONFIG_COMPAT defined cmd
must be equal to NCP_IOC_GETPRIVATEDATA, and having empty "else" variant is IMHO just asking for troubles. Or what about
#ifdef CONFIG_COMPAT
if (cmd == NCP_IOC_GETPRIVATEDATA_32) {
struct ...
} else#endif
if (copy_to_user(argp, &user, sizeof(user)))
return -EFAULT;
Thanks,
Petr
Re: [PATCH] ncpfs: move ioctl32 code to fs/ncpfs/ioctl.c
Quoted 1 line · Petr Vandrovec
Yes, tomorrow (on amd64).
No need to hurry, I was sitting on my patch for more than a year now ;-)
Quoted 4 lines
Although I understand that this code is correct, what about removing this second #ifdef ? gcc should realize it anyway that without
CONFIG_COMPATdefined cmd must be equal toNCP_IOC_GETPRIVATEDATA, and having empty "else" variant is IMHO just asking for troubles.
That was what I did first, but unfortunately we don't define compat_caddr_t when CONFIG_COMPAT is disabled, so it would reference an invalid data structure.
Quoted 9 lines
Or what about
#ifdef
CONFIG_COMPAT
if (cmd ==NCP_IOC_GETPRIVATEDATA_32) {
struct ...
} else
#endif
if (copy_to_user(argp, &user, sizeof(user)))
return-EFAULT;
Yes, that should be clearer than my approach.
Arnd <><
Re: [PATCH] ncpfs: move ioctl32 code to fs/ncpfs/ioctl.c
Quoted 4 lines · Arnd Bergmann
Quoted 1 line · Petr Vandrovec
Yes, tomorrow (on amd64).
No need to hurry, I was sitting on my patch for more than a year now ;-)
Seems to work, both natively 64bit and also through compat layer.
Quoted 11 lines
Quoted 9 lines
Or what about
#ifdef
CONFIG_COMPAT
if (cmd ==NCP_IOC_GETPRIVATEDATA_32) {
struct ...
} else
#endif
if (copy_to_user(argp, &user, sizeof(user)))
return-EFAULT;Yes, that should be clearer than my approach.
I've updated your diff as outlined above, and I've removed ncp_fs.h include from compat_ioctl, as it is not needed anymore. I've also removed one #include <linux/config.h> you introduced...
Thanks,
Petr
Quoted 1 line
From Arnd Bergmann <[email protected]>
The ncp specific compat ioctls are clearly local to one file system, so the code can better live there.
fs/compat_ioctl.c +0 -198
@@ -65,7 +65,6 @@#include <linux/ctype.h> #include <linux/ioctl32.h> #include <linux/syscalls.h> -#include <linux/ncp_fs.h> #include <linux/i2c.h> #include <linux/i2c-dev.h> #include <linux/wireless.h>
@@ -2507,193 +2506,6 @@ static int rtc_ioctl(unsigned fd, unsign } } -#if defined(CONFIG_NCP_FS ) || defined(CONFIG_NCP_FS_MODULE ) -struct ncp_ioctl_request_32 { -u32 function; -u32 size; -compat_caddr_t data; -}; - -struct ncp_fs_info_v2_32 { -s32 version; -u32 mounted_uid; -u32 connection; -u32 buffer_size; - -u32 volume_number; -u32 directory_id; - -u32 dummy1; -u32 dummy2; -u32 dummy3; -}; - -struct ncp_objectname_ioctl_32 -{ -s32 auth_type; -u32 object_name_len; -compat_caddr_t object_name;/* an userspace data, in most cases user name */ -}; - -struct ncp_privatedata_ioctl_32 -{ -u32 len; -compat_caddr_t data;/* ~1000 for NDS */ -}; - -#define NCP_IOC_NCPREQUEST_32 _IOR('n', 1, struct ncp_ioctl_request_32) -#define NCP_IOC_GETMOUNTUID2_32 _IOW('n', 2, u32) -#define NCP_IOC_GET_FS_INFO_V2_32 _IOWR('n', 4, struct ncp_fs_info_v2_32) -#define NCP_IOC_GETOBJECTNAME_32 _IOWR('n', 9, struct ncp_objectname_ioctl_32) -#define NCP_IOC_SETOBJECTNAME_32 _IOR('n', 9, struct ncp_objectname_ioctl_32) -#define NCP_IOC_GETPRIVATEDATA_32 _IOWR('n', 10, struct ncp_privatedata_ioctl_32) -#define NCP_IOC_SETPRIVATEDATA_32 _IOR('n', 10, struct ncp_privatedata_ioctl_32) - -static int do_ncp_ncprequest (unsigned int fd,unsigned int cmd,unsigned long arg) -{ -struct ncp_ioctl_request_32 n32; -struct ncp_ioctl_request __user *p =compat_alloc_user_space (sizeof (*p)); - -if (copy_from_user (&n32,compat_ptr (arg),sizeof (n32)) || -put_user (n32.function, &p->function) || -put_user (n32.size, &p->size) || -put_user (compat_ptr (n32.data), &p->data)) -return -EFAULT ; - -return sys_ioctl (fd,NCP_IOC_NCPREQUEST , (unsigned long )p); -} - -static int do_ncp_getmountuid2 (unsigned int fd,unsigned int cmd,unsigned long arg) -{ -mm_segment_t old_fs =get_fs (); -__kernel_uid_t kuid; -int err; - - cmd =NCP_IOC_GETMOUNTUID2 ; - -set_fs (KERNEL_DS ); - err =sys_ioctl (fd, cmd, (unsigned long )&kuid); -set_fs (old_fs); - -if (!err) - err =put_user (kuid, - (unsigned int __user *)compat_ptr (arg)); - -return err; -} - -static int do_ncp_getfsinfo2 (unsigned int fd,unsigned int cmd,unsigned long arg) -{ -mm_segment_t old_fs =get_fs (); -struct ncp_fs_info_v2_32 n32; -struct ncp_fs_info_v2 n; -int err; - -if (copy_from_user (&n32,compat_ptr (arg),sizeof (n32))) -return -EFAULT ; -if (n32.version !=NCP_GET_FS_INFO_VERSION_V2 ) -return -EINVAL ; - n.version =NCP_GET_FS_INFO_VERSION_V2 ; - -set_fs (KERNEL_DS ); - err =sys_ioctl (fd,NCP_IOC_GET_FS_INFO_V2 , (unsigned long )&n); -set_fs (old_fs); - -if (!err) { - n32.version = n.version; - n32.mounted_uid = n.mounted_uid; - n32.connection = n.connection; - n32.buffer_size = n.buffer_size; - n32.volume_number = n.volume_number; - n32.directory_id = n.directory_id; - n32.dummy1 = n.dummy1; - n32.dummy2 = n.dummy2; - n32.dummy3 = n.dummy3; - err =copy_to_user (compat_ptr (arg), &n32,sizeof (n32)) ? -EFAULT :0 ; - } -return err; -} - -static int do_ncp_getobjectname (unsigned int fd,unsigned int cmd,unsigned long arg) -{ -struct ncp_objectname_ioctl_32 n32,__user *p32 =compat_ptr (arg); -struct ncp_objectname_ioctl __user *p =compat_alloc_user_space (sizeof (*p)); -s32 auth_type; -u32 name_len; -int err; - -if (copy_from_user (&n32, p32,sizeof (n32)) || -put_user (n32.object_name_len, &p->object_name_len) || -put_user (compat_ptr (n32.object_name), &p->object_name)) -return -EFAULT ; - - err =sys_ioctl (fd,NCP_IOC_GETOBJECTNAME , (unsigned long )p); -if (err) -return err; - -if (get_user (auth_type, &p->auth_type) || -put_user (auth_type, &p32->auth_type) || -get_user (name_len, &p->object_name_len) || -put_user (name_len, &p32->object_name_len)) -return -EFAULT ; - -return 0 ; -} - -static int do_ncp_setobjectname (unsigned int fd,unsigned int cmd,unsigned long arg) -{ -struct ncp_objectname_ioctl_32 n32,__user *p32 =compat_ptr (arg); -struct ncp_objectname_ioctl __user *p =compat_alloc_user_space (sizeof (*p)); - -if (copy_from_user (&n32, p32,sizeof (n32)) || -put_user (n32.auth_type, &p->auth_type) || -put_user (n32.object_name_len, &p->object_name_len) || -put_user (compat_ptr (n32.object_name), &p->object_name)) -return -EFAULT ; - -return sys_ioctl (fd,NCP_IOC_SETOBJECTNAME , (unsigned long )p); -} - -static int do_ncp_getprivatedata (unsigned int fd,unsigned int cmd,unsigned long arg) -{ -struct ncp_privatedata_ioctl_32 n32,__user *p32 =compat_ptr (arg); -struct ncp_privatedata_ioctl __user *p = -compat_alloc_user_space (sizeof (*p)); -u32 len; -int err; - -if (copy_from_user (&n32, p32,sizeof (n32)) || -put_user (n32.len, &p->len) || -put_user (compat_ptr (n32.data), &p->data)) -return -EFAULT ; - - err =sys_ioctl (fd,NCP_IOC_GETPRIVATEDATA , (unsigned long )p); -if (err) -return err; - -if (get_user (len, &p->len) || -put_user (len, &p32->len)) -return -EFAULT ; - -return 0 ; -} - -static int do_ncp_setprivatedata (unsigned int fd,unsigned int cmd,unsigned long arg) -{ -struct ncp_privatedata_ioctl_32 n32; -struct ncp_privatedata_ioctl_32 __user *p32 =compat_ptr (arg); -struct ncp_privatedata_ioctl __user *p = -compat_alloc_user_space (sizeof (*p)); - -if (copy_from_user (&n32, p32,sizeof (n32)) || -put_user (n32.len, &p->len) || -put_user (compat_ptr (n32.data), &p->data)) -return -EFAULT ; - -return sys_ioctl (fd,NCP_IOC_SETPRIVATEDATA , (unsigned long )p); -} -#endif -static int lp_timeout_trans (unsigned int fd,unsigned int cmd,unsigned long arg) {
@@ -2920,16 +2732,6 @@ HANDLE_IOCTL(RTC_IRQP_SET32, rtc_ioctl) HANDLE_IOCTL(RTC_EPOCH_READ32, rtc_ioctl)HANDLE_IOCTL (RTC_EPOCH_SET32 , rtc_ioctl) -#if defined(CONFIG_NCP_FS ) || defined(CONFIG_NCP_FS_MODULE ) -HANDLE_IOCTL(NCP_IOC_NCPREQUEST_32, do_ncp_ncprequest) -HANDLE_IOCTL(NCP_IOC_GETMOUNTUID2_32, do_ncp_getmountuid2) -HANDLE_IOCTL(NCP_IOC_GET_FS_INFO_V2_32, do_ncp_getfsinfo2) -HANDLE_IOCTL(NCP_IOC_GETOBJECTNAME_32, do_ncp_getobjectname) -HANDLE_IOCTL(NCP_IOC_SETOBJECTNAME_32, do_ncp_setobjectname) -HANDLE_IOCTL(NCP_IOC_GETPRIVATEDATA_32, do_ncp_getprivatedata) -HANDLE_IOCTL(NCP_IOC_SETPRIVATEDATA_32, do_ncp_setprivatedata) -#endif - /* dvb */ HANDLE_IOCTL(VIDEO_GET_EVENT, do_video_get_event)HANDLE_IOCTL (VIDEO_STILLPICTURE , do_video_stillpicture)
fs/ncpfs/dir.c +3 -0
@@ -53,6 +53,9 @@ const struct file_operations ncp_dir_ope .read = generic_read_dir, .readdir = ncp_readdir, .ioctl = ncp_ioctl, +#ifdef CONFIG_COMPAT + .compat_ioctl = ncp_compat_ioctl, +#endif }; struct inode_operations ncp_dir_inode_operations =
fs/ncpfs/file.c +3 -0
@@ -289,6 +289,9 @@ const struct file_operations ncp_file_op .read = ncp_file_read, .write = ncp_file_write, .ioctl = ncp_ioctl, +#ifdef CONFIG_COMPAT + .compat_ioctl = ncp_compat_ioctl, +#endif .mmap = ncp_mmap, .release = ncp_release, .fsync = ncp_fsync,
fs/ncpfs/ioctl.c +210 -29
338 lines not on this page · raw message
include/linux/compat_ioctl.h +0 -12
@@ -572,18 +572,6 @@ COMPATIBLE_IOCTL(RAW_SETBIND) COMPATIBLE_IOCTL(RAW_GETBIND) /* SMB ioctls which do not need any translations */ COMPATIBLE_IOCTL(SMB_IOC_NEWCONN) -/* NCP ioctls which do not need any translations */ -COMPATIBLE_IOCTL(NCP_IOC_CONN_LOGGED_IN) -COMPATIBLE_IOCTL(NCP_IOC_SIGN_INIT) -COMPATIBLE_IOCTL(NCP_IOC_SIGN_WANTED) -COMPATIBLE_IOCTL(NCP_IOC_SET_SIGN_WANTED) -COMPATIBLE_IOCTL(NCP_IOC_LOCKUNLOCK) -COMPATIBLE_IOCTL(NCP_IOC_GETROOT) -COMPATIBLE_IOCTL(NCP_IOC_SETROOT) -COMPATIBLE_IOCTL(NCP_IOC_GETCHARSETS) -COMPATIBLE_IOCTL(NCP_IOC_SETCHARSETS) -COMPATIBLE_IOCTL(NCP_IOC_GETDENTRYTTL) -COMPATIBLE_IOCTL(NCP_IOC_SETDENTRYTTL) /* Little a */ COMPATIBLE_IOCTL(ATMSIGD_CTRL) COMPATIBLE_IOCTL(ATMARPD_CTRL)
include/linux/ncp_fs.h +1 -0
@@ -215,6 +215,7 @@ void ncp_date_unix2dos(int unix_date, __/* linux/fs/ncpfs/ioctl.c */ int ncp_ioctl (struct inode *,struct file *,unsigned int ,unsigned long ); +long ncp_compat_ioctl (struct file *,unsigned int ,unsigned long );/* linux/fs/ncpfs/sock.c */ int ncp_request2(struct ncp_server *server, int function,
Re: [PATCH] ncpfs: move ioctl32 code to fs/ncpfs/ioctl.c
Quoted 3 lines · Petr Vandrovec
I've updated your diff as outlined above, and I've removed
ncp_fs.hinclude fromcompat_ioctl, as it is not needed anymore. I've also removed one #include <linux/config.h> you introduced...
Ok, great! Are you pushing this for 2.6.19?
Arnd <><
Quoted 10 lines · Arnd Bergmann
Quoted 9 lines · Heiko Carstens
"Only" thing is that we unfortunately have different sizes for __kernel_old_[uid|gid]_t (16 bit on s390, 32 on s390x). I was tempted to change these just to find out that there are other users as well:
include/linux/ncp_fs.h:
?#defineNCP_IOC_GETMOUNTUID_IOW('n', 2, __kernel_old_uid_t)include/linux/smb_fs.h:
?#defineSMB_IOC_GETMOUNTUID_IOR('u', 1, __kernel_old_uid_t)
Quoted 7 lines
Quoted 2 lines
So, this is no option. Would anybody know of something to get this work? Or is this just a stupid idea?
Ok, I don't know exactly what you're talking about, but I have in the past tried to hack that area as well. It's probably a good idea to pick up my old patch and work from there, by making these two file systems understand all possible ways:
I dropped my initial patch and gave up on this. The idea of using kernel/uid16.c for compat code seems to be... not very good :)