Linux Headquarters
[ Register ]
[ About us ] [ Home Page ]

Advertisement
[ Kernel ] [ Documentation ] [ Links ] [ Books ]

Advertisement

Kernel v2.6.24-git22 /kernel/audit.c

Filename:/kernel/audit.c
Lines Added:185
Lines Deleted:259
Also changed in: (Previous) 2.6.24-git21  2.6.24-git20  2.6.24-git19  2.6.24-git18  2.6.24-git17  2.6.24-git16 
(Following) 2.6.24.3-rc1  2.6.24.3  2.6.24.4  2.6.24.5  2.6.24.6  2.6.24.7 

Location
[  2.6.24-git22
  [  kernel
     o  audit.c

Patch

diff --git a/kernel/audit.c b/kernel/audit.c
index f93c271..c8555b1 100644
--- a/kernel/audit.c
+++ b/kernel/audit.c
@@ -66,10 +66,11 @@
  * (Initialization happens after skb_init is called.) */
 static int   audit_initialized;
 
-/* 0 - no auditing
- * 1 - auditing enabled
- * 2 - auditing enabled and configuration is locked/unchangeable. */
+#define AUDIT_OFF   0
+#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;
@@ -152,8 +153,10 @@ struct audit_buffer {
 
 static void audit_set_pid(struct audit_buffer *ab, pid_t pid)
 {
-   struct nlmsghdr *nlh = nlmsg_hdr(ab->skb);
-   nlh->nlmsg_pid = pid;
+   if (ab) {
+      struct nlmsghdr *nlh = nlmsg_hdr(ab->skb);
+      nlh->nlmsg_pid = pid;
+   }
 }
 
 void audit_panic(const char *message)
@@ -163,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);
@@ -231,161 +235,107 @@ 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);
    }
 }
 
-static int audit_set_rate_limit(int limit, uid_t loginuid, u32 sid)
+static int audit_log_config_change(char *function_name, int new, int old,
+               uid_t loginuid, u32 sid, int allow_changes)
 {
-   int res, rc = 0, old = audit_rate_limit;
-
-   /* check if we are locked */
-   if (audit_enabled == 2)
-      res = 0;
-   else
-      res = 1;
+   struct audit_buffer *ab;
+   int rc = 0;
 
+   ab = audit_log_start(NULL, GFP_KERNEL, AUDIT_CONFIG_CHANGE);
+   audit_log_format(ab, "%s=%d old=%d by auid=%u", function_name, new,
+          old, loginuid);
    if (sid) {
       char *ctx = NULL;
       u32 len;
-      if ((rc = selinux_sid_to_string(sid, &ctx, &len)) == 0) {
-         audit_log(NULL, GFP_KERNEL, AUDIT_CONFIG_CHANGE,
-            "audit_rate_limit=%d old=%d by auid=%u"
-            " subj=%s res=%d",
-            limit, old, loginuid, ctx, res);
+
+      rc = selinux_sid_to_string(sid, &ctx, &len);
+      if (rc) {
+         audit_log_format(ab, " sid=%u", sid);
+         allow_changes = 0; /* Something weird, deny request */
+      } else {
+         audit_log_format(ab, " subj=%s", ctx);
          kfree(ctx);
-      } else
-         res = 0; /* Something weird, deny request */
+      }
    }
-   audit_log(NULL, GFP_KERNEL, AUDIT_CONFIG_CHANGE,
-      "audit_rate_limit=%d old=%d by auid=%u res=%d",
-      limit, old, loginuid, res);
-
-   /* If we are allowed, make the change */
-   if (res == 1)
-      audit_rate_limit = limit;
-   /* Not allowed, update reason */
-   else if (rc == 0)
-      rc = -EPERM;
+   audit_log_format(ab, " res=%d", allow_changes);
+   audit_log_end(ab);
    return rc;
 }
 
