aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-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,