bci: some more code for testing
[pandora-kernel.git] / security / lowmem.c
index a5b6088..ae78a53 100644 (file)
@@ -23,6 +23,10 @@ enum {
        VM_LOWMEM_ALLOWED_UIDS,
        VM_LOWMEM_ALLOWED_PAGES,
        VM_LOWMEM_FREE_PAGES,
+       VM_LOWMEM_DENY,
+       VM_LOWMEM_LEVEL1_NOTIFY,
+       VM_LOWMEM_LEVEL2_NOTIFY,
+       VM_LOWMEM_USED_PAGES
 };
 
 static long deny_pages;
@@ -33,6 +37,22 @@ static unsigned long lowmem_free_pages;
 static unsigned int allowed_uids[LOWMEM_MAX_UIDS];
 static unsigned int minuid = 1;
 static unsigned int maxuid = 65535;
+static unsigned int deny_percentage;
+static unsigned int l1_notify, l2_notify;
+static long used_pages;
+
+static int
+proc_dointvec_used(ctl_table *table, int write, struct file *filp,
+                       void __user *buffer, size_t *lenp, loff_t *ppos);
+static int
+proc_dointvec_l1_notify(ctl_table *table, int write, struct file *filp,
+                       void __user *buffer, size_t *lenp, loff_t *ppos);
+static int
+proc_dointvec_l2_notify(ctl_table *table, int write, struct file *filp,
+                       void __user *buffer, size_t *lenp, loff_t *ppos);
+static int
+proc_dointvec_deny(ctl_table *table, int write, struct file *filp,
+                       void __user *buffer, size_t *lenp, loff_t *ppos);
 
 static ctl_table lowmem_table[] = {
        {
@@ -44,6 +64,42 @@ static ctl_table lowmem_table[] = {
                .child = NULL,
                .proc_handler = &proc_dointvec,
                .strategy = &sysctl_intvec,
+       }, {
+               .ctl_name = VM_LOWMEM_DENY,
+               .procname = "lowmem_deny_watermark",
+               .data = &deny_percentage,
+               .maxlen = sizeof(unsigned int),
+               .mode = 0444,
+               .child = NULL,
+               .proc_handler = &proc_dointvec_deny,
+               .strategy = &sysctl_intvec,
+       }, {
+               .ctl_name = VM_LOWMEM_LEVEL1_NOTIFY,
+               .procname = "lowmem_notify_low",
+               .data = &l1_notify,
+               .maxlen = sizeof(unsigned int),
+               .mode = 0444,
+               .child = NULL,
+               .proc_handler = &proc_dointvec_l1_notify,
+               .strategy = &sysctl_intvec,
+       }, {
+               .ctl_name = VM_LOWMEM_LEVEL2_NOTIFY,
+               .procname = "lowmem_notify_high",
+               .data = &l2_notify,
+               .maxlen = sizeof(unsigned int),
+               .mode = 0444,
+               .child = NULL,
+               .proc_handler = &proc_dointvec_l2_notify,
+               .strategy = &sysctl_intvec,
+       }, {
+               .ctl_name = VM_LOWMEM_USED_PAGES,
+               .procname = "lowmem_used_pages",
+               .data = &used_pages,
+               .maxlen = sizeof(long),
+               .mode = 0444,
+               .child = NULL,
+               .proc_handler = &proc_dointvec_used,
+               .strategy = &sysctl_intvec,
        }, {
                .ctl_name = VM_LOWMEM_NOTIFY_LOW_PAGES,
                .procname = "lowmem_notify_low_pages",
@@ -121,6 +177,44 @@ static struct kobj_attribute _name##_attr = __ATTR_RO(_name)
 
 static int low_watermark_reached, high_watermark_reached;
 
+static int
+proc_dointvec_l1_notify(ctl_table *table, int write, struct file *filp,
+                       void __user *buffer, size_t *lenp, loff_t *ppos)
+{
+       l1_notify =
+       100 - (100 * notify_low_pages + allowed_pages / 2) / allowed_pages;
+       return proc_dointvec(table, write, filp, buffer, lenp, ppos);
+}
+
+static int
+proc_dointvec_l2_notify(ctl_table *table, int write, struct file *filp,
+                       void __user *buffer, size_t *lenp, loff_t *ppos)
+{
+       l2_notify =
+       100 - (100 * notify_high_pages + allowed_pages / 2) / allowed_pages;
+       return proc_dointvec(table, write, filp, buffer, lenp, ppos);
+}
+
+static int
+proc_dointvec_deny(ctl_table *table, int write, struct file *filp,
+                       void __user *buffer, size_t *lenp, loff_t *ppos)
+{
+       deny_percentage =
+       100 - (100 * deny_pages + allowed_pages / 2) / allowed_pages;
+       return proc_dointvec(table, write, filp, buffer, lenp, ppos);
+}
+
+static int
+proc_dointvec_used(ctl_table *table, int write, struct file *filp,
+                       void __user *buffer, size_t *lenp, loff_t *ppos)
+{
+       if (lowmem_free_pages > 0 && allowed_pages > lowmem_free_pages)
+               used_pages = allowed_pages - lowmem_free_pages;
+       else
+               used_pages = 0;
+       return proc_dointvec(table, write, filp, buffer, lenp, ppos);
+}
+
 static ssize_t low_watermark_show(struct kobject *kobj,
                                  struct kobj_attribute *attr, char *page)
 {
@@ -152,7 +246,7 @@ static void high_watermark_state(int new_state)
        }
 }
 
-static int low_vm_enough_memory(long pages)
+static int low_vm_enough_memory(struct mm_struct *mm, long pages)
 {
        unsigned long free, allowed;
        int cap_sys_admin = 0, notify;
@@ -166,7 +260,7 @@ static int low_vm_enough_memory(long pages)
        /* We activate ourselves only after both parameters have been
         * configured. */
        if (deny_pages == 0 || notify_low_pages == 0 || notify_high_pages == 0)
-               return  __vm_enough_memory(pages, cap_sys_admin);
+               return  __vm_enough_memory(mm, pages, cap_sys_admin);
 
        vm_acct_memory(pages);
 
@@ -230,7 +324,8 @@ enough_memory:
 
 static struct security_operations lowmem_security_ops = {
        /* Use the capability functions for some of the hooks */
-       .ptrace = cap_ptrace,
+       .ptrace_may_access = cap_ptrace_may_access,
+       .ptrace_traceme = cap_ptrace_traceme,
        .capget = cap_capget,
        .capset_check = cap_capset_check,
        .capset_set = cap_capset_set,
@@ -245,8 +340,6 @@ static struct security_operations lowmem_security_ops = {
 };
 
 static struct ctl_table_header *lowmem_table_header;
-/* flag to keep track of how we were registered */
-static int secondary;
 
 static struct attribute *lowmem_attrs[] = {
        &low_watermark_attr.attr,
@@ -265,13 +358,7 @@ static int __init lowmem_init(void)
        /* register ourselves with the security framework */
        if (register_security(&lowmem_security_ops)) {
                printk(KERN_ERR MY_NAME ": Failure registering with the kernel\n");
-               /* try registering with primary module */
-               if (mod_reg_security(MY_NAME, &lowmem_security_ops)) {
-                       printk(KERN_ERR ": Failure registering with the primary"
-                              "security module.\n");
-                       return -EINVAL;
-               }
-               secondary = 1;
+               return -EINVAL;
        }
 
        /* initialize the uids vector */
@@ -291,29 +378,7 @@ static int __init lowmem_init(void)
        return 0;
 }
 
-static void __exit lowmem_exit(void)
-{
-       /* remove ourselves from the security framework */
-       if (secondary) {
-               if (mod_unreg_security(MY_NAME, &lowmem_security_ops))
-                       printk(KERN_ERR MY_NAME ": Failure unregistering "
-                              "with the primary security module.\n");
-       } else {
-               if (unregister_security(&lowmem_security_ops)) {
-                       printk(KERN_ERR MY_NAME ": Failure unregistering "
-                              "with the kernel.\n");
-               }
-       }
-
-       unregister_sysctl_table(lowmem_table_header);
-
-       sysfs_remove_group(kernel_kobj, &lowmem_attr_group);
-
-       printk(KERN_INFO MY_NAME ": Module removed.\n");
-}
-
 module_init(lowmem_init);
-module_exit(lowmem_exit);
 
 MODULE_DESCRIPTION("Low watermark LSM module");
 MODULE_LICENSE("GPL");