aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPetr Vandrovec <petr@vandrovec.name>2006-10-01 02:27:55 -0400
committerLinus Torvalds <torvalds@g5.osdl.org>2006-10-01 03:39:23 -0400
commit54f67f631dfc25ca7a8b19200e34013abc974337 (patch)
tree96c481c2723e1f5f626110c9a7f1c4a07b9ee056
parent89bbc03c01f68e627a2b120963f136e2815f0d84 (diff)
[PATCH] Move ncpfs 32bit compat ioctl to ncpfs
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. Signed-off-by: Arnd Bergmann <arnd@arndb.de> Signed-off-by: Petr Vandrovec <petr@vandrovec.name> Signed-off-by: Andrew Morton <akpm@osdl.org> Signed-off-by: Linus Torvalds <torvalds@osdl.org>
-rw-r--r--fs/compat_ioctl.c198
-rw-r--r--fs/ncpfs/dir.c3
-rw-r--r--fs/ncpfs/file.c3
-rw-r--r--fs/ncpfs/ioctl.c239
-rw-r--r--include/linux/compat_ioctl.h12
-rw-r--r--include/linux/ncp_fs.h1
6 files changed, 217 insertions, 239 deletions
diff --git a/fs/compat_ioctl.c b/fs/compat_ioctl.c
index 64b34533edea..27ca1aa30562 100644
--- a/fs/compat_ioctl.c
+++ b/fs/compat_ioctl.c
@@ -60,7 +60,6 @@
60#include <linux/ctype.h> 60#include <linux/ctype.h>
61#include <linux/ioctl32.h> 61#include <linux/ioctl32.h>
62#include <linux/syscalls.h> 62#include <linux/syscalls.h>
63#include <linux/ncp_fs.h>
64#include <linux/i2c.h> 63#include <linux/i2c.h>
65#include <linux/i2c-dev.h> 64#include <linux/i2c-dev.h>
66#include <linux/wireless.h> 65#include <linux/wireless.h>
@@ -2348,193 +2347,6 @@ static int rtc_ioctl(unsigned fd, unsigned cmd, unsigned long arg)
2348 } 2347 }
2349} 2348}
2350 2349
2351#if defined(CONFIG_NCP_FS) || defined(CONFIG_NCP_FS_MODULE)
2352struct ncp_ioctl_request_32 {
2353 u32 function;
2354 u32 size;
2355 compat_caddr_t data;
2356};
2357
2358struct ncp_fs_info_v2_32 {
2359 s32 version;
2360 u32 mounted_uid;
2361 u32 connection;
2362 u32 buffer_size;
2363
2364 u32 volume_number;
2365 u32 directory_id;
2366
2367 u32 dummy1;
2368 u32 dummy2;
2369 u32 dummy3;
2370};
2371
2372struct ncp_objectname_ioctl_32
2373{
2374 s32 auth_type;
2375 u32 object_name_len;
2376 compat_caddr_t object_name; /* an userspace data, in most cases user name */
2377};
2378
2379struct ncp_privatedata_ioctl_32
2380{
2381 u32 len;
2382 compat_caddr_t data; /* ~1000 for NDS */
2383};
2384
2385#define NCP_IOC_NCPREQUEST_32 _IOR('n', 1, struct ncp_ioctl_request_32)
2386#define NCP_IOC_GETMOUNTUID2_32 _IOW('n', 2, u32)
2387#define NCP_IOC_GET_FS_INFO_V2_32 _IOWR('n', 4, struct ncp_fs_info_v2_32)
2388#define NCP_IOC_GETOBJECTNAME_32 _IOWR('n', 9, struct ncp_objectname_ioctl_32)
2389#define NCP_IOC_SETOBJECTNAME_32 _IOR('n', 9, struct ncp_objectname_ioctl_32)
2390#define NCP_IOC_GETPRIVATEDATA_32 _IOWR('n', 10, struct ncp_privatedata_ioctl_32)
2391#define NCP_IOC_SETPRIVATEDATA_32 _IOR('n', 10, struct ncp_privatedata_ioctl_32)
2392
2393static int do_ncp_ncprequest(unsigned int fd, unsigned int cmd, unsigned long arg)
2394{
2395 struct ncp_ioctl_request_32 n32;
2396 struct ncp_ioctl_request __user *p = compat_alloc_user_space(sizeof(*p));
2397
2398 if (copy_from_user(&n32, compat_ptr(arg), sizeof(n32)) ||
2399 put_user(n32.function, &p->function) ||
2400 put_user(n32.size, &p->size) ||
2401 put_user(compat_ptr(n32.data), &p->data))
2402 return -EFAULT;
2403
2404 return sys_ioctl(fd, NCP_IOC_NCPREQUEST, (unsigned long)p);
2405}
2406
2407static int do_ncp_getmountuid2(unsigned int fd, unsigned int cmd, unsigned long arg)
2408{
2409 mm_segment_t old_fs = get_fs();
2410 __kernel_uid_t kuid;
2411 int err;
2412
2413 cmd = NCP_IOC_GETMOUNTUID2;
2414
2415 set_fs(KERNEL_DS);
2416 err = sys_ioctl(fd, cmd, (unsigned long)&kuid);
2417 set_fs(old_fs);
2418
2419 if (!err)
2420 err = put_user(kuid,
2421 (unsigned int __user *) compat_ptr(arg));
2422
2423 return err;
2424}
2425
2426static int do_ncp_getfsinfo2(unsigned int fd, unsigned int cmd, unsigned long arg)
2427{
2428 mm_segment_t old_fs = get_fs();
2429 struct ncp_fs_info_v2_32 n32;
2430 struct ncp_fs_info_v2 n;
2431 int err;
2432
2433 if (copy_from_user(&n32, compat_ptr(arg), sizeof(n32)))
2434 return -EFAULT;
2435 if (n32.version != NCP_GET_FS_INFO_VERSION_V2)
2436 return -EINVAL;
2437 n.version = NCP_GET_FS_INFO_VERSION_V2;
2438
2439 set_fs(KERNEL_DS);
2440 err = sys_ioctl(fd, NCP_IOC_GET_FS_INFO_V2, (unsigned long)&n);
2441 set_fs(old_fs);
2442
2443 if (!err) {
2444 n32.version = n.version;
2445 n32.mounted_uid = n.mounted_uid;
2446 n32.connection = n.connection;
2447 n32.buffer_size = n.buffer_size;
2448 n32.volume_number = n.volume_number;
2449 n32.directory_id = n.directory_id;
2450 n32.dummy1 = n.dummy1;
2451 n32.dummy2 = n.dummy2;
2452 n32.dummy3 = n.dummy3;
2453 err = copy_to_user(compat_ptr(arg), &n32, sizeof(n32)) ? -EFAULT : 0;
2454 }
2455 return err;
2456}
2457
2458static int do_ncp_getobjectname(unsigned int fd, unsigned int cmd, unsigned long arg)
2459{
2460 struct ncp_objectname_ioctl_32 n32, __user *p32 = compat_ptr(arg);
2461 struct ncp_objectname_ioctl __user *p = compat_alloc_user_space(sizeof(*p));
2462 s32 auth_type;
2463 u32 name_len;
2464 int err;
2465
2466 if (copy_from_user(&n32, p32, sizeof(n32)) ||
2467 put_user(n32.object_name_len, &p->object_name_len) ||
2468 put_user(compat_ptr(n32.object_name), &p->object_name))
2469 return -EFAULT;
2470
2471 err = sys_ioctl(fd, NCP_IOC_GETOBJECTNAME, (unsigned long)p);
2472 if (err)
2473 return err;
2474
2475 if (get_user(auth_type, &p->auth_type) ||
2476 put_user(auth_type, &p32->auth_type) ||
2477 get_user(name_len, &p->object_name_len) ||
2478 put_user(name_len, &p32->object_name_len))
2479 return -EFAULT;
2480
2481 return 0;
2482}
2483
2484static int do_ncp_setobjectname(unsigned int fd, unsigned int cmd, unsigned long arg)
2485{
2486 struct ncp_objectname_ioctl_32 n32, __user *p32 = compat_ptr(arg);
2487 struct ncp_objectname_ioctl __user *p = compat_alloc_user_space(sizeof(*p));
2488
2489 if (copy_from_user(&n32, p32, sizeof(n32)) ||
2490 put_user(n32.auth_type, &p->auth_type) ||
2491 put_user(n32.object_name_len, &p->object_name_len) ||
2492 put_user(compat_ptr(n32.object_name), &p->object_name))
2493 return -EFAULT;
2494
2495 return sys_ioctl(fd, NCP_IOC_SETOBJECTNAME, (unsigned long)p);
2496}
2497
2498static int do_ncp_getprivatedata(unsigned int fd, unsigned int cmd, unsigned long arg)
2499{
2500 struct ncp_privatedata_ioctl_32 n32, __user *p32 = compat_ptr(arg);
2501 struct ncp_privatedata_ioctl __user *p =
2502 compat_alloc_user_space(sizeof(*p));
2503 u32 len;
2504 int err;
2505
2506 if (copy_from_user(&n32, p32, sizeof(n32)) ||
2507 put_user(n32.len, &p->len) ||
2508 put_user(compat_ptr(n32.data), &p->data))
2509 return -EFAULT;
2510
2511 err = sys_ioctl(fd, NCP_IOC_GETPRIVATEDATA, (unsigned long)p);
2512 if (err)
2513 return err;
2514
2515 if (get_user(len, &p->len) ||
2516 put_user(len, &p32->len))
2517 return -EFAULT;
2518
2519 return 0;
2520}
2521
2522static int do_ncp_setprivatedata(unsigned int fd, unsigned int cmd, unsigned long arg)
2523{
2524 struct ncp_privatedata_ioctl_32 n32;
2525 struct ncp_privatedata_ioctl_32 __user *p32 = compat_ptr(arg);
2526 struct ncp_privatedata_ioctl __user *p =
2527 compat_alloc_user_space(sizeof(*p));
2528
2529 if (copy_from_user(&n32, p32, sizeof(n32)) ||
2530 put_user(n32.len, &p->len) ||
2531 put_user(compat_ptr(n32.data), &p->data))
2532 return -EFAULT;
2533
2534 return sys_ioctl(fd, NCP_IOC_SETPRIVATEDATA, (unsigned long)p);
2535}
2536#endif
2537
2538static int 2350static int
2539lp_timeout_trans(unsigned int fd, unsigned int cmd, unsigned long arg) 2351lp_timeout_trans(unsigned int fd, unsigned int cmd, unsigned long arg)
2540{ 2352{
@@ -2748,16 +2560,6 @@ HANDLE_IOCTL(RTC_IRQP_SET32, rtc_ioctl)
2748HANDLE_IOCTL(RTC_EPOCH_READ32, rtc_ioctl) 2560HANDLE_IOCTL(RTC_EPOCH_READ32, rtc_ioctl)
2749HANDLE_IOCTL(RTC_EPOCH_SET32, rtc_ioctl) 2561HANDLE_IOCTL(RTC_EPOCH_SET32, rtc_ioctl)
2750 2562
2751#if defined(CONFIG_NCP_FS) || defined(CONFIG_NCP_FS_MODULE)
2752HANDLE_IOCTL(NCP_IOC_NCPREQUEST_32, do_ncp_ncprequest)
2753HANDLE_IOCTL(NCP_IOC_GETMOUNTUID2_32, do_ncp_getmountuid2)
2754HANDLE_IOCTL(NCP_IOC_GET_FS_INFO_V2_32, do_ncp_getfsinfo2)
2755HANDLE_IOCTL(NCP_IOC_GETOBJECTNAME_32, do_ncp_getobjectname)
2756HANDLE_IOCTL(NCP_IOC_SETOBJECTNAME_32, do_ncp_setobjectname)
2757HANDLE_IOCTL(NCP_IOC_GETPRIVATEDATA_32, do_ncp_getprivatedata)
2758HANDLE_IOCTL(NCP_IOC_SETPRIVATEDATA_32, do_ncp_setprivatedata)
2759#endif
2760
2761/* dvb */ 2563/* dvb */
2762HANDLE_IOCTL(VIDEO_GET_EVENT, do_video_get_event) 2564HANDLE_IOCTL(VIDEO_GET_EVENT, do_video_get_event)
2763HANDLE_IOCTL(VIDEO_STILLPICTURE, do_video_stillpicture) 2565HANDLE_IOCTL(VIDEO_STILLPICTURE, do_video_stillpicture)
diff --git a/fs/ncpfs/dir.c b/fs/ncpfs/dir.c
index b4ee89250e95..458b3b785194 100644
--- a/fs/ncpfs/dir.c
+++ b/fs/ncpfs/dir.c
@@ -53,6 +53,9 @@ const struct file_operations ncp_dir_operations =
53 .read = generic_read_dir, 53 .read = generic_read_dir,
54 .readdir = ncp_readdir, 54 .readdir = ncp_readdir,
55 .ioctl = ncp_ioctl, 55 .ioctl = ncp_ioctl,
56#ifdef CONFIG_COMPAT
57 .compat_ioctl = ncp_compat_ioctl,
58#endif
56}; 59};
57 60
58struct inode_operations ncp_dir_inode_operations = 61struct inode_operations ncp_dir_inode_operations =
diff --git a/fs/ncpfs/file.c b/fs/ncpfs/file.c
index e6b7c67cf057..df37524b85db 100644
--- a/fs/ncpfs/file.c
+++ b/fs/ncpfs/file.c
@@ -289,6 +289,9 @@ const struct file_operations ncp_file_operations =
289 .read = ncp_file_read, 289 .read = ncp_file_read,
290 .write = ncp_file_write, 290 .write = ncp_file_write,
291 .ioctl = ncp_ioctl, 291 .ioctl = ncp_ioctl,
292#ifdef CONFIG_COMPAT
293 .compat_ioctl = ncp_compat_ioctl,
294#endif
292 .mmap = ncp_mmap, 295 .mmap = ncp_mmap,
293 .release = ncp_release, 296 .release = ncp_release,
294 .fsync = ncp_fsync, 297 .fsync = ncp_fsync,
diff --git a/fs/ncpfs/ioctl.c b/fs/ncpfs/ioctl.c
index 42039fe0653c..a89ac84a8241 100644
--- a/fs/ncpfs/ioctl.c
+++ b/fs/ncpfs/ioctl.c
@@ -7,19 +7,21 @@
7 * 7 *
8 */ 8 */
9 9
10
11#include <asm/uaccess.h>
12#include <linux/capability.h> 10#include <linux/capability.h>
11#include <linux/compat.h>
13#include <linux/errno.h> 12#include <linux/errno.h>
14#include <linux/fs.h> 13#include <linux/fs.h>
15#include <linux/ioctl.h> 14#include <linux/ioctl.h>
16#include <linux/time.h> 15#include <linux/time.h>
17#include <linux/mm.h> 16#include <linux/mm.h>
18#include <linux/highuid.h> 17#include <linux/highuid.h>
18#include <linux/smp_lock.h>
19#include <linux/vmalloc.h> 19#include <linux/vmalloc.h>
20 20
21#include <linux/ncp_fs.h> 21#include <linux/ncp_fs.h>
22 22
23#include <asm/uaccess.h>
24
23#include "ncplib_kernel.h" 25#include "ncplib_kernel.h"
24 26
25/* maximum limit for ncp_objectname_ioctl */ 27/* maximum limit for ncp_objectname_ioctl */
@@ -89,6 +91,82 @@ ncp_get_fs_info_v2(struct ncp_server * server, struct file *file,
89 return 0; 91 return 0;
90} 92}
91 93
94#ifdef CONFIG_COMPAT
95struct compat_ncp_objectname_ioctl
96{
97 s32 auth_type;
98 u32 object_name_len;
99 compat_caddr_t object_name; /* an userspace data, in most cases user name */
100};
101
102struct compat_ncp_fs_info_v2 {
103 s32 version;
104 u32 mounted_uid;
105 u32 connection;
106 u32 buffer_size;
107
108 u32 volume_number;
109 u32 directory_id;
110
111 u32 dummy1;
112 u32 dummy2;
113 u32 dummy3;
114};
115
116struct compat_ncp_ioctl_request {
117 u32 function;
118 u32 size;
119 compat_caddr_t data;
120};
121
122struct compat_ncp_privatedata_ioctl
123{
124 u32 len;
125 compat_caddr_t data; /* ~1000 for NDS */
126};
127
128#define NCP_IOC_GET_FS_INFO_V2_32 _IOWR('n', 4, struct compat_ncp_fs_info_v2)
129#define NCP_IOC_NCPREQUEST_32 _IOR('n', 1, struct compat_ncp_ioctl_request)
130#define NCP_IOC_GETOBJECTNAME_32 _IOWR('n', 9, struct compat_ncp_objectname_ioctl)
131#define NCP_IOC_SETOBJECTNAME_32 _IOR('n', 9, struct compat_ncp_objectname_ioctl)
132#define NCP_IOC_GETPRIVATEDATA_32 _IOWR('n', 10, struct compat_ncp_privatedata_ioctl)
133#define NCP_IOC_SETPRIVATEDATA_32 _IOR('n', 10, struct compat_ncp_privatedata_ioctl)
134
135static int
136ncp_get_compat_fs_info_v2(struct ncp_server * server, struct file *file,
137 struct compat_ncp_fs_info_v2 __user * arg)
138{
139 struct inode *inode = file->f_dentry->d_inode;
140 struct compat_ncp_fs_info_v2 info2;
141
142 if ((file_permission(file, MAY_WRITE) != 0)
143 && (current->uid != server->m.mounted_uid)) {
144 return -EACCES;
145 }
146 if (copy_from_user(&info2, arg, sizeof(info2)))
147 return -EFAULT;
148
149 if (info2.version != NCP_GET_FS_INFO_VERSION_V2) {
150 DPRINTK("info.version invalid: %d\n", info2.version);
151 return -EINVAL;
152 }
153 info2.mounted_uid = server->m.mounted_uid;
154 info2.connection = server->connection;
155 info2.buffer_size = server->buffer_size;
156 info2.volume_number = NCP_FINFO(inode)->volNumber;
157 info2.directory_id = NCP_FINFO(inode)->DosDirNum;
158 info2.dummy1 = info2.dummy2 = info2.dummy3 = 0;
159
160 if (copy_to_user(arg, &info2, sizeof(info2)))
161 return -EFAULT;
162 return 0;
163}
164#endif
165
166#define NCP_IOC_GETMOUNTUID16 _IOW('n', 2, u16)
167#define NCP_IOC_GETMOUNTUID32 _IOW('n', 2, u32)
168#define NCP_IOC_GETMOUNTUID64 _IOW('n', 2, u64)
169
92#ifdef CONFIG_NCPFS_NLS 170#ifdef CONFIG_NCPFS_NLS
93/* Here we are select the iocharset and the codepage for NLS. 171/* Here we are select the iocharset and the codepage for NLS.
94 * Thanks Petr Vandrovec for idea and many hints. 172 * Thanks Petr Vandrovec for idea and many hints.
@@ -192,12 +270,24 @@ int ncp_ioctl(struct inode *inode, struct file *filp,
192 void __user *argp = (void __user *)arg; 270 void __user *argp = (void __user *)arg;
193 271
194 switch (cmd) { 272 switch (cmd) {
273#ifdef CONFIG_COMPAT
274 case NCP_IOC_NCPREQUEST_32:
275#endif
195 case NCP_IOC_NCPREQUEST: 276 case NCP_IOC_NCPREQUEST:
196
197 if ((file_permission(filp, MAY_WRITE) != 0) 277 if ((file_permission(filp, MAY_WRITE) != 0)
198 && (current->uid != server->m.mounted_uid)) { 278 && (current->uid != server->m.mounted_uid)) {
199 return -EACCES; 279 return -EACCES;
200 } 280 }
281#ifdef CONFIG_COMPAT
282 if (cmd == NCP_IOC_NCPREQUEST_32) {
283 struct compat_ncp_ioctl_request request32;
284 if (copy_from_user(&request32, argp, sizeof(request32)))
285 return -EFAULT;
286 request.function = request32.function;
287 request.size = request32.size;
288 request.data = compat_ptr(request32.data);
289 } else
290#endif
201 if (copy_from_user(&request, argp, sizeof(request))) 291 if (copy_from_user(&request, argp, sizeof(request)))
202 return -EFAULT; 292 return -EFAULT;
203 293
@@ -254,19 +344,35 @@ int ncp_ioctl(struct inode *inode, struct file *filp,
254 case NCP_IOC_GET_FS_INFO_V2: 344 case NCP_IOC_GET_FS_INFO_V2:
255 return ncp_get_fs_info_v2(server, filp, argp); 345 return ncp_get_fs_info_v2(server, filp, argp);
256 346
257 case NCP_IOC_GETMOUNTUID2: 347#ifdef CONFIG_COMPAT
258 { 348 case NCP_IOC_GET_FS_INFO_V2_32:
259 unsigned long tmp = server->m.mounted_uid; 349 return ncp_get_compat_fs_info_v2(server, filp, argp);
260 350#endif
261 if ((file_permission(filp, MAY_READ) != 0) 351 /* we have too many combinations of CONFIG_COMPAT,
262 && (current->uid != server->m.mounted_uid)) 352 * CONFIG_64BIT and CONFIG_UID16, so just handle
263 { 353 * any of the possible ioctls */
264 return -EACCES; 354 case NCP_IOC_GETMOUNTUID16:
265 } 355 case NCP_IOC_GETMOUNTUID32:
266 if (put_user(tmp, (unsigned long __user *)argp)) 356 case NCP_IOC_GETMOUNTUID64:
357 if ((file_permission(filp, MAY_READ) != 0)
358 && (current->uid != server->m.mounted_uid)) {
359 return -EACCES;
360 }
361 if (cmd == NCP_IOC_GETMOUNTUID16) {
362 u16 uid;
363 SET_UID(uid, server->m.mounted_uid);
364 if (put_user(uid, (u16 __user *)argp))
365 return -EFAULT;
366 } else if (cmd == NCP_IOC_GETMOUNTUID32) {
367 if (put_user(server->m.mounted_uid,
368 (u32 __user *)argp))
369 return -EFAULT;
370 } else {
371 if (put_user(server->m.mounted_uid,
372 (u64 __user *)argp))
267 return -EFAULT; 373 return -EFAULT;
268 return 0;
269 } 374 }
375 return 0;
270 376
271 case NCP_IOC_GETROOT: 377 case NCP_IOC_GETROOT:
272 { 378 {
@@ -476,6 +582,32 @@ outrel:
476 } 582 }
477#endif /* CONFIG_NCPFS_IOCTL_LOCKING */ 583#endif /* CONFIG_NCPFS_IOCTL_LOCKING */
478 584
585#ifdef CONFIG_COMPAT
586 case NCP_IOC_GETOBJECTNAME_32:
587 if (current->uid != server->m.mounted_uid) {
588 return -EACCES;
589 }
590 {
591 struct compat_ncp_objectname_ioctl user;
592 size_t outl;
593
594 if (copy_from_user(&user, argp, sizeof(user)))
595 return -EFAULT;
596 user.auth_type = server->auth.auth_type;
597 outl = user.object_name_len;
598 user.object_name_len = server->auth.object_name_len;
599 if (outl > user.object_name_len)
600 outl = user.object_name_len;
601 if (outl) {
602 if (copy_to_user(compat_ptr(user.object_name),
603 server->auth.object_name,
604 outl)) return -EFAULT;
605 }
606 if (copy_to_user(argp, &user, sizeof(user)))
607 return -EFAULT;
608 return 0;
609 }
610#endif
479 case NCP_IOC_GETOBJECTNAME: 611 case NCP_IOC_GETOBJECTNAME:
480 if (current->uid != server->m.mounted_uid) { 612 if (current->uid != server->m.mounted_uid) {
481 return -EACCES; 613 return -EACCES;
@@ -500,6 +632,9 @@ outrel:
500 return -EFAULT; 632 return -EFAULT;
501 return 0; 633 return 0;
502 } 634 }
635#ifdef CONFIG_COMPAT
636 case NCP_IOC_SETOBJECTNAME_32:
637#endif
503 case NCP_IOC_SETOBJECTNAME: 638 case NCP_IOC_SETOBJECTNAME:
504 if (current->uid != server->m.mounted_uid) { 639 if (current->uid != server->m.mounted_uid) {
505 return -EACCES; 640 return -EACCES;
@@ -512,8 +647,19 @@ outrel:
512 void* oldprivate; 647 void* oldprivate;
513 size_t oldprivatelen; 648 size_t oldprivatelen;
514 649
650#ifdef CONFIG_COMPAT
651 if (cmd == NCP_IOC_SETOBJECTNAME_32) {
652 struct compat_ncp_objectname_ioctl user32;
653 if (copy_from_user(&user32, argp, sizeof(user32)))
654 return -EFAULT;
655 user.auth_type = user32.auth_type;
656 user.object_name_len = user32.object_name_len;
657 user.object_name = compat_ptr(user32.object_name);
658 } else
659#endif
515 if (copy_from_user(&user, argp, sizeof(user))) 660 if (copy_from_user(&user, argp, sizeof(user)))
516 return -EFAULT; 661 return -EFAULT;
662
517 if (user.object_name_len > NCP_OBJECT_NAME_MAX_LEN) 663 if (user.object_name_len > NCP_OBJECT_NAME_MAX_LEN)
518 return -ENOMEM; 664 return -ENOMEM;
519 if (user.object_name_len) { 665 if (user.object_name_len) {
@@ -544,6 +690,9 @@ outrel:
544 kfree(oldname); 690 kfree(oldname);
545 return 0; 691 return 0;
546 } 692 }
693#ifdef CONFIG_COMPAT
694 case NCP_IOC_GETPRIVATEDATA_32:
695#endif
547 case NCP_IOC_GETPRIVATEDATA: 696 case NCP_IOC_GETPRIVATEDATA:
548 if (current->uid != server->m.mounted_uid) { 697 if (current->uid != server->m.mounted_uid) {
549 return -EACCES; 698 return -EACCES;
@@ -552,8 +701,18 @@ outrel:
552 struct ncp_privatedata_ioctl user; 701 struct ncp_privatedata_ioctl user;
553 size_t outl; 702 size_t outl;
554 703
704#ifdef CONFIG_COMPAT
705 if (cmd == NCP_IOC_GETPRIVATEDATA_32) {
706 struct compat_ncp_privatedata_ioctl user32;
707 if (copy_from_user(&user32, argp, sizeof(user32)))
708 return -EFAULT;
709 user.len = user32.len;
710 user.data = compat_ptr(user32.data);
711 } else
712#endif
555 if (copy_from_user(&user, argp, sizeof(user))) 713 if (copy_from_user(&user, argp, sizeof(user)))
556 return -EFAULT; 714 return -EFAULT;
715
557 outl = user.len; 716 outl = user.len;
558 user.len = server->priv.len; 717 user.len = server->priv.len;
559 if (outl > user.len) outl = user.len; 718 if (outl > user.len) outl = user.len;
@@ -562,10 +721,23 @@ outrel:
562 server->priv.data, 721 server->priv.data,
563 outl)) return -EFAULT; 722 outl)) return -EFAULT;
564 } 723 }
724#ifdef CONFIG_COMPAT
725 if (cmd == NCP_IOC_GETPRIVATEDATA_32) {
726 struct compat_ncp_privatedata_ioctl user32;
727 user32.len = user.len;
728 user32.data = (unsigned long) user.data;
729 if (copy_to_user(&user32, argp, sizeof(user32)))
730 return -EFAULT;
731 } else
732#endif
565 if (copy_to_user(argp, &user, sizeof(user))) 733 if (copy_to_user(argp, &user, sizeof(user)))
566 return -EFAULT; 734 return -EFAULT;
735
567 return 0; 736 return 0;
568 } 737 }
738#ifdef CONFIG_COMPAT
739 case NCP_IOC_SETPRIVATEDATA_32:
740#endif
569 case NCP_IOC_SETPRIVATEDATA: 741 case NCP_IOC_SETPRIVATEDATA:
570 if (current->uid != server->m.mounted_uid) { 742 if (current->uid != server->m.mounted_uid) {
571 return -EACCES; 743 return -EACCES;
@@ -576,8 +748,18 @@ outrel:
576 void* old; 748 void* old;
577 size_t oldlen; 749 size_t oldlen;
578 750
751#ifdef CONFIG_COMPAT
752 if (cmd == NCP_IOC_SETPRIVATEDATA_32) {
753 struct compat_ncp_privatedata_ioctl user32;
754 if (copy_from_user(&user32, argp, sizeof(user32)))
755 return -EFAULT;
756 user.len = user32.len;
757 user.data = compat_ptr(user32.data);
758 } else
759#endif
579 if (copy_from_user(&user, argp, sizeof(user))) 760 if (copy_from_user(&user, argp, sizeof(user)))
580 return -EFAULT; 761 return -EFAULT;
762
581 if (user.len > NCP_PRIVATE_DATA_MAX_LEN) 763 if (user.len > NCP_PRIVATE_DATA_MAX_LEN)
582 return -ENOMEM; 764 return -ENOMEM;
583 if (user.len) { 765 if (user.len) {
@@ -636,20 +818,19 @@ outrel:
636 } 818 }
637 819
638 } 820 }
639/* #ifdef CONFIG_UID16 */
640 /* NCP_IOC_GETMOUNTUID may be same as NCP_IOC_GETMOUNTUID2,
641 so we have this out of switch */
642 if (cmd == NCP_IOC_GETMOUNTUID) {
643 __kernel_uid_t uid = 0;
644 if ((file_permission(filp, MAY_READ) != 0)
645 && (current->uid != server->m.mounted_uid)) {
646 return -EACCES;
647 }
648 SET_UID(uid, server->m.mounted_uid);
649 if (put_user(uid, (__kernel_uid_t __user *)argp))
650 return -EFAULT;
651 return 0;
652 }
653/* #endif */
654 return -EINVAL; 821 return -EINVAL;
655} 822}
823
824#ifdef CONFIG_COMPAT
825long ncp_compat_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
826{
827 struct inode *inode = file->f_dentry->d_inode;
828 int ret;
829
830 lock_kernel();
831 arg = (unsigned long) compat_ptr(arg);
832 ret = ncp_ioctl(inode, file, cmd, arg);
833 unlock_kernel();
834 return ret;
835}
836#endif
diff --git a/include/linux/compat_ioctl.h b/include/linux/compat_ioctl.h
index d61ef5951538..d5b7abc4f409 100644
--- a/include/linux/compat_ioctl.h
+++ b/include/linux/compat_ioctl.h
@@ -569,18 +569,6 @@ COMPATIBLE_IOCTL(RAW_SETBIND)
569COMPATIBLE_IOCTL(RAW_GETBIND) 569COMPATIBLE_IOCTL(RAW_GETBIND)
570/* SMB ioctls which do not need any translations */ 570/* SMB ioctls which do not need any translations */
571COMPATIBLE_IOCTL(SMB_IOC_NEWCONN) 571COMPATIBLE_IOCTL(SMB_IOC_NEWCONN)
572/* NCP ioctls which do not need any translations */
573COMPATIBLE_IOCTL(NCP_IOC_CONN_LOGGED_IN)
574COMPATIBLE_IOCTL(NCP_IOC_SIGN_INIT)
575COMPATIBLE_IOCTL(NCP_IOC_SIGN_WANTED)
576COMPATIBLE_IOCTL(NCP_IOC_SET_SIGN_WANTED)
577COMPATIBLE_IOCTL(NCP_IOC_LOCKUNLOCK)
578COMPATIBLE_IOCTL(NCP_IOC_GETROOT)
579COMPATIBLE_IOCTL(NCP_IOC_SETROOT)
580COMPATIBLE_IOCTL(NCP_IOC_GETCHARSETS)
581COMPATIBLE_IOCTL(NCP_IOC_SETCHARSETS)
582COMPATIBLE_IOCTL(NCP_IOC_GETDENTRYTTL)
583COMPATIBLE_IOCTL(NCP_IOC_SETDENTRYTTL)
584/* Little a */ 572/* Little a */
585COMPATIBLE_IOCTL(ATMSIGD_CTRL) 573COMPATIBLE_IOCTL(ATMSIGD_CTRL)
586COMPATIBLE_IOCTL(ATMARPD_CTRL) 574COMPATIBLE_IOCTL(ATMARPD_CTRL)
diff --git a/include/linux/ncp_fs.h b/include/linux/ncp_fs.h
index 02e352be717e..0ea7f89e613c 100644
--- a/include/linux/ncp_fs.h
+++ b/include/linux/ncp_fs.h
@@ -212,6 +212,7 @@ void ncp_date_unix2dos(int unix_date, __le16 * time, __le16 * date);
212 212
213/* linux/fs/ncpfs/ioctl.c */ 213/* linux/fs/ncpfs/ioctl.c */
214int ncp_ioctl(struct inode *, struct file *, unsigned int, unsigned long); 214int ncp_ioctl(struct inode *, struct file *, unsigned int, unsigned long);
215long ncp_compat_ioctl(struct file *, unsigned int, unsigned long);
215 216
216/* linux/fs/ncpfs/sock.c */ 217/* linux/fs/ncpfs/sock.c */
217int ncp_request2(struct ncp_server *server, int function, 218int ncp_request2(struct ncp_server *server, int function,