*  'R' - User forced a module unload.
  *  'M' - Machine had a machine check experience.
  *  'B' - System has hit bad_page.
+ *  'U' - Userspace-defined naughtiness.
  *
  *     The string is overwritten by the next call to print_taint().
  */
 {
        static char buf[20];
        if (tainted) {
-               snprintf(buf, sizeof(buf), "Tainted: %c%c%c%c%c%c",
+               snprintf(buf, sizeof(buf), "Tainted: %c%c%c%c%c%c%c",
                        tainted & TAINT_PROPRIETARY_MODULE ? 'P' : 'G',
                        tainted & TAINT_FORCED_MODULE ? 'F' : ' ',
                        tainted & TAINT_UNSAFE_SMP ? 'S' : ' ',
                        tainted & TAINT_FORCED_RMMOD ? 'R' : ' ',
                        tainted & TAINT_MACHINE_CHECK ? 'M' : ' ',
-                       tainted & TAINT_BAD_PAGE ? 'B' : ' ');
+                       tainted & TAINT_BAD_PAGE ? 'B' : ' ',
+                       tainted & TAINT_USER ? 'U' : ' ');
        }
        else
                snprintf(buf, sizeof(buf), "Not tainted");
 
 #ifdef CONFIG_PROC_SYSCTL
 static int proc_do_cad_pid(ctl_table *table, int write, struct file *filp,
                  void __user *buffer, size_t *lenp, loff_t *ppos);
+static int proc_dointvec_taint(ctl_table *table, int write, struct file *filp,
+                              void __user *buffer, size_t *lenp, loff_t *ppos);
 #endif
 
 static ctl_table root_table[];
 int sysctl_legacy_va_layout;
 #endif
 
+
 static void *get_uts(ctl_table *table, int write)
 {
        char *which = table->data;
                .proc_handler   = &proc_dostring,
                .strategy       = &sysctl_string,
        },
+#ifdef CONFIG_PROC_SYSCTL
        {
                .ctl_name       = KERN_TAINTED,
                .procname       = "tainted",
                .data           = &tainted,
                .maxlen         = sizeof(int),
-               .mode           = 0444,
-               .proc_handler   = &proc_dointvec,
+               .mode           = 0644,
+               .proc_handler   = &proc_dointvec_taint,
        },
+#endif
        {
                .ctl_name       = KERN_CAP_BSET,
                .procname       = "cap-bound",
 
 #define OP_SET 0
 #define OP_AND 1
+#define OP_OR  2
 
 static int do_proc_dointvec_bset_conv(int *negp, unsigned long *lvalp,
                                      int *valp,
                switch(op) {
                case OP_SET:    *valp = val; break;
                case OP_AND:    *valp &= val; break;
+               case OP_OR:     *valp |= val; break;
                }
        } else {
                int val = *valp;
                                do_proc_dointvec_bset_conv,&op);
 }
 
+/*
+ *     Taint values can only be increased
+ */
+static int proc_dointvec_taint(ctl_table *table, int write, struct file *filp,
+                              void __user *buffer, size_t *lenp, loff_t *ppos)
+{
+       int op;
+
+       if (!capable(CAP_SYS_ADMIN))
+               return -EPERM;
+
+       op = OP_OR;
+       return do_proc_dointvec(table,write,filp,buffer,lenp,ppos,
+                               do_proc_dointvec_bset_conv,&op);
+}
+
 struct do_proc_dointvec_minmax_conv_param {
        int *min;
        int *max;