-static int audit_set_backlog_limit(int limit, uid_t loginuid, u32 sid)
+static int audit_do_config_change(char *function_name, int *to_change,
+              int new, uid_t loginuid, u32 sid)
 {
-   int res, rc = 0, old = audit_backlog_limit;
+   int allow_changes, rc = 0, old = *to_change;
 
    /* check if we are locked */
-   if (audit_enabled == 2)
-      res = 0;
+   if (audit_enabled == AUDIT_LOCKED)
+      allow_changes = 0;
    else
-      res = 1;
+      allow_changes = 1;
 
-   if (sid) {
-      char *ctx = NULL;
-      u32 len;
-      if ((rc = selinux_sid_to_string(sid, &ctx, &len)) == 0) {
-         audit_log(NULL, GFP_KERNEL, AUDIT_CONFIG_CHANGE,
-            "audit_backlog_limit=%d old=%d by auid=%u"
-            " subj=%s res=%d",
-            limit, old, loginuid, ctx, res);
-         kfree(ctx);
-      } else
-         res = 0; /* Something weird, deny request */
+   if (audit_enabled != AUDIT_OFF) {
+      rc = audit_log_config_change(function_name, new, old,
+                    loginuid, sid, allow_changes);
+      if (rc)
+         allow_changes = 0;
    }
-   audit_log(NULL, GFP_KERNEL, AUDIT_CONFIG_CHANGE,
-      "audit_backlog_limit=%d old=%d by auid=%u res=%d",
-      limit, old, loginuid, res);
 
    /* If we are allowed, make the change */
-   if (res == 1)
-      audit_backlog_limit = limit;
+   if (allow_changes == 1)
+      *to_change = new;
    /* Not allowed, update reason */
    else if (rc == 0)
       rc = -EPERM;
    return rc;
 }
 
-static int audit_set_enabled(int state, uid_t loginuid, u32 sid)
+static int audit_set_rate_limit(int limit, uid_t loginuid, u32 sid)
 {
-   int res, rc = 0, old = audit_enabled;
+   return audit_do_config_change("audit_rate_limit", &audit_rate_limit,
+                  limit, loginuid, sid);
+}
+
+static int audit_set_backlog_limit(int limit, uid_t loginuid, u32 sid)
+{
+   return audit_do_config_change("audit_backlog_limit", &audit_backlog_limit,
+                  limit, loginuid, sid);
+}
 
-   if (state < 0 || state > 2)
+static int audit_set_enabled(int state, uid_t loginuid, u32 sid)
+{
+   int rc;
+   if (state < AUDIT_OFF || state > AUDIT_LOCKED)
       return -EINVAL;
 
-   /* check if we are locked */
-   if (audit_enabled == 2)
-      res = 0;
-   else
-      res = 1;
+   rc =  audit_do_config_change("audit_enabled", &audit_enabled, state,
+                 loginuid, sid);
 
-   if (sid) {
-      char *ctx = NULL;
-      u32 len;
-      if ((rc = selinux_sid_to_string(sid, &ctx, &len)) == 0) {
-         audit_log(NULL, GFP_KERNEL, AUDIT_CONFIG_CHANGE,
-            "audit_enabled=%d old=%d by auid=%u"
-            " subj=%s res=%d",
-            state, old, loginuid, ctx, res);
-         kfree(ctx);
-      } else
-         res = 0; /* Something weird, deny request */
-   }
-   audit_log(NULL, GFP_KERNEL, AUDIT_CONFIG_CHANGE,
-      "audit_enabled=%d old=%d by auid=%u res=%d",
-      state, old, loginuid, res);
+   if (!rc)
+      audit_ever_enabled |= !!state;
 
-   /* If we are allowed, make the change */
-   if (res == 1)
-      audit_enabled = state;
-   /* Not allowed, update reason */
-   else if (rc == 0)
-      rc = -EPERM;
    return rc;
 }
 
 static int audit_set_failure(int state, uid_t loginuid, u32 sid)
 {
-   int res, rc = 0, old = audit_failure;
-
    if (state != AUDIT_FAIL_SILENT
        && state != AUDIT_FAIL_PRINTK
        && state != AUDIT_FAIL_PANIC)
       return -EINVAL;
 
-   /* check if we are locked */
-   if (audit_enabled == 2)
-      res = 0;
-   else
-      res = 1;
-
-   if (sid) {
-      char *ctx = NULL;
-      u32 len;
-      if ((rc = selinux_sid_to_string(sid, &ctx, &len)) == 0) {
-         audit_log(NULL, GFP_KERNEL, AUDIT_CONFIG_CHANGE,
-            "audit_failure=%d old=%d by auid=%u"
-            " subj=%s res=%d",
-            state, old, loginuid, ctx, res);
-         kfree(ctx);
-      } else
-         res = 0; /* Something weird, deny request */
-   }
-   audit_log(NULL, GFP_KERNEL, AUDIT_CONFIG_CHANGE,
-      "audit_failure=%d old=%d by auid=%u res=%d",
-      state, old, loginuid, res);
-
-   /* If we are allowed, make the change */
-   if (res == 1)
-      audit_failure = state;
-   /* Not allowed, update reason */
-   else if (rc == 0)
-      rc = -EPERM;
-   return rc;
+   return audit_do_config_change("audit_failure", &audit_failure, state,
+                  loginuid, sid);
 }
 
 static int kauditd_thread(void *dummy)
@@ -405,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 {
@@ -573,6 +527,33 @@ static int audit_netlink_ok(struct sk_buff *skb, u16 msg_type)
    return err;
 }
 
+static int audit_log_common_recv_msg(struct audit_buffer **ab, u16 msg_type,
+                 u32 pid, u32 uid, uid_t auid, u32 sid)
+{
+   int rc = 0;
+   char *ctx = NULL;
+   u32 len;
+
+   if (!audit_enabled) {
+      *ab = NULL;
+      return rc;
+   }
+
+   *ab = audit_log_start(NULL, GFP_KERNEL, msg_type);
+   audit_log_format(*ab, "user pid=%d uid=%u auid=%u",
+          pid, uid, auid);
+   if (sid) {
+      rc = selinux_sid_to_string(sid, &ctx, &len);
+      if (rc)
+         audit_log_format(*ab, " ssid=%u", sid);
+      else
+         audit_log_format(*ab, " subj=%s", ctx);
+      kfree(ctx);
+   }
+
+   return rc;
+}
+
 static int audit_receive_msg(struct sk_buff *skb, struct nlmsghdr *nlh)
 {
    u32         uid, pid, seq, sid;
@@ -583,7 +564,7 @@ static int audit_receive_msg(struct sk_buff *skb, struct nlmsghdr *nlh)
    u16         msg_type = nlh->nlmsg_type;
    uid_t         loginuid; /* loginuid of sender */
    struct audit_sig_info   *sig_data;
-   char         *ctx;
+   char         *ctx = NULL;
    u32         len;
 
    err = audit_netlink_ok(skb, msg_type);
@@ -634,23 +615,14 @@ static int audit_receive_msg(struct sk_buff *skb, struct nlmsghdr *nlh)
          if (err < 0) return err;
       }
       if (status_get->mask & AUDIT_STATUS_PID) {
-         int old   = audit_pid;
-         if (sid) {
-            if ((err = selinux_sid_to_string(
-                  sid, &ctx, &len)))
-               return err;
-            else
-               audit_log(NULL, GFP_KERNEL,
-                  AUDIT_CONFIG_CHANGE,
-                  "audit_pid=%d old=%d by auid=%u subj=%s",
-                  status_get->pid, old,
-                  loginuid, ctx);
-            kfree(ctx);
-         } else
-            audit_log(NULL, GFP_KERNEL, AUDIT_CONFIG_CHANGE,
-               "audit_pid=%d old=%d by auid=%u",
-                 status_get->pid, old, loginuid);
-         audit_pid = status_get->pid;
+         int new_pid = status_get->pid;
+
+         if (audit_enabled != AUDIT_OFF)
+            audit_log_config_change("audit_pid", new_pid,
+                     audit_pid, loginuid,
+                     sid, 1);
+
+         audit_pid = new_pid;
       }
       if (status_get->mask & AUDIT_STATUS_RATE_LIMIT)
          err = audit_set_rate_limit(status_get->rate_limit,
@@ -673,64 +645,35 @@ static int audit_receive_msg(struct sk_buff *skb, struct nlmsghdr *nlh)
             if (err)
                break;
          }
-         ab = audit_log_start(NULL, GFP_KERNEL, msg_type);
-         if (ab) {
-            audit_log_format(ab,
-                   "user pid=%d uid=%u auid=%u",
-                   pid, uid, loginuid);
-            if (sid) {
-               if (selinux_sid_to_string(
-                     sid, &ctx, &len)) {
-                  audit_log_format(ab,
-                     " ssid=%u", sid);
-                  /* Maybe call audit_panic? */
-               } else
-                  audit_log_format(ab,
-                     " subj=%s", ctx);
-               kfree(ctx);
-            }
-            if (msg_type != AUDIT_USER_TTY)
-               audit_log_format(ab, " msg='%.1024s'",
-                      (char *)data);
-            else {
-               int size;
-
-               audit_log_format(ab, " msg=");
-               size = nlmsg_len(nlh);
-               audit_log_n_untrustedstring(ab, size,
-                            data);
-            }
-            audit_set_pid(ab, pid);
-            audit_log_end(ab);
+         audit_log_common_recv_msg(&ab, msg_type, pid, uid,
+                    loginuid, sid);
+
+         if (msg_type != AUDIT_USER_TTY)
+            audit_log_format(ab, " msg='%.1024s'",
+                   (char *)data);
+         else {
+            int size;
+
+            audit_log_format(ab, " msg=");
+            size = nlmsg_len(nlh);
+            audit_log_n_untrustedstring(ab, size,
+                         data);
          }
+         audit_set_pid(ab, pid);
+         audit_log_end(ab);
       }
       break;
    case AUDIT_ADD:
    case AUDIT_DEL:
       if (nlmsg_len(nlh) < sizeof(struct audit_rule))
          return -EINVAL;
-      if (audit_enabled == 2) {
-         ab = audit_log_start(NULL, GFP_KERNEL,
-               AUDIT_CONFIG_CHANGE);
-         if (ab) {
-            audit_log_format(ab,
-                   "pid=%d uid=%u auid=%u",
-                   pid, uid, loginuid);
-            if (sid) {
-               if (selinux_sid_to_string(
-                     sid, &ctx, &len)) {
-                  audit_log_format(ab,
-                     " ssid=%u", sid);
-                  /* Maybe call audit_panic? */
-               } else
-                  audit_log_format(ab,
-                     " subj=%s", ctx);
-               kfree(ctx);
-            }
-            audit_log_format(ab, " audit_enabled=%d res=0",
-               audit_enabled);
-            audit_log_end(ab);
-         }
+      if (audit_enabled == AUDIT_LOCKED) {
+         audit_log_common_recv_msg(&ab, AUDIT_CONFIG_CHANGE, pid,
+                    uid, loginuid, sid);
+
+         audit_log_format(ab, " audit_enabled=%d res=0",
+                audit_enabled);
+         audit_log_end(ab);
          return -EPERM;
       }
       /* fallthrough */
@@ -743,28 +686,13 @@ static int audit_receive_msg(struct sk_buff *skb, struct nlmsghdr *nlh)
    case AUDIT_DEL_RULE:
       if (nlmsg_len(nlh) < sizeof(struct audit_rule_data))
          return -EINVAL;
-      if (audit_enabled == 2) {
-         ab = audit_log_start(NULL, GFP_KERNEL,
-               AUDIT_CONFIG_CHANGE);
-         if (ab) {
-            audit_log_format(ab,
-                   "pid=%d uid=%u auid=%u",
-                   pid, uid, loginuid);
-            if (sid) {
-               if (selinux_sid_to_string(
-                     sid, &ctx, &len)) {
-                  audit_log_format(ab,
-                     " ssid=%u", sid);
-                  /* Maybe call audit_panic? */
-               } else
-                  audit_log_format(ab,
-                     " subj=%s", ctx);
-               kfree(ctx);
-            }
-            audit_log_format(ab, " audit_enabled=%d res=0",
-               audit_enabled);
-            audit_log_end(ab);
-         }
+      if (audit_enabled == AUDIT_LOCKED) {
+         audit_log_common_recv_msg(&ab, AUDIT_CONFIG_CHANGE, pid,
+                    uid, loginuid, sid);
+
+         audit_log_format(ab, " audit_enabled=%d res=0",
+                audit_enabled);
+         audit_log_end(ab);
          return -EPERM;
       }
       /* fallthrough */
@@ -775,19 +703,10 @@ static int audit_receive_msg(struct sk_buff *skb, struct nlmsghdr *nlh)
       break;
    case AUDIT_TRIM:
       audit_trim_trees();
-      ab = audit_log_start(NULL, GFP_KERNEL, AUDIT_CONFIG_CHANGE);
-      if (!ab)
-         break;
-      audit_log_format(ab, "auid=%u", loginuid);
-      if (sid) {
-         u32 len;
-         ctx = NULL;
-         if (selinux_sid_to_string(sid, &ctx, &len))
-            audit_log_format(ab, " ssid=%u", sid);
-         else
-            audit_log_format(ab, " subj=%s", ctx);
-         kfree(ctx);
-      }
+
+      audit_log_common_recv_msg(&ab, AUDIT_CONFIG_CHANGE, pid,
+                 uid, loginuid, sid);
+
       audit_log_format(ab, " op=trim res=1");
       audit_log_end(ab);
       break;
@@ -817,22 +736,9 @@ static int audit_receive_msg(struct sk_buff *skb, struct nlmsghdr *nlh)
       /* OK, here comes... */
       err = audit_tag_tree(old, new);
 
-      ab = audit_log_start(NULL, GFP_KERNEL, AUDIT_CONFIG_CHANGE);
-      if (!ab) {
-         kfree(old);
-         kfree(new);
-         break;
-      }
-      audit_log_format(ab, "auid=%u", loginuid);
-      if (sid) {
-         u32 len;
-         ctx = NULL;
-         if (selinux_sid_to_string(sid, &ctx, &len))
-            audit_log_format(ab, " ssid=%u", sid);
-         else
-            audit_log_format(ab, " subj=%s", ctx);
-         kfree(ctx);
-      }
+      audit_log_common_recv_msg(&ab, AUDIT_CONFIG_CHANGE, pid,
+                 uid, loginuid, sid);
+
       audit_log_format(ab, " op=make_equiv old=");
       audit_log_untrustedstring(ab, old);
       audit_log_format(ab, " new=");
@@ -965,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. */
@@ -992,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;
 }
 
@@ -1130,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;
 
@@ -1164,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",
@@ -1200,13 +1109,17 @@ struct audit_buffer *audit_log_start(struct audit_context *ctx, gfp_t gfp_mask,
 static inline int audit_expand(struct audit_buffer *ab, int extra)
 {
    struct sk_buff *skb = ab->skb;
-   int ret = pskb_expand_head(skb, skb_headroom(skb), extra,
-               ab->gfp_mask);
+   int oldtail = skb_tailroom(skb);
+   int ret = pskb_expand_head(skb, 0, extra, ab->gfp_mask);
+   int newtail = skb_tailroom(skb);
+
    if (ret < 0) {
       audit_log_lost("out of memory in audit_expand");
       return 0;
    }
-   return skb_tailroom(skb);
+
+   skb->truesize += newtail - oldtail;
+   return newtail;
 }
 
 /*
@@ -1245,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:
@@ -1346,6 +1260,21 @@ static void audit_log_n_string(struct audit_buffer *ab, size_t slen,
 }
 
 /**
+ * audit_string_contains_control - does a string need to be logged in hex
+ * @string - string to be checked
+ * @len - max length of the string to check
+ */
+int audit_string_contains_control(const char *string, size_t len)
+{
+   const unsigned char *p;
+   for (p = string; p < (const unsigned char *)string + len && *p; p++) {
+      if (*p == '"' || *p < 0x21 || *p > 0x7f)
+         return 1;
+   }
+   return 0;
+}
+
+/**
  * audit_log_n_untrustedstring - log a string that may contain random characters
  * @ab: audit_buffer
  * @len: lenth of string (not including trailing null)
@@ -1359,19 +1288,13 @@ static void audit_log_n_string(struct audit_buffer *ab, size_t slen,
  * The caller specifies the number of characters in the string to log, which may
  * or may not be the entire string.
  */
-const char *audit_log_n_untrustedstring(struct audit_buffer *ab, size_t len,
-               const char *string)
+void audit_log_n_untrustedstring(struct audit_buffer *ab, size_t len,
+             const char *string)
 {
-   const unsigned char *p;
-
-   for (p = string; p < (const unsigned char *)string + len && *p; p++) {
-      if (*p == '"' || *p < 0x21 || *p > 0x7f) {
-         audit_log_hex(ab, string, len);
-         return string + len + 1;
-      }
-   }
-   audit_log_n_string(ab, len, string);
-   return p + 1;
+   if (audit_string_contains_control(string, len))
+      audit_log_hex(ab, string, len);
+   else
+      audit_log_n_string(ab, len, string);
 }
 
 /**
@@ -1382,9 +1305,9 @@ const char *audit_log_n_untrustedstring(struct audit_buffer *ab, size_t len,
  * Same as audit_log_n_untrustedstring(), except that strlen is used to
  * determine string length.
  */
-const char *audit_log_untrustedstring(struct audit_buffer *ab, const char *string)
+void audit_log_untrustedstring(struct audit_buffer *ab, const char *string)
 {
-   return audit_log_n_untrustedstring(ab, strlen(string), string);
+   audit_log_n_untrustedstring(ab, strlen(string), string);
 }
 
 /* This is a helper-function to print the escaped d_path */
@@ -1433,8 +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 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 {
-         printk(KERN_NOTICE "%s\n", ab->skb->data + NLMSG_SPACE(0));
+         audit_log_lost("printk limit exceeded\n");
       }
    }
    audit_buffer_free(ab);


Comments: webmaster (at) linuxhq.com.
Advertising: banners (at) linuxhq.com.
Compilation ©1998-2008 Linux Headquarters, Inc.