]> git.karo-electronics.de Git - mv-sheeva.git/blobdiff - kernel/audit.c
ide-cd: fix 'ireason' handling for REQ_TYPE_ATA_PC requests
[mv-sheeva.git] / kernel / audit.c
index 549b2f55b649ab58fad267aa6643d34de3479ed8..2eeea9a142408a156f0897a75c81343a5619c07c 100644 (file)
@@ -70,6 +70,7 @@ static int    audit_initialized;
 #define AUDIT_ON       1
 #define AUDIT_LOCKED   2
 int            audit_enabled;
+int            audit_ever_enabled;
 
 /* Default state when kernel boots without any parameters. */
 static int     audit_default;
@@ -165,7 +166,8 @@ void audit_panic(const char *message)
        case AUDIT_FAIL_SILENT:
                break;
        case AUDIT_FAIL_PRINTK:
-               printk(KERN_ERR "audit: %s\n", message);
+               if (printk_ratelimit())
+                       printk(KERN_ERR "audit: %s\n", message);
                break;
        case AUDIT_FAIL_PANIC:
                panic("audit: %s\n", message);
@@ -233,11 +235,13 @@ void audit_log_lost(const char *message)
        }
 
        if (print) {
-               printk(KERN_WARNING
-                      "audit: audit_lost=%d audit_rate_limit=%d audit_backlog_limit=%d\n",
-                      atomic_read(&audit_lost),
-                      audit_rate_limit,
-                      audit_backlog_limit);
+               if (printk_ratelimit())
+                       printk(KERN_WARNING
+                               "audit: audit_lost=%d audit_rate_limit=%d "
+                               "audit_backlog_limit=%d\n",
+                               atomic_read(&audit_lost),
+                               audit_rate_limit,
+                               audit_backlog_limit);
                audit_panic(message);
        }
 }
@@ -310,11 +314,17 @@ static int audit_set_backlog_limit(int limit, uid_t loginuid, u32 sid)
 
 static int audit_set_enabled(int state, uid_t loginuid, u32 sid)
 {
+       int rc;
        if (state < AUDIT_OFF || state > AUDIT_LOCKED)
                return -EINVAL;
 
-       return audit_do_config_change("audit_enabled", &audit_enabled, state,
-                                     loginuid, sid);
+       rc =  audit_do_config_change("audit_enabled", &audit_enabled, state,
+                                    loginuid, sid);
+
+       if (!rc)
+               audit_ever_enabled |= !!state;
+
+       return rc;
 }
 
 static int audit_set_failure(int state, uid_t loginuid, u32 sid)
@@ -345,7 +355,11 @@ static int kauditd_thread(void *dummy)
                                        audit_pid = 0;
                                }
                        } else {
-                               printk(KERN_NOTICE "%s\n", skb->data + NLMSG_SPACE(0));
+                               if (printk_ratelimit())
+                                       printk(KERN_NOTICE "%s\n", skb->data +
+                                               NLMSG_SPACE(0));
+                               else
+                                       audit_log_lost("printk limit exceeded\n");
                                kfree_skb(skb);
                        }
                } else {
@@ -857,6 +871,7 @@ static int __init audit_init(void)
        skb_queue_head_init(&audit_skb_queue);
        audit_initialized = 1;
        audit_enabled = audit_default;
+       audit_ever_enabled |= !!audit_default;
 
        /* Register the callback with selinux.  This callback will be invoked
         * when a new policy is loaded. */
@@ -884,8 +899,10 @@ static int __init audit_enable(char *str)
        printk(KERN_INFO "audit: %s%s\n",
               audit_default ? "enabled" : "disabled",
               audit_initialized ? "" : " (after initialization)");
-       if (audit_initialized)
+       if (audit_initialized) {
                audit_enabled = audit_default;
+               audit_ever_enabled |= !!audit_default;
+       }
        return 1;
 }
 
@@ -1022,7 +1039,7 @@ struct audit_buffer *audit_log_start(struct audit_context *ctx, gfp_t gfp_mask,
 {
        struct audit_buffer     *ab     = NULL;
        struct timespec         t;
-       unsigned int            serial;
+       unsigned int            uninitialized_var(serial);
        int reserve;
        unsigned long timeout_start = jiffies;
 
@@ -1056,7 +1073,7 @@ struct audit_buffer *audit_log_start(struct audit_context *ctx, gfp_t gfp_mask,
                        remove_wait_queue(&audit_backlog_wait, &wait);
                        continue;
                }
-               if (audit_rate_check())
+               if (audit_rate_check() && printk_ratelimit())
                        printk(KERN_WARNING
                               "audit: audit_backlog=%d > "
                               "audit_backlog_limit=%d\n",
@@ -1141,6 +1158,7 @@ static void audit_log_vformat(struct audit_buffer *ab, const char *fmt,
                        goto out;
                len = vsnprintf(skb_tail_pointer(skb), avail, fmt, args2);
        }
+       va_end(args2);
        if (len > 0)
                skb_put(skb, len);
 out:
@@ -1294,26 +1312,26 @@ void audit_log_untrustedstring(struct audit_buffer *ab, const char *string)
 
 /* This is a helper-function to print the escaped d_path */
 void audit_log_d_path(struct audit_buffer *ab, const char *prefix,
-                     struct dentry *dentry, struct vfsmount *vfsmnt)
+                     struct path *path)
 {
-       char *p, *path;
+       char *p, *pathname;
 
        if (prefix)
                audit_log_format(ab, " %s", prefix);
 
        /* We will allow 11 spaces for ' (deleted)' to be appended */
-       path = kmalloc(PATH_MAX+11, ab->gfp_mask);
-       if (!path) {
+       pathname = kmalloc(PATH_MAX+11, ab->gfp_mask);
+       if (!pathname) {
                audit_log_format(ab, "<no memory>");
                return;
        }
-       p = d_path(dentry, vfsmnt, path, PATH_MAX+11);
+       p = d_path(path, pathname, PATH_MAX+11);
        if (IS_ERR(p)) { /* Should never happen since we send PATH_MAX */
                /* FIXME: can we save some information here? */
                audit_log_format(ab, "<too long>");
        } else
                audit_log_untrustedstring(ab, p);
-       kfree(path);
+       kfree(pathname);
 }
 
 /**
@@ -1338,9 +1356,11 @@ void audit_log_end(struct audit_buffer *ab)
                        skb_queue_tail(&audit_skb_queue, ab->skb);
                        ab->skb = NULL;
                        wake_up_interruptible(&kauditd_wait);
-               } else {
+               } else if (printk_ratelimit()) {
                        struct nlmsghdr *nlh = nlmsg_hdr(ab->skb);
                        printk(KERN_NOTICE "type=%d %s\n", nlh->nlmsg_type, ab->skb->data + NLMSG_SPACE(0));
+               } else {
+                       audit_log_lost("printk limit exceeded\n");
                }
        }
        audit_buffer_free(ab);