|
@@ -70,6 +70,7 @@
|
|
#include <linux/capability.h>
|
|
#include <linux/capability.h>
|
|
#include <linux/fs_struct.h>
|
|
#include <linux/fs_struct.h>
|
|
#include <linux/compat.h>
|
|
#include <linux/compat.h>
|
|
|
|
+#include <linux/ctype.h>
|
|
|
|
|
|
#include "audit.h"
|
|
#include "audit.h"
|
|
|
|
|
|
@@ -81,6 +82,9 @@
|
|
/* no execve audit message should be longer than this (userspace limits) */
|
|
/* no execve audit message should be longer than this (userspace limits) */
|
|
#define MAX_EXECVE_AUDIT_LEN 7500
|
|
#define MAX_EXECVE_AUDIT_LEN 7500
|
|
|
|
|
|
|
|
+/* max length to print of cmdline/proctitle value during audit */
|
|
|
|
+#define MAX_PROCTITLE_AUDIT_LEN 128
|
|
|
|
+
|
|
/* number of audit rules */
|
|
/* number of audit rules */
|
|
int audit_n_rules;
|
|
int audit_n_rules;
|
|
|
|
|
|
@@ -844,6 +848,13 @@ static inline struct audit_context *audit_get_context(struct task_struct *tsk,
|
|
return context;
|
|
return context;
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+static inline void audit_proctitle_free(struct audit_context *context)
|
|
|
|
+{
|
|
|
|
+ kfree(context->proctitle.value);
|
|
|
|
+ context->proctitle.value = NULL;
|
|
|
|
+ context->proctitle.len = 0;
|
|
|
|
+}
|
|
|
|
+
|
|
static inline void audit_free_names(struct audit_context *context)
|
|
static inline void audit_free_names(struct audit_context *context)
|
|
{
|
|
{
|
|
struct audit_names *n, *next;
|
|
struct audit_names *n, *next;
|
|
@@ -956,6 +967,7 @@ static inline void audit_free_context(struct audit_context *context)
|
|
audit_free_aux(context);
|
|
audit_free_aux(context);
|
|
kfree(context->filterkey);
|
|
kfree(context->filterkey);
|
|
kfree(context->sockaddr);
|
|
kfree(context->sockaddr);
|
|
|
|
+ audit_proctitle_free(context);
|
|
kfree(context);
|
|
kfree(context);
|
|
}
|
|
}
|
|
|
|
|
|
@@ -1272,6 +1284,59 @@ static void show_special(struct audit_context *context, int *call_panic)
|
|
audit_log_end(ab);
|
|
audit_log_end(ab);
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+static inline int audit_proctitle_rtrim(char *proctitle, int len)
|
|
|
|
+{
|
|
|
|
+ char *end = proctitle + len - 1;
|
|
|
|
+ while (end > proctitle && !isprint(*end))
|
|
|
|
+ end--;
|
|
|
|
+
|
|
|
|
+ /* catch the case where proctitle is only 1 non-print character */
|
|
|
|
+ len = end - proctitle + 1;
|
|
|
|
+ len -= isprint(proctitle[len-1]) == 0;
|
|
|
|
+ return len;
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+static void audit_log_proctitle(struct task_struct *tsk,
|
|
|
|
+ struct audit_context *context)
|
|
|
|
+{
|
|
|
|
+ int res;
|
|
|
|
+ char *buf;
|
|
|
|
+ char *msg = "(null)";
|
|
|
|
+ int len = strlen(msg);
|
|
|
|
+ struct audit_buffer *ab;
|
|
|
|
+
|
|
|
|
+ ab = audit_log_start(context, GFP_KERNEL, AUDIT_PROCTITLE);
|
|
|
|
+ if (!ab)
|
|
|
|
+ return; /* audit_panic or being filtered */
|
|
|
|
+
|
|
|
|
+ audit_log_format(ab, "proctitle=");
|
|
|
|
+
|
|
|
|
+ /* Not cached */
|
|
|
|
+ if (!context->proctitle.value) {
|
|
|
|
+ buf = kmalloc(MAX_PROCTITLE_AUDIT_LEN, GFP_KERNEL);
|
|
|
|
+ if (!buf)
|
|
|
|
+ goto out;
|
|
|
|
+ /* Historically called this from procfs naming */
|
|
|
|
+ res = get_cmdline(tsk, buf, MAX_PROCTITLE_AUDIT_LEN);
|
|
|
|
+ if (res == 0) {
|
|
|
|
+ kfree(buf);
|
|
|
|
+ goto out;
|
|
|
|
+ }
|
|
|
|
+ res = audit_proctitle_rtrim(buf, res);
|
|
|
|
+ if (res == 0) {
|
|
|
|
+ kfree(buf);
|
|
|
|
+ goto out;
|
|
|
|
+ }
|
|
|
|
+ context->proctitle.value = buf;
|
|
|
|
+ context->proctitle.len = res;
|
|
|
|
+ }
|
|
|
|
+ msg = context->proctitle.value;
|
|
|
|
+ len = context->proctitle.len;
|
|
|
|
+out:
|
|
|
|
+ audit_log_n_untrustedstring(ab, msg, len);
|
|
|
|
+ audit_log_end(ab);
|
|
|
|
+}
|
|
|
|
+
|
|
static void audit_log_exit(struct audit_context *context, struct task_struct *tsk)
|
|
static void audit_log_exit(struct audit_context *context, struct task_struct *tsk)
|
|
{
|
|
{
|
|
int i, call_panic = 0;
|
|
int i, call_panic = 0;
|
|
@@ -1389,6 +1454,8 @@ static void audit_log_exit(struct audit_context *context, struct task_struct *ts
|
|
audit_log_name(context, n, NULL, i++, &call_panic);
|
|
audit_log_name(context, n, NULL, i++, &call_panic);
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+ audit_log_proctitle(tsk, context);
|
|
|
|
+
|
|
/* Send end of event record to help user space know we are finished */
|
|
/* Send end of event record to help user space know we are finished */
|
|
ab = audit_log_start(context, GFP_KERNEL, AUDIT_EOE);
|
|
ab = audit_log_start(context, GFP_KERNEL, AUDIT_EOE);
|
|
if (ab)
|
|
if (ab)
|