aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--include/linux/audit.h2
-rw-r--r--include/linux/init_task.h7
-rw-r--r--include/linux/sched.h3
-rw-r--r--kernel/auditsc.c56
4 files changed, 26 insertions, 42 deletions
diff --git a/include/linux/audit.h b/include/linux/audit.h
index f63117fab305..d7c6a12f4d1c 100644
--- a/include/linux/audit.h
+++ b/include/linux/audit.h
@@ -409,7 +409,7 @@ extern unsigned int audit_serial(void);
409extern void auditsc_get_stamp(struct audit_context *ctx, 409extern void auditsc_get_stamp(struct audit_context *ctx,
410 struct timespec *t, unsigned int *serial); 410 struct timespec *t, unsigned int *serial);
411extern int audit_set_loginuid(struct task_struct *task, uid_t loginuid); 411extern int audit_set_loginuid(struct task_struct *task, uid_t loginuid);
412extern uid_t audit_get_loginuid(struct task_struct *task); 412#define audit_get_loginuid(t) ((t)->loginuid)
413extern void audit_log_task_context(struct audit_buffer *ab); 413extern void audit_log_task_context(struct audit_buffer *ab);
414extern int __audit_ipc_obj(struct kern_ipc_perm *ipcp); 414extern int __audit_ipc_obj(struct kern_ipc_perm *ipcp);
415extern int __audit_ipc_set_perm(unsigned long qbytes, uid_t uid, gid_t gid, mode_t mode); 415extern int __audit_ipc_set_perm(unsigned long qbytes, uid_t uid, gid_t gid, mode_t mode);
diff --git a/include/linux/init_task.h b/include/linux/init_task.h
index e6b3f7080679..ea3e9efd7396 100644
--- a/include/linux/init_task.h
+++ b/include/linux/init_task.h
@@ -114,6 +114,12 @@ extern struct group_info init_groups;
114 .pid = &init_struct_pid, \ 114 .pid = &init_struct_pid, \
115} 115}
116 116
117#ifdef CONFIG_AUDITSYSCALL
118#define INIT_IDS \
119 .loginuid = -1,
120#else
121#define INIT_IDS
122#endif
117/* 123/*
118 * INIT_TASK is used to set up the first task table, touch at 124 * INIT_TASK is used to set up the first task table, touch at
119 * your own risk!. Base=0, limit=0x1fffff (=2MB) 125 * your own risk!. Base=0, limit=0x1fffff (=2MB)
@@ -173,6 +179,7 @@ extern struct group_info init_groups;
173 [PIDTYPE_SID] = INIT_PID_LINK(PIDTYPE_SID), \ 179 [PIDTYPE_SID] = INIT_PID_LINK(PIDTYPE_SID), \
174 }, \ 180 }, \
175 .dirties = INIT_PROP_LOCAL_SINGLE(dirties), \ 181 .dirties = INIT_PROP_LOCAL_SINGLE(dirties), \
182 INIT_IDS \
176 INIT_TRACE_IRQFLAGS \ 183 INIT_TRACE_IRQFLAGS \
177 INIT_LOCKDEP \ 184 INIT_LOCKDEP \
178} 185}
diff --git a/include/linux/sched.h b/include/linux/sched.h
index 6c333579d9da..5e2730389089 100644
--- a/include/linux/sched.h
+++ b/include/linux/sched.h
@@ -1139,6 +1139,9 @@ struct task_struct {
1139 void *security; 1139 void *security;
1140#endif 1140#endif
1141 struct audit_context *audit_context; 1141 struct audit_context *audit_context;
1142#ifdef CONFIG_AUDITSYSCALL
1143 uid_t loginuid;
1144#endif
1142 seccomp_t seccomp; 1145 seccomp_t seccomp;
1143 1146
1144/* Thread group tracking */ 1147/* Thread group tracking */
diff --git a/kernel/auditsc.c b/kernel/auditsc.c
index bd4e0a2443fb..c95173a194bf 100644
--- a/kernel/auditsc.c
+++ b/kernel/auditsc.c
@@ -192,7 +192,6 @@ struct audit_context {
192 enum audit_state state; 192 enum audit_state state;
193 unsigned int serial; /* serial number for record */ 193 unsigned int serial; /* serial number for record */
194 struct timespec ctime; /* time of syscall entry */ 194 struct timespec ctime; /* time of syscall entry */
195 uid_t loginuid; /* login uid (identity) */
196 int major; /* syscall number */ 195 int major; /* syscall number */
197 unsigned long argv[4]; /* syscall arguments */ 196 unsigned long argv[4]; /* syscall arguments */
198 int return_valid; /* return code is valid */ 197 int return_valid; /* return code is valid */
@@ -506,7 +505,7 @@ static int audit_filter_rules(struct task_struct *tsk,
506 case AUDIT_LOGINUID: 505 case AUDIT_LOGINUID:
507 result = 0; 506 result = 0;
508 if (ctx) 507 if (ctx)
509 result = audit_comparator(ctx->loginuid, f->op, f->val); 508 result = audit_comparator(tsk->loginuid, f->op, f->val);
510 break; 509 break;
511 case AUDIT_SUBJ_USER: 510 case AUDIT_SUBJ_USER:
512 case AUDIT_SUBJ_ROLE: 511 case AUDIT_SUBJ_ROLE:
@@ -783,11 +782,8 @@ static inline void audit_free_aux(struct audit_context *context)
783static inline void audit_zero_context(struct audit_context *context, 782static inline void audit_zero_context(struct audit_context *context,
784 enum audit_state state) 783 enum audit_state state)
785{ 784{
786 uid_t loginuid = context->loginuid;
787
788 memset(context, 0, sizeof(*context)); 785 memset(context, 0, sizeof(*context));
789 context->state = state; 786 context->state = state;
790 context->loginuid = loginuid;
791} 787}
792 788
793static inline struct audit_context *audit_alloc_context(enum audit_state state) 789static inline struct audit_context *audit_alloc_context(enum audit_state state)
@@ -826,11 +822,6 @@ int audit_alloc(struct task_struct *tsk)
826 return -ENOMEM; 822 return -ENOMEM;
827 } 823 }
828 824
829 /* Preserve login uid */
830 context->loginuid = -1;
831 if (current->audit_context)
832 context->loginuid = current->audit_context->loginuid;
833
834 tsk->audit_context = context; 825 tsk->audit_context = context;
835 set_tsk_thread_flag(tsk, TIF_SYSCALL_AUDIT); 826 set_tsk_thread_flag(tsk, TIF_SYSCALL_AUDIT);
836 return 0; 827 return 0;
@@ -1047,7 +1038,7 @@ static void audit_log_exit(struct audit_context *context, struct task_struct *ts
1047 context->name_count, 1038 context->name_count,
1048 context->ppid, 1039 context->ppid,
1049 context->pid, 1040 context->pid,
1050 context->loginuid, 1041 tsk->loginuid,
1051 context->uid, 1042 context->uid,
1052 context->gid, 1043 context->gid,
1053 context->euid, context->suid, context->fsuid, 1044 context->euid, context->suid, context->fsuid,
@@ -1779,40 +1770,23 @@ int audit_set_loginuid(struct task_struct *task, uid_t loginuid)
1779{ 1770{
1780 struct audit_context *context = task->audit_context; 1771 struct audit_context *context = task->audit_context;
1781 1772
1782 if (context) { 1773 if (context && context->in_syscall) {
1783 /* Only log if audit is enabled */ 1774 struct audit_buffer *ab;
1784 if (context->in_syscall) { 1775
1785 struct audit_buffer *ab; 1776 ab = audit_log_start(NULL, GFP_KERNEL, AUDIT_LOGIN);
1786 1777 if (ab) {
1787 ab = audit_log_start(NULL, GFP_KERNEL, AUDIT_LOGIN); 1778 audit_log_format(ab, "login pid=%d uid=%u "
1788 if (ab) { 1779 "old auid=%u new auid=%u",
1789 audit_log_format(ab, "login pid=%d uid=%u " 1780 task->pid, task->uid,
1790 "old auid=%u new auid=%u", 1781 task->loginuid, loginuid);
1791 task->pid, task->uid, 1782 audit_log_end(ab);
1792 context->loginuid, loginuid);
1793 audit_log_end(ab);
1794 }
1795 } 1783 }
1796 context->loginuid = loginuid;
1797 } 1784 }
1785 task->loginuid = loginuid;
1798 return 0; 1786 return 0;
1799} 1787}
1800 1788
1801/** 1789/**
1802 * audit_get_loginuid - get the loginuid for an audit_context
1803 * @ctx: the audit_context
1804 *
1805 * Returns the context's loginuid or -1 if @ctx is NULL.
1806 */
1807uid_t audit_get_loginuid(struct task_struct *task)
1808{
1809 struct audit_context *ctx = task->audit_context;
1810 return ctx ? ctx->loginuid : -1;
1811}
1812
1813EXPORT_SYMBOL(audit_get_loginuid);
1814
1815/**
1816 * __audit_mq_open - record audit data for a POSIX MQ open 1790 * __audit_mq_open - record audit data for a POSIX MQ open
1817 * @oflag: open flag 1791 * @oflag: open flag
1818 * @mode: mode bits 1792 * @mode: mode bits
@@ -2217,8 +2191,8 @@ int __audit_signal_info(int sig, struct task_struct *t)
2217 if (audit_pid && t->tgid == audit_pid) { 2191 if (audit_pid && t->tgid == audit_pid) {
2218 if (sig == SIGTERM || sig == SIGHUP || sig == SIGUSR1) { 2192 if (sig == SIGTERM || sig == SIGHUP || sig == SIGUSR1) {
2219 audit_sig_pid = tsk->pid; 2193 audit_sig_pid = tsk->pid;
2220 if (ctx) 2194 if (tsk->loginuid != -1)
2221 audit_sig_uid = ctx->loginuid; 2195 audit_sig_uid = tsk->loginuid;
2222 else 2196 else
2223 audit_sig_uid = tsk->uid; 2197 audit_sig_uid = tsk->uid;
2224 selinux_get_task_sid(tsk, &audit_sig_sid); 2198 selinux_get_task_sid(tsk, &audit_sig_sid);