aboutsummaryrefslogtreecommitdiffstats
path: root/fs/compat.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/compat.c')
-rw-r--r--fs/compat.c122
1 files changed, 23 insertions, 99 deletions
diff --git a/fs/compat.c b/fs/compat.c
index 6b06b6bae35e..ac3fb9ed8eea 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
313int 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}
342EXPORT_SYMBOL(register_ioctl32_conversion);
343
344static 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
354int 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);
397out:
398 up_write(&ioctl32_sem);
399 return -EINVAL;
400}
401EXPORT_SYMBOL(unregister_ioctl32_conversion);
402
403static void compat_ioctl_error(struct file *filp, unsigned int fd, 313static 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)
720struct compat_ncp_mount_data { 630struct 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
785struct compat_smb_mount_data { 695struct 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 */
1281asmlinkage long
1282compat_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.
@@ -1699,6 +1619,7 @@ compat_sys_select(int n, compat_ulong_t __user *inp, compat_ulong_t __user *outp
1699 char *bits; 1619 char *bits;
1700 long timeout; 1620 long timeout;
1701 int size, max_fdset, ret = -EINVAL; 1621 int size, max_fdset, ret = -EINVAL;
1622 struct fdtable *fdt;
1702 1623
1703 timeout = MAX_SCHEDULE_TIMEOUT; 1624 timeout = MAX_SCHEDULE_TIMEOUT;
1704 if (tvp) { 1625 if (tvp) {
@@ -1724,7 +1645,10 @@ compat_sys_select(int n, compat_ulong_t __user *inp, compat_ulong_t __user *outp
1724 goto out_nofds; 1645 goto out_nofds;
1725 1646
1726 /* max_fdset can increase, so grab it once to avoid race */ 1647 /* max_fdset can increase, so grab it once to avoid race */
1727 max_fdset = current->files->max_fdset; 1648 rcu_read_lock();
1649 fdt = files_fdtable(current->files);
1650 max_fdset = fdt->max_fdset;
1651 rcu_read_unlock();
1728 if (n > max_fdset) 1652 if (n > max_fdset)
1729 n = max_fdset; 1653 n = max_fdset;
1730 1654
@@ -1808,8 +1732,8 @@ struct compat_nfsctl_export {
1808 compat_dev_t ex32_dev; 1732 compat_dev_t ex32_dev;
1809 compat_ino_t ex32_ino; 1733 compat_ino_t ex32_ino;
1810 compat_int_t ex32_flags; 1734 compat_int_t ex32_flags;
1811 compat_uid_t ex32_anon_uid; 1735 __compat_uid_t ex32_anon_uid;
1812 compat_gid_t ex32_anon_gid; 1736 __compat_gid_t ex32_anon_gid;
1813}; 1737};
1814 1738
1815struct compat_nfsctl_fdparm { 1739struct compat_nfsctl_fdparm {