aboutsummaryrefslogtreecommitdiffstats
path: root/kernel/auditsc.c
diff options
context:
space:
mode:
authorAmy Griffis <amy.griffis@hp.com>2007-03-29 18:01:04 -0400
committerAl Viro <viro@zeniv.linux.org.uk>2007-05-11 05:38:25 -0400
commite54dc2431d740a79a6bd013babade99d71b1714f (patch)
tree16b0990d5c16946239a17b332f54b5918fb03305 /kernel/auditsc.c
parent7f13da40e36c84d0d046b7adbd060af7d3717250 (diff)
[PATCH] audit signal recipients
When auditing syscalls that send signals, log the pid and security context for each target process. Optimize the data collection by adding a counter for signal-related rules, and avoiding allocating an aux struct unless we have more than one target process. For process groups, collect pid/context data in blocks of 16. Move the audit_signal_info() hook up in check_kill_permission() so we audit attempts where permission is denied. Signed-off-by: Amy Griffis <amy.griffis@hp.com> Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
Diffstat (limited to 'kernel/auditsc.c')
-rw-r--r--kernel/auditsc.c111
1 files changed, 92 insertions, 19 deletions
diff --git a/kernel/auditsc.c b/kernel/auditsc.c
index 2243c559bc03..6aff0df75568 100644
--- a/kernel/auditsc.c
+++ b/kernel/auditsc.c
@@ -89,6 +89,9 @@ extern int audit_enabled;
89/* number of audit rules */ 89/* number of audit rules */
90int audit_n_rules; 90int audit_n_rules;
91 91
92/* determines whether we collect data for signals sent */
93int audit_signals;
94
92/* When fs/namei.c:getname() is called, we store the pointer in name and 95/* When fs/namei.c:getname() is called, we store the pointer in name and
93 * we don't let putname() free it (instead we free all of the saved 96 * we don't let putname() free it (instead we free all of the saved
94 * pointers at syscall exit time). 97 * pointers at syscall exit time).
@@ -114,6 +117,9 @@ struct audit_aux_data {
114 117
115#define AUDIT_AUX_IPCPERM 0 118#define AUDIT_AUX_IPCPERM 0
116 119
120/* Number of target pids per aux struct. */
121#define AUDIT_AUX_PIDS 16
122
117struct audit_aux_data_mq_open { 123struct audit_aux_data_mq_open {
118 struct audit_aux_data d; 124 struct audit_aux_data d;
119 int oflag; 125 int oflag;
@@ -181,6 +187,13 @@ struct audit_aux_data_path {
181 struct vfsmount *mnt; 187 struct vfsmount *mnt;
182}; 188};
183 189
190struct audit_aux_data_pids {
191 struct audit_aux_data d;
192 pid_t target_pid[AUDIT_AUX_PIDS];
193 u32 target_sid[AUDIT_AUX_PIDS];
194 int pid_count;
195};
196
184/* The per-task audit context. */ 197/* The per-task audit context. */
185struct audit_context { 198struct audit_context {
186 int dummy; /* must be the first element */ 199 int dummy; /* must be the first element */
@@ -201,6 +214,7 @@ struct audit_context {
201 struct vfsmount * pwdmnt; 214 struct vfsmount * pwdmnt;
202 struct audit_context *previous; /* For nested syscalls */ 215 struct audit_context *previous; /* For nested syscalls */
203 struct audit_aux_data *aux; 216 struct audit_aux_data *aux;
217 struct audit_aux_data *aux_pids;
204 218
205 /* Save things to print about task_struct */ 219 /* Save things to print about task_struct */
206 pid_t pid, ppid; 220 pid_t pid, ppid;
@@ -657,6 +671,10 @@ static inline void audit_free_aux(struct audit_context *context)
657 context->aux = aux->next; 671 context->aux = aux->next;
658 kfree(aux); 672 kfree(aux);
659 } 673 }
674 while ((aux = context->aux_pids)) {
675 context->aux_pids = aux->next;
676 kfree(aux);
677 }
660} 678}
661 679
662static inline void audit_zero_context(struct audit_context *context, 680static inline void audit_zero_context(struct audit_context *context,
@@ -798,6 +816,29 @@ static void audit_log_task_info(struct audit_buffer *ab, struct task_struct *tsk
798 audit_log_task_context(ab); 816 audit_log_task_context(ab);
799} 817}
800 818
819static int audit_log_pid_context(struct audit_context *context, pid_t pid,
820 u32 sid)
821{
822 struct audit_buffer *ab;
823 char *s = NULL;
824 u32 len;
825 int rc = 0;
826
827 ab = audit_log_start(context, GFP_KERNEL, AUDIT_OBJ_PID);
828 if (!ab)
829 return 1;
830
831 if (selinux_sid_to_string(sid, &s, &len)) {
832 audit_log_format(ab, "opid=%d obj=(none)", pid);
833 rc = 1;
834 } else
835 audit_log_format(ab, "opid=%d obj=%s", pid, s);
836 audit_log_end(ab);
837 kfree(s);
838
839 return rc;
840}
841
801static void audit_log_exit(struct audit_context *context, struct task_struct *tsk) 842static void audit_log_exit(struct audit_context *context, struct task_struct *tsk)
802{ 843{
803 int i, call_panic = 0; 844 int i, call_panic = 0;
@@ -976,23 +1017,21 @@ static void audit_log_exit(struct audit_context *context, struct task_struct *ts
976 audit_log_end(ab); 1017 audit_log_end(ab);
977 } 1018 }
978 1019
979 if (context->target_pid) { 1020 for (aux = context->aux_pids; aux; aux = aux->next) {
980 ab =audit_log_start(context, GFP_KERNEL, AUDIT_OBJ_PID); 1021 struct audit_aux_data_pids *axs = (void *)aux;
981 if (ab) { 1022 int i;
982 char *s = NULL, *t; 1023
983 u32 len; 1024 for (i = 0; i < axs->pid_count; i++)
984 if (selinux_sid_to_string(context->target_sid, 1025 if (audit_log_pid_context(context, axs->target_pid[i],
985 &s, &len)) 1026 axs->target_sid[i]))
986 t = "(none)"; 1027 call_panic = 1;
987 else
988 t = s;
989 audit_log_format(ab, "opid=%d obj=%s",
990 context->target_pid, t);
991 audit_log_end(ab);
992 kfree(s);
993 }
994 } 1028 }
995 1029
1030 if (context->target_pid &&
1031 audit_log_pid_context(context, context->target_pid,
1032 context->target_sid))
1033 call_panic = 1;
1034
996 if (context->pwd && context->pwdmnt) { 1035 if (context->pwd && context->pwdmnt) {
997 ab = audit_log_start(context, GFP_KERNEL, AUDIT_CWD); 1036 ab = audit_log_start(context, GFP_KERNEL, AUDIT_CWD);
998 if (ab) { 1037 if (ab) {
@@ -1213,7 +1252,10 @@ void audit_syscall_exit(int valid, long return_code)
1213 } else { 1252 } else {
1214 audit_free_names(context); 1253 audit_free_names(context);
1215 audit_free_aux(context); 1254 audit_free_aux(context);
1255 context->aux = NULL;
1256 context->aux_pids = NULL;
1216 context->target_pid = 0; 1257 context->target_pid = 0;
1258 context->target_sid = 0;
1217 kfree(context->filterkey); 1259 kfree(context->filterkey);
1218 context->filterkey = NULL; 1260 context->filterkey = NULL;
1219 tsk->audit_context = context; 1261 tsk->audit_context = context;
@@ -1947,15 +1989,17 @@ int audit_avc_path(struct dentry *dentry, struct vfsmount *mnt)
1947 * If the audit subsystem is being terminated, record the task (pid) 1989 * If the audit subsystem is being terminated, record the task (pid)
1948 * and uid that is doing that. 1990 * and uid that is doing that.
1949 */ 1991 */
1950void __audit_signal_info(int sig, struct task_struct *t) 1992int __audit_signal_info(int sig, struct task_struct *t)
1951{ 1993{
1994 struct audit_aux_data_pids *axp;
1995 struct task_struct *tsk = current;
1996 struct audit_context *ctx = tsk->audit_context;
1952 extern pid_t audit_sig_pid; 1997 extern pid_t audit_sig_pid;
1953 extern uid_t audit_sig_uid; 1998 extern uid_t audit_sig_uid;
1954 extern u32 audit_sig_sid; 1999 extern u32 audit_sig_sid;
1955 2000
1956 if (sig == SIGTERM || sig == SIGHUP || sig == SIGUSR1) { 2001 if (audit_pid && t->tgid == audit_pid &&
1957 struct task_struct *tsk = current; 2002 (sig == SIGTERM || sig == SIGHUP || sig == SIGUSR1)) {
1958 struct audit_context *ctx = tsk->audit_context;
1959 audit_sig_pid = tsk->pid; 2003 audit_sig_pid = tsk->pid;
1960 if (ctx) 2004 if (ctx)
1961 audit_sig_uid = ctx->loginuid; 2005 audit_sig_uid = ctx->loginuid;
@@ -1963,4 +2007,33 @@ void __audit_signal_info(int sig, struct task_struct *t)
1963 audit_sig_uid = tsk->uid; 2007 audit_sig_uid = tsk->uid;
1964 selinux_get_task_sid(tsk, &audit_sig_sid); 2008 selinux_get_task_sid(tsk, &audit_sig_sid);
1965 } 2009 }
2010
2011 if (!audit_signals) /* audit_context checked in wrapper */
2012 return 0;
2013
2014 /* optimize the common case by putting first signal recipient directly
2015 * in audit_context */
2016 if (!ctx->target_pid) {
2017 ctx->target_pid = t->tgid;
2018 selinux_get_task_sid(t, &ctx->target_sid);
2019 return 0;
2020 }
2021
2022 axp = (void *)ctx->aux_pids;
2023 if (!axp || axp->pid_count == AUDIT_AUX_PIDS) {
2024 axp = kzalloc(sizeof(*axp), GFP_ATOMIC);
2025 if (!axp)
2026 return -ENOMEM;
2027
2028 axp->d.type = AUDIT_OBJ_PID;
2029 axp->d.next = ctx->aux_pids;
2030 ctx->aux_pids = (void *)axp;
2031 }
2032 BUG_ON(axp->pid_count > AUDIT_AUX_PIDS);
2033
2034 axp->target_pid[axp->pid_count] = t->tgid;
2035 selinux_get_task_sid(t, &axp->target_sid[axp->pid_count]);
2036 axp->pid_count++;
2037
2038 return 0;
1966} 2039}