Commit 2ddb3b15f1b46836c61cfac5b00d8f08a24236e6
Exists in
master
and in
39 other branches
Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/kyle/parisc-2.6
* 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/kyle/parisc-2.6: parisc: use __ratelimit in unaligned.c parisc: Convert to read/update_persistent_clock parisc: Simplify param.h by including <asm-generic/param.h> parisc: drop unnecessary cast in __ldcw_align() macro parisc: add strict copy size checks (v2) parisc: remove trailing space in messages parisc: ditto sys_accept4 parisc: wire up sys_recvmmsg
Showing 12 changed files Side-by-side Diff
- arch/parisc/Kconfig.debug
- arch/parisc/include/asm/param.h
- arch/parisc/include/asm/system.h
- arch/parisc/include/asm/uaccess.h
- arch/parisc/include/asm/unistd.h
- arch/parisc/kernel/cache.c
- arch/parisc/kernel/syscall_table.S
- arch/parisc/kernel/time.c
- arch/parisc/kernel/unaligned.c
- arch/parisc/lib/memcpy.c
- drivers/parisc/eisa_enumerator.c
- drivers/parisc/superio.c
arch/parisc/Kconfig.debug
... | ... | @@ -12,5 +12,19 @@ |
12 | 12 | portion of the kernel code won't be covered by a TLB anymore. |
13 | 13 | If in doubt, say "N". |
14 | 14 | |
15 | +config DEBUG_STRICT_USER_COPY_CHECKS | |
16 | + bool "Strict copy size checks" | |
17 | + depends on DEBUG_KERNEL && !TRACE_BRANCH_PROFILING | |
18 | + ---help--- | |
19 | + Enabling this option turns a certain set of sanity checks for user | |
20 | + copy operations into compile time failures. | |
21 | + | |
22 | + The copy_from_user() etc checks are there to help test if there | |
23 | + are sufficient security checks on the length argument of | |
24 | + the copy operation, by having gcc prove that the argument is | |
25 | + within bounds. | |
26 | + | |
27 | + If unsure, or if you run an older (pre 4.4) gcc, say N. | |
28 | + | |
15 | 29 | endmenu |
arch/parisc/include/asm/param.h
1 | -#ifndef _ASMPARISC_PARAM_H | |
2 | -#define _ASMPARISC_PARAM_H | |
3 | - | |
4 | -#ifdef __KERNEL__ | |
5 | -#define HZ CONFIG_HZ | |
6 | -#define USER_HZ 100 /* some user API use "ticks" */ | |
7 | -#define CLOCKS_PER_SEC (USER_HZ) /* like times() */ | |
8 | -#endif | |
9 | - | |
10 | -#ifndef HZ | |
11 | -#define HZ 100 | |
12 | -#endif | |
13 | - | |
14 | -#define EXEC_PAGESIZE 4096 | |
15 | - | |
16 | -#ifndef NOGROUP | |
17 | -#define NOGROUP (-1) | |
18 | -#endif | |
19 | - | |
20 | -#define MAXHOSTNAMELEN 64 /* max length of hostname */ | |
21 | - | |
22 | -#endif | |
1 | +#include <asm-generic/param.h> |
arch/parisc/include/asm/system.h
arch/parisc/include/asm/uaccess.h
... | ... | @@ -7,6 +7,7 @@ |
7 | 7 | #include <asm/page.h> |
8 | 8 | #include <asm/system.h> |
9 | 9 | #include <asm/cache.h> |
10 | +#include <asm/errno.h> | |
10 | 11 | #include <asm-generic/uaccess-unaligned.h> |
11 | 12 | |
12 | 13 | #define VERIFY_READ 0 |
13 | 14 | |
... | ... | @@ -234,12 +235,34 @@ |
234 | 235 | |
235 | 236 | unsigned long copy_to_user(void __user *dst, const void *src, unsigned long len); |
236 | 237 | #define __copy_to_user copy_to_user |
237 | -unsigned long copy_from_user(void *dst, const void __user *src, unsigned long len); | |
238 | -#define __copy_from_user copy_from_user | |
238 | +unsigned long __copy_from_user(void *dst, const void __user *src, unsigned long len); | |
239 | 239 | unsigned long copy_in_user(void __user *dst, const void __user *src, unsigned long len); |
240 | 240 | #define __copy_in_user copy_in_user |
241 | 241 | #define __copy_to_user_inatomic __copy_to_user |
242 | 242 | #define __copy_from_user_inatomic __copy_from_user |
243 | + | |
244 | +extern void copy_from_user_overflow(void) | |
245 | +#ifdef CONFIG_DEBUG_STRICT_USER_COPY_CHECKS | |
246 | + __compiletime_error("copy_from_user() buffer size is not provably correct") | |
247 | +#else | |
248 | + __compiletime_warning("copy_from_user() buffer size is not provably correct") | |
249 | +#endif | |
250 | +; | |
251 | + | |
252 | +static inline unsigned long __must_check copy_from_user(void *to, | |
253 | + const void __user *from, | |
254 | + unsigned long n) | |
255 | +{ | |
256 | + int sz = __compiletime_object_size(to); | |
257 | + int ret = -EFAULT; | |
258 | + | |
259 | + if (likely(sz == -1 || !__builtin_constant_p(n) || sz >= n)) | |
260 | + ret = __copy_from_user(to, from, n); | |
261 | + else | |
262 | + copy_from_user_overflow(); | |
263 | + | |
264 | + return ret; | |
265 | +} | |
243 | 266 | |
244 | 267 | struct pt_regs; |
245 | 268 | int fixup_exception(struct pt_regs *regs); |
arch/parisc/include/asm/unistd.h
... | ... | @@ -811,8 +811,10 @@ |
811 | 811 | #define __NR_pwritev (__NR_Linux + 316) |
812 | 812 | #define __NR_rt_tgsigqueueinfo (__NR_Linux + 317) |
813 | 813 | #define __NR_perf_event_open (__NR_Linux + 318) |
814 | +#define __NR_recvmmsg (__NR_Linux + 319) | |
815 | +#define __NR_accept4 (__NR_Linux + 320) | |
814 | 816 | |
815 | -#define __NR_Linux_syscalls (__NR_perf_event_open + 1) | |
817 | +#define __NR_Linux_syscalls (__NR_accept4 + 1) | |
816 | 818 | |
817 | 819 | |
818 | 820 | #define __IGNORE_select /* newselect */ |
arch/parisc/kernel/cache.c
... | ... | @@ -171,14 +171,14 @@ |
171 | 171 | cache_info.ic_conf.cc_cst, |
172 | 172 | cache_info.ic_conf.cc_hv); |
173 | 173 | |
174 | - printk("D-TLB conf: sh %d page %d cst %d aid %d pad1 %d \n", | |
174 | + printk("D-TLB conf: sh %d page %d cst %d aid %d pad1 %d\n", | |
175 | 175 | cache_info.dt_conf.tc_sh, |
176 | 176 | cache_info.dt_conf.tc_page, |
177 | 177 | cache_info.dt_conf.tc_cst, |
178 | 178 | cache_info.dt_conf.tc_aid, |
179 | 179 | cache_info.dt_conf.tc_pad1); |
180 | 180 | |
181 | - printk("I-TLB conf: sh %d page %d cst %d aid %d pad1 %d \n", | |
181 | + printk("I-TLB conf: sh %d page %d cst %d aid %d pad1 %d\n", | |
182 | 182 | cache_info.it_conf.tc_sh, |
183 | 183 | cache_info.it_conf.tc_page, |
184 | 184 | cache_info.it_conf.tc_cst, |
arch/parisc/kernel/syscall_table.S
arch/parisc/kernel/time.c
... | ... | @@ -250,9 +250,21 @@ |
250 | 250 | } |
251 | 251 | module_init(rtc_init); |
252 | 252 | |
253 | -void __init time_init(void) | |
253 | +void read_persistent_clock(struct timespec *ts) | |
254 | 254 | { |
255 | 255 | static struct pdc_tod tod_data; |
256 | + if (pdc_tod_read(&tod_data) == 0) { | |
257 | + ts->tv_sec = tod_data.tod_sec; | |
258 | + ts->tv_nsec = tod_data.tod_usec * 1000; | |
259 | + } else { | |
260 | + printk(KERN_ERR "Error reading tod clock\n"); | |
261 | + ts->tv_sec = 0; | |
262 | + ts->tv_nsec = 0; | |
263 | + } | |
264 | +} | |
265 | + | |
266 | +void __init time_init(void) | |
267 | +{ | |
256 | 268 | unsigned long current_cr16_khz; |
257 | 269 | |
258 | 270 | clocktick = (100 * PAGE0->mem_10msec) / HZ; |
... | ... | @@ -264,20 +276,5 @@ |
264 | 276 | clocksource_cr16.mult = clocksource_khz2mult(current_cr16_khz, |
265 | 277 | clocksource_cr16.shift); |
266 | 278 | clocksource_register(&clocksource_cr16); |
267 | - | |
268 | - if (pdc_tod_read(&tod_data) == 0) { | |
269 | - unsigned long flags; | |
270 | - | |
271 | - write_seqlock_irqsave(&xtime_lock, flags); | |
272 | - xtime.tv_sec = tod_data.tod_sec; | |
273 | - xtime.tv_nsec = tod_data.tod_usec * 1000; | |
274 | - set_normalized_timespec(&wall_to_monotonic, | |
275 | - -xtime.tv_sec, -xtime.tv_nsec); | |
276 | - write_sequnlock_irqrestore(&xtime_lock, flags); | |
277 | - } else { | |
278 | - printk(KERN_ERR "Error reading tod clock\n"); | |
279 | - xtime.tv_sec = 0; | |
280 | - xtime.tv_nsec = 0; | |
281 | - } | |
282 | 279 | } |
arch/parisc/kernel/unaligned.c
... | ... | @@ -25,6 +25,7 @@ |
25 | 25 | #include <linux/module.h> |
26 | 26 | #include <linux/sched.h> |
27 | 27 | #include <linux/signal.h> |
28 | +#include <linux/ratelimit.h> | |
28 | 29 | #include <asm/uaccess.h> |
29 | 30 | |
30 | 31 | /* #define DEBUG_UNALIGNED 1 */ |
... | ... | @@ -446,8 +447,7 @@ |
446 | 447 | |
447 | 448 | void handle_unaligned(struct pt_regs *regs) |
448 | 449 | { |
449 | - static unsigned long unaligned_count = 0; | |
450 | - static unsigned long last_time = 0; | |
450 | + static DEFINE_RATELIMIT_STATE(ratelimit, 5 * HZ, 5); | |
451 | 451 | unsigned long newbase = R1(regs->iir)?regs->gr[R1(regs->iir)]:0; |
452 | 452 | int modify = 0; |
453 | 453 | int ret = ERR_NOTHANDLED; |
... | ... | @@ -460,14 +460,8 @@ |
460 | 460 | goto force_sigbus; |
461 | 461 | } |
462 | 462 | |
463 | - if (unaligned_count > 5 && | |
464 | - time_after(jiffies, last_time + 5 * HZ)) { | |
465 | - unaligned_count = 0; | |
466 | - last_time = jiffies; | |
467 | - } | |
468 | - | |
469 | - if (!(current->thread.flags & PARISC_UAC_NOPRINT) | |
470 | - && ++unaligned_count < 5) { | |
463 | + if (!(current->thread.flags & PARISC_UAC_NOPRINT) && | |
464 | + __ratelimit(&ratelimit)) { | |
471 | 465 | char buf[256]; |
472 | 466 | sprintf(buf, "%s(%d): unaligned access to 0x" RFMT " at ip=0x" RFMT "\n", |
473 | 467 | current->comm, task_pid_nr(current), regs->ior, regs->iaoq[0]); |
arch/parisc/lib/memcpy.c
... | ... | @@ -475,7 +475,8 @@ |
475 | 475 | return pa_memcpy((void __force *)dst, src, len); |
476 | 476 | } |
477 | 477 | |
478 | -unsigned long copy_from_user(void *dst, const void __user *src, unsigned long len) | |
478 | +EXPORT_SYMBOL(__copy_from_user); | |
479 | +unsigned long __copy_from_user(void *dst, const void __user *src, unsigned long len) | |
479 | 480 | { |
480 | 481 | mtsp(get_user_space(), 1); |
481 | 482 | mtsp(get_kernel_space(), 2); |
drivers/parisc/eisa_enumerator.c
drivers/parisc/superio.c
... | ... | @@ -169,7 +169,7 @@ |
169 | 169 | /* ...then properly fixup the USB to point at suckyio PIC */ |
170 | 170 | sio->usb_pdev->irq = superio_fixup_irq(sio->usb_pdev); |
171 | 171 | |
172 | - printk(KERN_INFO PFX "Found NS87560 Legacy I/O device at %s (IRQ %i) \n", | |
172 | + printk(KERN_INFO PFX "Found NS87560 Legacy I/O device at %s (IRQ %i)\n", | |
173 | 173 | pci_name(pdev), pdev->irq); |
174 | 174 | |
175 | 175 | pci_read_config_dword (pdev, SIO_SP1BAR, &sio->sp1_base); |