[POWERPC] Implement SLB shadow buffer
[powerpc.git] / kernel / audit.c
index 0fbf1c1..d417ca1 100644 (file)
@@ -445,7 +445,7 @@ void audit_send_reply(int pid, int seq, int type, int done, int multi,
  * Check for appropriate CAP_AUDIT_ capabilities on incoming audit
  * control messages.
  */
-static int audit_netlink_ok(kernel_cap_t eff_cap, u16 msg_type)
+static int audit_netlink_ok(struct sk_buff *skb, u16 msg_type)
 {
        int err = 0;
 
@@ -459,13 +459,13 @@ static int audit_netlink_ok(kernel_cap_t eff_cap, u16 msg_type)
        case AUDIT_DEL:
        case AUDIT_DEL_RULE:
        case AUDIT_SIGNAL_INFO:
-               if (!cap_raised(eff_cap, CAP_AUDIT_CONTROL))
+               if (security_netlink_recv(skb, CAP_AUDIT_CONTROL))
                        err = -EPERM;
                break;
        case AUDIT_USER:
        case AUDIT_FIRST_USER_MSG...AUDIT_LAST_USER_MSG:
        case AUDIT_FIRST_USER_MSG2...AUDIT_LAST_USER_MSG2:
-               if (!cap_raised(eff_cap, CAP_AUDIT_WRITE))
+               if (security_netlink_recv(skb, CAP_AUDIT_WRITE))
                        err = -EPERM;
                break;
        default:  /* bad msg */
@@ -488,7 +488,7 @@ static int audit_receive_msg(struct sk_buff *skb, struct nlmsghdr *nlh)
        char                    *ctx;
        u32                     len;
 
-       err = audit_netlink_ok(NETLINK_CB(skb).eff_cap, msg_type);
+       err = audit_netlink_ok(skb, msg_type);
        if (err)
                return err;
 
@@ -818,7 +818,7 @@ err:
  */
 unsigned int audit_serial(void)
 {
-       static spinlock_t serial_lock = SPIN_LOCK_UNLOCKED;
+       static DEFINE_SPINLOCK(serial_lock);
        static unsigned int serial = 0;
 
        unsigned long flags;
@@ -1051,20 +1051,53 @@ void audit_log_hex(struct audit_buffer *ab, const unsigned char *buf,
        skb_put(skb, len << 1); /* new string is twice the old string */
 }
 
+/*
+ * Format a string of no more than slen characters into the audit buffer,
+ * enclosed in quote marks.
+ */
+static void audit_log_n_string(struct audit_buffer *ab, size_t slen,
+                              const char *string)
+{
+       int avail, new_len;
+       unsigned char *ptr;
+       struct sk_buff *skb;
+
+       BUG_ON(!ab->skb);
+       skb = ab->skb;
+       avail = skb_tailroom(skb);
+       new_len = slen + 3;     /* enclosing quotes + null terminator */
+       if (new_len > avail) {
+               avail = audit_expand(ab, new_len);
+               if (!avail)
+                       return;
+       }
+       ptr = skb->tail;
+       *ptr++ = '"';
+       memcpy(ptr, string, slen);
+       ptr += slen;
+       *ptr++ = '"';
+       *ptr = 0;
+       skb_put(skb, slen + 2); /* don't include null terminator */
+}
+
 /**
- * audit_log_unstrustedstring - log a string that may contain random characters
+ * audit_log_n_unstrustedstring - log a string that may contain random characters
  * @ab: audit_buffer
+ * @len: lenth of string (not including trailing null)
  * @string: string to be logged
  *
  * This code will escape a string that is passed to it if the string
  * contains a control character, unprintable character, double quote mark,
  * or a space. Unescaped strings will start and end with a double quote mark.
  * Strings that are escaped are printed in hex (2 digits per char).
+ *
+ * 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_untrustedstring(struct audit_buffer *ab, const char *string)
+const char *audit_log_n_untrustedstring(struct audit_buffer *ab, size_t len,
+                                       const char *string)
 {
        const unsigned char *p = string;
-       size_t len = strlen(string);
 
        while (*p) {
                if (*p == '"' || *p < 0x21 || *p > 0x7f) {
@@ -1073,10 +1106,23 @@ const char *audit_log_untrustedstring(struct audit_buffer *ab, const char *strin
                }
                p++;
        }
-       audit_log_format(ab, "\"%s\"", string);
+       audit_log_n_string(ab, len, string);
        return p + 1;
 }
 
+/**
+ * audit_log_unstrustedstring - log a string that may contain random characters
+ * @ab: audit_buffer
+ * @string: string to be logged
+ *
+ * Same as audit_log_n_unstrustedstring(), except that strlen is used to
+ * determine string length.
+ */
+const char *audit_log_untrustedstring(struct audit_buffer *ab, const char *string)
+{
+       return audit_log_n_untrustedstring(ab, strlen(string), 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)