aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--arch/ia64/kernel/unaligned.c31
-rw-r--r--include/linux/sysctl.h1
-rw-r--r--kernel/sysctl.c14
3 files changed, 43 insertions, 3 deletions
diff --git a/arch/ia64/kernel/unaligned.c b/arch/ia64/kernel/unaligned.c
index 112913896844..1e357550c776 100644
--- a/arch/ia64/kernel/unaligned.c
+++ b/arch/ia64/kernel/unaligned.c
@@ -53,6 +53,15 @@ dump (const char *str, void *vp, size_t len)
53#define SIGN_EXT9 0xffffffffffffff00ul 53#define SIGN_EXT9 0xffffffffffffff00ul
54 54
55/* 55/*
56 * sysctl settable hook which tells the kernel whether to honor the
57 * IA64_THREAD_UAC_NOPRINT prctl. Because this is user settable, we want
58 * to allow the super user to enable/disable this for security reasons
59 * (i.e. don't allow attacker to fill up logs with unaligned accesses).
60 */
61int no_unaligned_warning;
62static int noprint_warning;
63
64/*
56 * For M-unit: 65 * For M-unit:
57 * 66 *
58 * opcode | m | x6 | 67 * opcode | m | x6 |
@@ -1324,8 +1333,9 @@ ia64_handle_unaligned (unsigned long ifa, struct pt_regs *regs)
1324 if ((current->thread.flags & IA64_THREAD_UAC_SIGBUS) != 0) 1333 if ((current->thread.flags & IA64_THREAD_UAC_SIGBUS) != 0)
1325 goto force_sigbus; 1334 goto force_sigbus;
1326 1335
1327 if (!(current->thread.flags & IA64_THREAD_UAC_NOPRINT) 1336 if (!no_unaligned_warning &&
1328 && within_logging_rate_limit()) 1337 !(current->thread.flags & IA64_THREAD_UAC_NOPRINT) &&
1338 within_logging_rate_limit())
1329 { 1339 {
1330 char buf[200]; /* comm[] is at most 16 bytes... */ 1340 char buf[200]; /* comm[] is at most 16 bytes... */
1331 size_t len; 1341 size_t len;
@@ -1340,7 +1350,22 @@ ia64_handle_unaligned (unsigned long ifa, struct pt_regs *regs)
1340 if (user_mode(regs)) 1350 if (user_mode(regs))
1341 tty_write_message(current->signal->tty, buf); 1351 tty_write_message(current->signal->tty, buf);
1342 buf[len-1] = '\0'; /* drop '\r' */ 1352 buf[len-1] = '\0'; /* drop '\r' */
1343 printk(KERN_WARNING "%s", buf); /* watch for command names containing %s */ 1353 /* watch for command names containing %s */
1354 printk(KERN_WARNING "%s", buf);
1355 } else {
1356 if (no_unaligned_warning && !noprint_warning) {
1357 noprint_warning = 1;
1358 printk(KERN_WARNING "%s(%d) encountered an "
1359 "unaligned exception which required\n"
1360 "kernel assistance, which degrades "
1361 "the performance of the application.\n"
1362 "Unaligned exception warnings have "
1363 "been disabled by the system "
1364 "administrator\n"
1365 "echo 0 > /proc/sys/kernel/ignore-"
1366 "unaligned-usertrap to re-enable\n",
1367 current->comm, current->pid);
1368 }
1344 } 1369 }
1345 } else { 1370 } else {
1346 if (within_logging_rate_limit()) 1371 if (within_logging_rate_limit())
diff --git a/include/linux/sysctl.h b/include/linux/sysctl.h
index 0e92bf7ec28e..bac61db26456 100644
--- a/include/linux/sysctl.h
+++ b/include/linux/sysctl.h
@@ -147,6 +147,7 @@ enum
147 KERN_SETUID_DUMPABLE=69, /* int: behaviour of dumps for setuid core */ 147 KERN_SETUID_DUMPABLE=69, /* int: behaviour of dumps for setuid core */
148 KERN_SPIN_RETRY=70, /* int: number of spinlock retries */ 148 KERN_SPIN_RETRY=70, /* int: number of spinlock retries */
149 KERN_ACPI_VIDEO_FLAGS=71, /* int: flags for setting up video after ACPI sleep */ 149 KERN_ACPI_VIDEO_FLAGS=71, /* int: flags for setting up video after ACPI sleep */
150 KERN_IA64_UNALIGNED=72, /* int: ia64 unaligned userland trap enable */
150}; 151};
151 152
152 153
diff --git a/kernel/sysctl.c b/kernel/sysctl.c
index c05a2b7125e1..acf6c1550f27 100644
--- a/kernel/sysctl.c
+++ b/kernel/sysctl.c
@@ -124,6 +124,10 @@ extern int sysctl_hz_timer;
124extern int acct_parm[]; 124extern int acct_parm[];
125#endif 125#endif
126 126
127#ifdef CONFIG_IA64
128extern int no_unaligned_warning;
129#endif
130
127static int parse_table(int __user *, int, void __user *, size_t __user *, void __user *, size_t, 131static int parse_table(int __user *, int, void __user *, size_t __user *, void __user *, size_t,
128 ctl_table *, void **); 132 ctl_table *, void **);
129static int proc_doutsstring(ctl_table *table, int write, struct file *filp, 133static int proc_doutsstring(ctl_table *table, int write, struct file *filp,
@@ -666,6 +670,16 @@ static ctl_table kern_table[] = {
666 .proc_handler = &proc_dointvec, 670 .proc_handler = &proc_dointvec,
667 }, 671 },
668#endif 672#endif
673#ifdef CONFIG_IA64
674 {
675 .ctl_name = KERN_IA64_UNALIGNED,
676 .procname = "ignore-unaligned-usertrap",
677 .data = &no_unaligned_warning,
678 .maxlen = sizeof (int),
679 .mode = 0644,
680 .proc_handler = &proc_dointvec,
681 },
682#endif
669 { .ctl_name = 0 } 683 { .ctl_name = 0 }
670}; 684};
671 685