aboutsummaryrefslogtreecommitdiffstats
path: root/kernel/audit.c
diff options
context:
space:
mode:
Diffstat (limited to 'kernel/audit.c')
-rw-r--r--kernel/audit.c71
1 files changed, 48 insertions, 23 deletions
diff --git a/kernel/audit.c b/kernel/audit.c
index e6d88635032c..dae3570b3a3b 100644
--- a/kernel/audit.c
+++ b/kernel/audit.c
@@ -692,7 +692,8 @@ static void audit_log_vformat(struct audit_buffer *ab, const char *fmt,
692 goto out; 692 goto out;
693 len = vsnprintf(skb->tail, avail, fmt, args2); 693 len = vsnprintf(skb->tail, avail, fmt, args2);
694 } 694 }
695 skb_put(skb, (len < avail) ? len : avail); 695 if (len > 0)
696 skb_put(skb, len);
696out: 697out:
697 return; 698 return;
698} 699}
@@ -710,20 +711,47 @@ void audit_log_format(struct audit_buffer *ab, const char *fmt, ...)
710 va_end(args); 711 va_end(args);
711} 712}
712 713
713void audit_log_hex(struct audit_buffer *ab, const unsigned char *buf, size_t len) 714/* This function will take the passed buf and convert it into a string of
715 * ascii hex digits. The new string is placed onto the skb. */
716void audit_log_hex(struct audit_buffer *ab, const unsigned char *buf,
717 size_t len)
714{ 718{
715 int i; 719 int i, avail, new_len;
720 unsigned char *ptr;
721 struct sk_buff *skb;
722 static const unsigned char *hex = "0123456789ABCDEF";
723
724 BUG_ON(!ab->skb);
725 skb = ab->skb;
726 avail = skb_tailroom(skb);
727 new_len = len<<1;
728 if (new_len >= avail) {
729 /* Round the buffer request up to the next multiple */
730 new_len = AUDIT_BUFSIZ*(((new_len-avail)/AUDIT_BUFSIZ) + 1);
731 avail = audit_expand(ab, new_len);
732 if (!avail)
733 return;
734 }
716 735
717 for (i=0; i<len; i++) 736 ptr = skb->tail;
718 audit_log_format(ab, "%02x", buf[i]); 737 for (i=0; i<len; i++) {
738 *ptr++ = hex[(buf[i] & 0xF0)>>4]; /* Upper nibble */
739 *ptr++ = hex[buf[i] & 0x0F]; /* Lower nibble */
740 }
741 *ptr = 0;
742 skb_put(skb, len << 1); /* new string is twice the old string */
719} 743}
720 744
745/* This code will escape a string that is passed to it if the string
746 * contains a control character, unprintable character, double quote mark,
747 * or a space. Unescaped strings will start and end with a double quote mark.
748 * Strings that are escaped are printed in hex (2 digits per char). */
721void audit_log_untrustedstring(struct audit_buffer *ab, const char *string) 749void audit_log_untrustedstring(struct audit_buffer *ab, const char *string)
722{ 750{
723 const unsigned char *p = string; 751 const unsigned char *p = string;
724 752
725 while (*p) { 753 while (*p) {
726 if (*p == '"' || *p == ' ' || *p < 0x20 || *p > 0x7f) { 754 if (*p == '"' || *p < 0x21 || *p > 0x7f) {
727 audit_log_hex(ab, string, strlen(string)); 755 audit_log_hex(ab, string, strlen(string));
728 return; 756 return;
729 } 757 }
@@ -732,31 +760,28 @@ void audit_log_untrustedstring(struct audit_buffer *ab, const char *string)
732 audit_log_format(ab, "\"%s\"", string); 760 audit_log_format(ab, "\"%s\"", string);
733} 761}
734 762
735 763/* This is a helper-function to print the escaped d_path */
736/* This is a helper-function to print the d_path without using a static
737 * buffer or allocating another buffer in addition to the one in
738 * audit_buffer. */
739void audit_log_d_path(struct audit_buffer *ab, const char *prefix, 764void audit_log_d_path(struct audit_buffer *ab, const char *prefix,
740 struct dentry *dentry, struct vfsmount *vfsmnt) 765 struct dentry *dentry, struct vfsmount *vfsmnt)
741{ 766{
742 char *p; 767 char *p, *path;
743 struct sk_buff *skb = ab->skb;
744 int len, avail;
745 768
746 if (prefix) 769 if (prefix)
747 audit_log_format(ab, " %s", prefix); 770 audit_log_format(ab, " %s", prefix);
748 771
749 avail = skb_tailroom(skb); 772 /* We will allow 11 spaces for ' (deleted)' to be appended */
750 p = d_path(dentry, vfsmnt, skb->tail, avail); 773 path = kmalloc(PATH_MAX+11, GFP_KERNEL);
751 if (IS_ERR(p)) { 774 if (!path) {
752 /* FIXME: can we save some information here? */ 775 audit_log_format(ab, "<no memory>");
753 audit_log_format(ab, "<toolong>"); 776 return;
754 } else {
755 /* path isn't at start of buffer */
756 len = ((char *)skb->tail + avail - 1) - p;
757 memmove(skb->tail, p, len);
758 skb_put(skb, len);
759 } 777 }
778 p = d_path(dentry, vfsmnt, path, PATH_MAX+11);
779 if (IS_ERR(p)) { /* Should never happen since we send PATH_MAX */
780 /* FIXME: can we save some information here? */
781 audit_log_format(ab, "<too long>");
782 } else
783 audit_log_untrustedstring(ab, p);
784 kfree(path);
760} 785}
761 786
762/* Remove queued messages from the audit_txlist and send them to user space. */ 787/* Remove queued messages from the audit_txlist and send them to user space. */