2.4.21: Optionally Configure UAC Policy via Sysctl (Alpha)
PATCH 1/1 2.4.21: Optionally Configure UAC Policy via Sysctl (Alpha)
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.
Signature · 209 lines
------------------------------------- [email protected] | 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} };
Review
Quoted 3 lines · Tavis Ormandy
(quoted diff) +3
-0+ To disable the warning messages at runtime, you might use + + echo 1 > /proc/sys/kernel/uac/noprint
It's really bad idea. Unaligned traps are *bugs*, so we don't want to hide them. Especially system-wide.
You can do all the same per process, using existing OSF-compatible UAC control.
Ivan.
Quoted 8 lines · Ivan Kokshaysky
Review
Quoted 3 lines · Tavis Ormandy
(quoted diff) +3
-0+ To disable the warning messages at runtime, you might use + + echo 1 > /proc/sys/kernel/uac/noprintIt's really bad idea. Unaligned traps are *bugs*, so we don't want to hide them. Especially system-wide.
It's true that that they are bugs, but on such widespread errors that are transparently fixed by the kernel, do we really need to be reminded every time such an event occurs?
$ grep unaligned /proc/cpuinfo kernel unaligned acc : 0 (pc=0,va=0) user unaligned acc : 4400 (pc=30281c8c434,va=30281db8f62)
This machine has been up just a few hours, and already a has fixed a lot of these errors. I really dont need the signal:noise ratio of my logs diluted by this, unless im searching for bugs, which is why a sysctl makes sense, imo.
Quoted 3 lines
You can do all the same per process, using existing OSF-compatible UAC control.
True, and thats _really_ useful for turning the messages _on_ for the application your working with/debugging/etc, system-wide messages just dont make sense to me.
Also, it is optional, so only users who foresee wanting to disable the messages will do so.
Signature · 3 lines
------------------------------------- [email protected] | finger me for my gpg key. -------------------------------------------------------