Fedora kernel-2.6.17-1.2142_FC4 patched with stable patch-2.6.17.4-vs2.0.2-rc26.diff
[linux-2.6.git] / arch / ia64 / kernel / unaligned.c
index 43b45b6..1e35755 100644 (file)
@@ -24,7 +24,7 @@
 #include <asm/uaccess.h>
 #include <asm/unaligned.h>
 
-extern void die_if_kernel(char *str, struct pt_regs *regs, long err) __attribute__ ((noreturn));
+extern void die_if_kernel(char *str, struct pt_regs *regs, long err);
 
 #undef DEBUG_UNALIGNED_TRAP
 
@@ -52,6 +52,15 @@ dump (const char *str, void *vp, size_t len)
 #define IA64_FIRST_ROTATING_FR 32
 #define SIGN_EXT9              0xffffffffffffff00ul
 
+/*
+ *  sysctl settable hook which tells the kernel whether to honor the
+ *  IA64_THREAD_UAC_NOPRINT prctl.  Because this is user settable, we want
+ *  to allow the super user to enable/disable this for security reasons
+ *  (i.e. don't allow attacker to fill up logs with unaligned accesses).
+ */
+int no_unaligned_warning;
+static int noprint_warning;
+
 /*
  * For M-unit:
  *
@@ -1283,8 +1292,9 @@ within_logging_rate_limit (void)
 
        if (jiffies - last_time > 5*HZ)
                count = 0;
-       if (++count < 5) {
+       if (count < 5) {
                last_time = jiffies;
+               count++;
                return 1;
        }
        return 0;
@@ -1323,8 +1333,9 @@ ia64_handle_unaligned (unsigned long ifa, struct pt_regs *regs)
                if ((current->thread.flags & IA64_THREAD_UAC_SIGBUS) != 0)
                        goto force_sigbus;
 
-               if (!(current->thread.flags & IA64_THREAD_UAC_NOPRINT)
-                   && within_logging_rate_limit())
+               if (!no_unaligned_warning &&
+                   !(current->thread.flags & IA64_THREAD_UAC_NOPRINT) &&
+                   within_logging_rate_limit())
                {
                        char buf[200];  /* comm[] is at most 16 bytes... */
                        size_t len;
@@ -1339,7 +1350,22 @@ ia64_handle_unaligned (unsigned long ifa, struct pt_regs *regs)
                        if (user_mode(regs))
                                tty_write_message(current->signal->tty, buf);
                        buf[len-1] = '\0';      /* drop '\r' */
-                       printk(KERN_WARNING "%s", buf); /* watch for command names containing %s */
+                       /* watch for command names containing %s */
+                       printk(KERN_WARNING "%s", buf);
+               } else {
+                       if (no_unaligned_warning && !noprint_warning) {
+                               noprint_warning = 1;
+                               printk(KERN_WARNING "%s(%d) encountered an "
+                                      "unaligned exception which required\n"
+                                      "kernel assistance, which degrades "
+                                      "the performance of the application.\n"
+                                      "Unaligned exception warnings have "
+                                      "been disabled by the system "
+                                      "administrator\n"
+                                      "echo 0 > /proc/sys/kernel/ignore-"
+                                      "unaligned-usertrap to re-enable\n",
+                                      current->comm, current->pid);
+                       }
                }
        } else {
                if (within_logging_rate_limit())