diff options
Diffstat (limited to 'fs/compat.c')
| -rw-r--r-- | fs/compat.c | 116 |
1 files changed, 18 insertions, 98 deletions
diff --git a/fs/compat.c b/fs/compat.c index 6b06b6bae35e..8c665705c6a0 100644 --- a/fs/compat.c +++ b/fs/compat.c | |||
| @@ -310,96 +310,6 @@ static int __init init_sys32_ioctl(void) | |||
| 310 | 310 | ||
| 311 | __initcall(init_sys32_ioctl); | 311 | __initcall(init_sys32_ioctl); |
| 312 | 312 | ||
| 313 | int register_ioctl32_conversion(unsigned int cmd, | ||
| 314 | ioctl_trans_handler_t handler) | ||
| 315 | { | ||
| 316 | struct ioctl_trans *t; | ||
| 317 | struct ioctl_trans *new_t; | ||
| 318 | unsigned long hash = ioctl32_hash(cmd); | ||
| 319 | |||
| 320 | new_t = kmalloc(sizeof(*new_t), GFP_KERNEL); | ||
| 321 | if (!new_t) | ||
| 322 | return -ENOMEM; | ||
| 323 | |||
| 324 | down_write(&ioctl32_sem); | ||
| 325 | for (t = ioctl32_hash_table[hash]; t; t = t->next) { | ||
| 326 | if (t->cmd == cmd) { | ||
| 327 | printk(KERN_ERR "Trying to register duplicated ioctl32 " | ||
| 328 | "handler %x\n", cmd); | ||
| 329 | up_write(&ioctl32_sem); | ||
| 330 | kfree(new_t); | ||
| 331 | return -EINVAL; | ||
| 332 | } | ||
| 333 | } | ||
| 334 | new_t->next = NULL; | ||
| 335 | new_t->cmd = cmd; | ||
| 336 | new_t->handler = handler; | ||
| 337 | ioctl32_insert_translation(new_t); | ||
| 338 | |||
| 339 | up_write(&ioctl32_sem); | ||
| 340 | return 0; | ||
| 341 | } | ||
| 342 | EXPORT_SYMBOL(register_ioctl32_conversion); | ||
| 343 | |||
| 344 | static inline int builtin_ioctl(struct ioctl_trans *t) | ||
| 345 | { | ||
| 346 | return t >= ioctl_start && t < (ioctl_start + ioctl_table_size); | ||
| 347 | } | ||
| 348 | |||
| 349 | /* Problem: | ||
| 350 | This function cannot unregister duplicate ioctls, because they are not | ||
| 351 | unique. | ||
| 352 | When they happen we need to extend the prototype to pass the handler too. */ | ||
| 353 | |||
| 354 | int unregister_ioctl32_conversion(unsigned int cmd) | ||
| 355 | { | ||
| 356 | unsigned long hash = ioctl32_hash(cmd); | ||
| 357 | struct ioctl_trans *t, *t1; | ||
| 358 | |||
| 359 | down_write(&ioctl32_sem); | ||
| 360 | |||
| 361 | t = ioctl32_hash_table[hash]; | ||
| 362 | if (!t) { | ||
| 363 | up_write(&ioctl32_sem); | ||
| 364 | return -EINVAL; | ||
| 365 | } | ||
| 366 | |||
| 367 | if (t->cmd == cmd) { | ||
| 368 | if (builtin_ioctl(t)) { | ||
| 369 | printk("%p tried to unregister builtin ioctl %x\n", | ||
| 370 | __builtin_return_address(0), cmd); | ||
| 371 | } else { | ||
| 372 | ioctl32_hash_table[hash] = t->next; | ||
| 373 | up_write(&ioctl32_sem); | ||
| 374 | kfree(t); | ||
| 375 | return 0; | ||
| 376 | } | ||
| 377 | } | ||
| 378 | while (t->next) { | ||
| 379 | t1 = t->next; | ||
| 380 | if (t1->cmd == cmd) { | ||
| 381 | if (builtin_ioctl(t1)) { | ||
| 382 | printk("%p tried to unregister builtin " | ||
| 383 | "ioctl %x\n", | ||
| 384 | __builtin_return_address(0), cmd); | ||
| 385 | goto out; | ||
| 386 | } else { | ||
| 387 | t->next = t1->next; | ||
| 388 | up_write(&ioctl32_sem); | ||
| 389 | kfree(t1); | ||
| 390 | return 0; | ||
| 391 | } | ||
| 392 | } | ||
| 393 | t = t1; | ||
| 394 | } | ||
| 395 | printk(KERN_ERR "Trying to free unknown 32bit ioctl handler %x\n", | ||
| 396 | cmd); | ||
| 397 | out: | ||
| 398 | up_write(&ioctl32_sem); | ||
| 399 | return -EINVAL; | ||
| 400 | } | ||
| 401 | EXPORT_SYMBOL(unregister_ioctl32_conversion); | ||
| 402 | |||
| 403 | static void compat_ioctl_error(struct file *filp, unsigned int fd, | 313 | static void compat_ioctl_error(struct file *filp, unsigned int fd, |
| 404 | unsigned int cmd, unsigned long arg) | 314 | unsigned int cmd, unsigned long arg) |
| 405 | { | 315 | { |
| @@ -720,14 +630,14 @@ compat_sys_io_submit(aio_context_t ctx_id, int nr, u32 __user *iocb) | |||
| 720 | struct compat_ncp_mount_data { | 630 | struct compat_ncp_mount_data { |
| 721 | compat_int_t version; | 631 | compat_int_t version; |
| 722 | compat_uint_t ncp_fd; | 632 | compat_uint_t ncp_fd; |
| 723 | compat_uid_t mounted_uid; | 633 | __compat_uid_t mounted_uid; |
| 724 | compat_pid_t wdog_pid; | 634 | compat_pid_t wdog_pid; |
| 725 | unsigned char mounted_vol[NCP_VOLNAME_LEN + 1]; | 635 | unsigned char mounted_vol[NCP_VOLNAME_LEN + 1]; |
| 726 | compat_uint_t time_out; | 636 | compat_uint_t time_out; |
| 727 | compat_uint_t retry_count; | 637 | compat_uint_t retry_count; |
| 728 | compat_uint_t flags; | 638 | compat_uint_t flags; |
| 729 | compat_uid_t uid; | 639 | __compat_uid_t uid; |
| 730 | compat_gid_t gid; | 640 | __compat_gid_t gid; |
| 731 | compat_mode_t file_mode; | 641 | compat_mode_t file_mode; |
| 732 | compat_mode_t dir_mode; | 642 | compat_mode_t dir_mode; |
| 733 | }; | 643 | }; |
| @@ -784,9 +694,9 @@ static void *do_ncp_super_data_conv(void *raw_data) | |||
| 784 | 694 | ||
| 785 | struct compat_smb_mount_data { | 695 | struct compat_smb_mount_data { |
| 786 | compat_int_t version; | 696 | compat_int_t version; |
| 787 | compat_uid_t mounted_uid; | 697 | __compat_uid_t mounted_uid; |
| 788 | compat_uid_t uid; | 698 | __compat_uid_t uid; |
| 789 | compat_gid_t gid; | 699 | __compat_gid_t gid; |
| 790 | compat_mode_t file_mode; | 700 | compat_mode_t file_mode; |
| 791 | compat_mode_t dir_mode; | 701 | compat_mode_t dir_mode; |
| 792 | }; | 702 | }; |
| @@ -1365,6 +1275,16 @@ out: | |||
| 1365 | } | 1275 | } |
| 1366 | 1276 | ||
| 1367 | /* | 1277 | /* |
| 1278 | * Exactly like fs/open.c:sys_open(), except that it doesn't set the | ||
| 1279 | * O_LARGEFILE flag. | ||
| 1280 | */ | ||
| 1281 | asmlinkage long | ||
| 1282 | compat_sys_open(const char __user *filename, int flags, int mode) | ||
| 1283 | { | ||
| 1284 | return do_sys_open(filename, flags, mode); | ||
| 1285 | } | ||
| 1286 | |||
| 1287 | /* | ||
| 1368 | * compat_count() counts the number of arguments/envelopes. It is basically | 1288 | * compat_count() counts the number of arguments/envelopes. It is basically |
| 1369 | * a copy of count() from fs/exec.c, except that it works with 32 bit argv | 1289 | * a copy of count() from fs/exec.c, except that it works with 32 bit argv |
| 1370 | * and envp pointers. | 1290 | * and envp pointers. |
| @@ -1808,8 +1728,8 @@ struct compat_nfsctl_export { | |||
| 1808 | compat_dev_t ex32_dev; | 1728 | compat_dev_t ex32_dev; |
| 1809 | compat_ino_t ex32_ino; | 1729 | compat_ino_t ex32_ino; |
| 1810 | compat_int_t ex32_flags; | 1730 | compat_int_t ex32_flags; |
| 1811 | compat_uid_t ex32_anon_uid; | 1731 | __compat_uid_t ex32_anon_uid; |
| 1812 | compat_gid_t ex32_anon_gid; | 1732 | __compat_gid_t ex32_anon_gid; |
| 1813 | }; | 1733 | }; |
| 1814 | 1734 | ||
| 1815 | struct compat_nfsctl_fdparm { | 1735 | struct compat_nfsctl_fdparm { |
