diff options
-rw-r--r-- | fs/compat_ioctl.c | 198 | ||||
-rw-r--r-- | fs/ncpfs/dir.c | 3 | ||||
-rw-r--r-- | fs/ncpfs/file.c | 3 | ||||
-rw-r--r-- | fs/ncpfs/ioctl.c | 239 | ||||
-rw-r--r-- | include/linux/compat_ioctl.h | 12 | ||||
-rw-r--r-- | include/linux/ncp_fs.h | 1 |
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) | ||
2352 | struct ncp_ioctl_request_32 { | ||
2353 | u32 function; | ||
2354 | u32 size; | ||
2355 | compat_caddr_t data; | ||
2356 | }; | ||
2357 | |||
2358 | struct 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 | |||
2372 | struct 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 | |||
2379 | struct 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 | |||
2393 | static 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 | |||
2407 | static 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 | |||
2426 | static 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 | |||
2458 | static 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 | |||
2484 | static 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 | |||
2498 | static 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 | |||
2522 | static 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 | |||
2538 | static int | 2350 | static int |
2539 | lp_timeout_trans(unsigned int fd, unsigned int cmd, unsigned long arg) | 2351 | lp_timeout_trans(unsigned int fd, unsigned int cmd, unsigned long arg) |
2540 | { | 2352 | { |
@@ -2748,16 +2560,6 @@ HANDLE_IOCTL(RTC_IRQP_SET32, rtc_ioctl) | |||
2748 | HANDLE_IOCTL(RTC_EPOCH_READ32, rtc_ioctl) | 2560 | HANDLE_IOCTL(RTC_EPOCH_READ32, rtc_ioctl) |
2749 | HANDLE_IOCTL(RTC_EPOCH_SET32, rtc_ioctl) | 2561 | HANDLE_IOCTL(RTC_EPOCH_SET32, rtc_ioctl) |
2750 | 2562 | ||
2751 | #if defined(CONFIG_NCP_FS) || defined(CONFIG_NCP_FS_MODULE) | ||
2752 | HANDLE_IOCTL(NCP_IOC_NCPREQUEST_32, do_ncp_ncprequest) | ||
2753 | HANDLE_IOCTL(NCP_IOC_GETMOUNTUID2_32, do_ncp_getmountuid2) | ||
2754 | HANDLE_IOCTL(NCP_IOC_GET_FS_INFO_V2_32, do_ncp_getfsinfo2) | ||
2755 | HANDLE_IOCTL(NCP_IOC_GETOBJECTNAME_32, do_ncp_getobjectname) | ||
2756 | HANDLE_IOCTL(NCP_IOC_SETOBJECTNAME_32, do_ncp_setobjectname) | ||
2757 | HANDLE_IOCTL(NCP_IOC_GETPRIVATEDATA_32, do_ncp_getprivatedata) | ||
2758 | HANDLE_IOCTL(NCP_IOC_SETPRIVATEDATA_32, do_ncp_setprivatedata) | ||
2759 | #endif | ||
2760 | |||
2761 | /* dvb */ | 2563 | /* dvb */ |
2762 | HANDLE_IOCTL(VIDEO_GET_EVENT, do_video_get_event) | 2564 | HANDLE_IOCTL(VIDEO_GET_EVENT, do_video_get_event) |
2763 | HANDLE_IOCTL(VIDEO_STILLPICTURE, do_video_stillpicture) | 2565 | HANDLE_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 | ||
58 | struct inode_operations ncp_dir_inode_operations = | 61 | struct 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 | ||
95 | struct 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 | |||
102 | struct 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 | |||
116 | struct compat_ncp_ioctl_request { | ||
117 | u32 function; | ||
118 | u32 size; | ||
119 | compat_caddr_t data; | ||
120 | }; | ||
121 | |||
122 | struct 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 | |||
135 | static int | ||
136 | ncp_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 | ||
825 | long 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) | |||
569 | COMPATIBLE_IOCTL(RAW_GETBIND) | 569 | COMPATIBLE_IOCTL(RAW_GETBIND) |
570 | /* SMB ioctls which do not need any translations */ | 570 | /* SMB ioctls which do not need any translations */ |
571 | COMPATIBLE_IOCTL(SMB_IOC_NEWCONN) | 571 | COMPATIBLE_IOCTL(SMB_IOC_NEWCONN) |
572 | /* NCP ioctls which do not need any translations */ | ||
573 | COMPATIBLE_IOCTL(NCP_IOC_CONN_LOGGED_IN) | ||
574 | COMPATIBLE_IOCTL(NCP_IOC_SIGN_INIT) | ||
575 | COMPATIBLE_IOCTL(NCP_IOC_SIGN_WANTED) | ||
576 | COMPATIBLE_IOCTL(NCP_IOC_SET_SIGN_WANTED) | ||
577 | COMPATIBLE_IOCTL(NCP_IOC_LOCKUNLOCK) | ||
578 | COMPATIBLE_IOCTL(NCP_IOC_GETROOT) | ||
579 | COMPATIBLE_IOCTL(NCP_IOC_SETROOT) | ||
580 | COMPATIBLE_IOCTL(NCP_IOC_GETCHARSETS) | ||
581 | COMPATIBLE_IOCTL(NCP_IOC_SETCHARSETS) | ||
582 | COMPATIBLE_IOCTL(NCP_IOC_GETDENTRYTTL) | ||
583 | COMPATIBLE_IOCTL(NCP_IOC_SETDENTRYTTL) | ||
584 | /* Little a */ | 572 | /* Little a */ |
585 | COMPATIBLE_IOCTL(ATMSIGD_CTRL) | 573 | COMPATIBLE_IOCTL(ATMSIGD_CTRL) |
586 | COMPATIBLE_IOCTL(ATMARPD_CTRL) | 574 | COMPATIBLE_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 */ |
214 | int ncp_ioctl(struct inode *, struct file *, unsigned int, unsigned long); | 214 | int ncp_ioctl(struct inode *, struct file *, unsigned int, unsigned long); |
215 | long ncp_compat_ioctl(struct file *, unsigned int, unsigned long); | ||
215 | 216 | ||
216 | /* linux/fs/ncpfs/sock.c */ | 217 | /* linux/fs/ncpfs/sock.c */ |
217 | int ncp_request2(struct ncp_server *server, int function, | 218 | int ncp_request2(struct ncp_server *server, int function, |