Commit b72570f1 authored by Andrew Morton's avatar Andrew Morton Committed by Linus Torvalds

[PATCH] s390: 32 bit ioctl emulation fixes.

From: Martin Schwidefsky <schwidefsky@de.ibm.com>

- audit all 32 bit pointer accesses and make them use compat_ioctl(),
  because of the necessary conversion on s390
- introduce ULONG_IOCTL() which is used instead of COMPATIBLE_IOCTL()
  for all ioctls that have their argument encoded in 'arg' instead
  of the memory pointed to by arg. Same reason as above.
- remove most #ifdefs in <linux/compat_ioctl.h>: They don't make
  any sense if the respective handlers in fs/compat_ioctl.c are
  not disabled as well and they are potentially harmful (the
  CONFIG_BLK_DEV_DM e.g. was insufficient).
- comment out  COMPATIBLE_IOCTL(SIOCSIFBR) and
  COMPATIBLE_IOCTL(SIOCGIFBR), they appear to require a handler
- implement copy_in_user for s390, as needed for many handlers in
  fs/compat_ioctl.c
- get rid of all duplicate stuff in arch/s390/kernel/compat_ioctl.c
  that is also in fs/compat_ioctl.c
parent 33c567a3
This diff is collapsed.
......@@ -71,6 +71,41 @@ __copy_to_user_asm:
.long 3b,1b
.previous
.align 4
.text
.globl __copy_in_user_asm
__copy_in_user_asm:
stm %r6,%r15,24(%r15)
lr %r5,%r3
lr %r7,%r3
lr %r6,%r2
cpya 6,4 # ar6 = ar4
sacf 512
0: mvcle %r4,%r6,0
jo 0b
1: sacf 0
lr %r2,%r7
lm %r6,%r15,24(%r15)
br %r14
2: lhi %r1,-4096
lr %r5,%r4
slr %r5,%r1 # %r5 = %r4 + 4096
nr %r5,%r1 # %r5 = (%r4 + 4096) & -4096
slr %r5,%r4 # %r5 = #bytes to next user page boundary
clr %r7,%r5 # copy crosses next page boundary ?
jnh 1b # no, the current page fauled
# The page after the current user page might have faulted.
# We cant't find out which page because the program check handler
# might have callled schedule, destroying all lowcore information.
# We retry with the shortened length.
3: mvcle %r4,%r6,0
jo 3b
j 1b
.section __ex_table,"a"
.long 0b,2b
.long 3b,1b
.previous
.align 4
.text
.globl __clear_user_asm
......
......@@ -71,6 +71,41 @@ __copy_to_user_asm:
.quad 3b,1b
.previous
.align 4
.text
.globl __copy_in_user_asm
__copy_in_user_asm:
stmg %r6,%r15,48(%r15)
lgr %r5,%r3
lgr %r7,%r5
lgr %r6,%r2
cpya 6,4 # ar6 = ar4
sacf 512
0: mvcle %r4,%r6,0
jo 0b
1: sacf 0
lgr %r2,%r7
lmg %r6,%r15,48(%r15)
br %r14
2: lghi %r1,-4096
lgr %r5,%r4
slgr %r5,%r1 # %r5 = %r4 + 4096
ngr %r5,%r1 # %r5 = (%r4 + 4096) & -4096
slgr %r5,%r4 # %r5 = #bytes to next user page boundary
clgr %r7,%r5 # copy crosses next page boundary ?
jnh 1b # no, the current page fauled
# The page after the current user page might have faulted.
# We cant't find out which page because the program check handler
# might have callled schedule, destroying all lowcore information.
# We retry with the shortened length.
3: mvcle %r4,%r6,0
jo 3b
j 1b
.section __ex_table,"a"
.quad 0b,2b
.quad 3b,1b
.previous
.align 4
.text
.globl __clear_user_asm
......
This diff is collapsed.
......@@ -389,6 +389,26 @@ extern long __copy_from_user_asm(void *to, long n, const void *from);
err; \
})
extern long __copy_in_user_asm(const void *from, long n, void *to);
#define __copy_in_user(to, from, n) \
({ \
__copy_in_user_asm(from, n, to); \
})
#define copy_in_user(to, from, n) \
({ \
long err = 0; \
__typeof__(n) __n = (n); \
might_sleep(); \
if (__access_ok(from,__n) && __access_ok(to,__n)) { \
err = __copy_in_user_asm(from, __n, to); \
} \
else \
err = __n; \
err; \
})
/*
* Copy a null terminated string from userspace.
*/
......@@ -594,5 +614,4 @@ clear_user(void *to, unsigned long n)
return n;
}
#endif /* _S390_UACCESS_H */
#endif /* __S390_UACCESS_H */
This diff is collapsed.
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment