| From: |
| Tavis Ormandy <taviso@gentoo.org> |
| To: |
| linux-kernel@vger.kernel.org |
| Subject: |
| [PATCH] 2.4.21: Optionally Configure UAC Policy via Sysctl (Alpha) |
| Date: |
| Thu, 10 Jul 2003 08:15:13 +0000 |
| Cc: |
| alpha@gentoo.org |
Hi there, this patch adds a configuration option in General Setup for Alpha
users, "CONFIG_ALPHA_UAC_SYSCTL", which will allow the kernel UAC policy to
be modified at runtime via sysctl's.
The sysctl's created are:
/proc/sys/kernel/uac/noprint
/proc/sys/kernel/uac/sigbus
/proc/sys/kernel/uac/nofix
which are initialised to the existing policy. I've added some text for
the Help screen.
Benefits:
* No longer need to recompile to change UAC policy.
* Disabling the 'unaligned trap' messages usually requires
changing the loglevel, which sacrifices other useful messages.
* UAC_SIGBUS can be turned on and off at will, which is quite
handy for debugging.
Suggestions/comments/flames welcome, im considering submitting to Marcelo
(so any tips welcome). Patch (against 2.4.21) below sig.
Thanks, Tavis.
--
-------------------------------------
taviso@sdf.lonestar.org | finger me for my gpg key.
-------------------------------------------------------
diff -ruN linux-2.4.21.orig/arch/alpha/config.in linux-2.4.21/arch/alpha/config.in
--- linux-2.4.21.orig/arch/alpha/config.in 2003-06-13 15:51:29.000000000 +0100
+++ linux-2.4.21/arch/alpha/config.in 2003-07-10 07:45:21.000000000 +0100
@@ -294,6 +294,9 @@
fi
if [ "$CONFIG_PROC_FS" != "n" ]; then
tristate 'SRM environment through procfs' CONFIG_SRM_ENV
+ if [ "$CONFIG_SYSCTL" != "n" ]; then
+ bool 'Configure uac policy via sysctl' CONFIG_ALPHA_UAC_SYSCTL
+ fi
fi
tristate 'Kernel support for a.out (ECOFF) binaries' CONFIG_BINFMT_AOUT
diff -ruN linux-2.4.21.orig/arch/alpha/kernel/traps.c linux-2.4.21/arch/alpha/kernel/traps.c
--- linux-2.4.21.orig/arch/alpha/kernel/traps.c 2003-06-13 15:51:29.000000000 +0100
+++ linux-2.4.21/arch/alpha/kernel/traps.c 2003-07-10 07:43:38.000000000 +0100
@@ -14,6 +14,8 @@
#include <linux/tty.h>
#include <linux/delay.h>
#include <linux/smp_lock.h>
+#include <linux/sysctl.h>
+#include <linux/init.h>
#include <asm/gentrap.h>
#include <asm/uaccess.h>
@@ -32,6 +34,43 @@
static int opDEC_checked = 0;
static unsigned long opDEC_test_pc = 0;
+#ifdef CONFIG_ALPHA_UAC_SYSCTL
+static struct ctl_table_header *uac_sysctl_header;
+
+static int enabled_noprint = 0;
+static int enabled_sigbus = 0;
+static int enabled_nofix = 0;
+
+ctl_table uac_table[] = {
+ {KERN_UAC_NOPRINT, "noprint", &enabled_noprint, sizeof (int), 0644, NULL, &proc_dointvec},
+ {KERN_UAC_SIGBUS, "sigbus", &enabled_sigbus, sizeof (int), 0644, NULL, &proc_dointvec},
+ {KERN_UAC_NOFIX, "nofix", &enabled_nofix, sizeof (int), 0644, NULL, &proc_dointvec},
+ {0}
+};
+
+static int __init init_uac_sysctl(void)
+{
+ unsigned long uac_bits;
+
+ /* get the defined UAC_POLICY */
+ uac_bits = (current->thread.flags >> UAC_SHIFT) & UAC_BITMASK;
+
+ /* now initialize sysctl's with that policy */
+ enabled_noprint = (uac_bits & UAC_NOPRINT) ? 1 : 0;
+ enabled_sigbus = (uac_bits & UAC_SIGBUS) ? 1 : 0;
+ enabled_nofix = (uac_bits & UAC_NOFIX) ? 1 : 0;
+
+ /* save this for later so we can clean up */
+ uac_sysctl_header = register_sysctl_table(uac_table, 0);
+ return 0;
+}
+
+static void __exit exit_uac_sysctl(void)
+{
+ unregister_sysctl_table(uac_sysctl_header);
+}
+#endif
+
static void
opDEC_check(void)
{
@@ -710,19 +749,24 @@
do_entUnaUser(void * va, unsigned long opcode,
unsigned long reg, struct pt_regs *regs)
{
- static int cnt = 0;
- static long last_time = 0;
-
unsigned long tmp1, tmp2, tmp3, tmp4;
unsigned long fake_reg, *reg_addr = &fake_reg;
- unsigned long uac_bits;
long error;
+ static int cnt = 0;
+ static long last_time = 0;
+#ifndef CONFIG_ALPHA_UAC_SYSCTL
+ unsigned long uac_bits;
+
/* Check the UAC bits to decide what the user wants us to do
with the unaliged access. */
uac_bits = (current->thread.flags >> UAC_SHIFT) & UAC_BITMASK;
if (!(uac_bits & UAC_NOPRINT)) {
+#else
+ /* check systcls for uac policy */
+ if (!(enabled_noprint)) {
+#endif
if (cnt >= 5 && jiffies - last_time > 5*HZ) {
cnt = 0;
}
@@ -733,10 +777,18 @@
}
last_time = jiffies;
}
+#ifndef CONFIG_ALPHA_UAC_SYSCTL
if (uac_bits & UAC_SIGBUS) {
+#else
+ if (enabled_sigbus) {
+#endif
goto give_sigbus;
}
+#ifndef CONFIG_ALPHA_UAC_SYSCTL
if (uac_bits & UAC_NOFIX) {
+#else
+ if (enabled_nofix) {
+#endif
/* Not sure why you'd want to use this, but... */
return;
}
diff -ruN linux-2.4.21.orig/Documentation/Configure.help linux-2.4.21/Documentation/Configure.help
--- linux-2.4.21.orig/Documentation/Configure.help 2003-06-13 15:51:29.000000000 +0100
+++ linux-2.4.21/Documentation/Configure.help 2003-07-10 07:40:03.000000000 +0100
@@ -3372,6 +3372,29 @@
Say N unless you know you need gobs and gobs of vmalloc space.
+Configure UAC policy via sysctl
+CONFIG_ALPHA_UAC_SYSCTL
+ Configuring the UAC policy on a Linux system usually involves
+ setting a compile time define, if you say Y here and also to
+ sysctl support above, you will be able to modify the UAC policy
+ at runtime using the /proc interface.
+
+ The UAC Policy defines the action Linux should take when an
+ unaligned memory access occurs, the action can include printing
+ a warning message (NOPRINT), sending a signal to help developers
+ debug their applications (SIGBUS), and you can disable the
+ transparent fixing (NOFIX).
+
+ The sysctl's will be initialized to the defined UAC policy, you
+ can change these manually, or with the sysctl(8) userspace
+ utility.
+
+ To disable the warning messages at runtime, you might use
+
+ echo 1 > /proc/sys/kernel/uac/noprint
+
+ Say N if your not sure.
+
Non-standard serial port support
CONFIG_SERIAL_NONSTANDARD
Say Y here if you have any non-standard serial boards -- boards
diff -ruN linux-2.4.21.orig/include/linux/sysctl.h linux-2.4.21/include/linux/sysctl.h
--- linux-2.4.21.orig/include/linux/sysctl.h 2003-06-13 15:51:39.000000000 +0100
+++ linux-2.4.21/include/linux/sysctl.h 2003-07-10 06:58:04.000000000 +0100
@@ -125,6 +125,9 @@
KERN_TAINTED=53, /* int: various kernel tainted flags */
KERN_CADPID=54, /* int: PID of the process to notify on CAD */
KERN_CORE_PATTERN=56, /* string: pattern for core-files */
+#ifdef CONFIG_ALPHA_UAC_SYSCTL
+ KERN_UAC_POLICY=57, /* uac policy */
+#endif
};
@@ -146,6 +149,16 @@
VM_MAX_READAHEAD=13, /* Max file readahead */
};
+#ifdef CONFIG_ALPHA_UAC_SYSCTL
+/* /proc/sys/kernel/uac */
+enum
+{
+ /* UAC policy */
+ KERN_UAC_NOPRINT=1, /* int: printk() on unaligned access */
+ KERN_UAC_SIGBUS=2, /* int: send SIGBUS on unaligned access */
+ KERN_UAC_NOFIX=3, /* int: dont fix. */
+};
+#endif
/* CTL_NET names: */
enum
diff -ruN linux-2.4.21.orig/kernel/sysctl.c linux-2.4.21/kernel/sysctl.c
--- linux-2.4.21.orig/kernel/sysctl.c 2003-06-13 15:51:39.000000000 +0100
+++ linux-2.4.21/kernel/sysctl.c 2003-07-10 06:18:00.000000000 +0100
@@ -97,6 +97,11 @@
extern int acct_parm[];
#endif
+
+#ifdef CONFIG_ALPHA_UAC_SYSCTL
+extern ctl_table uac_table[];
+#endif
+
extern int pgt_cache_water[];
static int parse_table(int *, int, void *, size_t *, void *, size_t,
@@ -259,6 +264,10 @@
{KERN_S390_USER_DEBUG_LOGGING,"userprocess_debug",
&sysctl_userprocess_debug,sizeof(int),0644,NULL,&proc_dointvec},
#endif
+
+#ifdef CONFIG_ALPHA_UAC_SYSCTL
+ {KERN_UAC_POLICY, "uac", NULL, 0, 0555, uac_table},
+#endif
{0}
};
-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/