diff options
author | Al Viro <viro@zeniv.linux.org.uk> | 2008-01-10 04:53:18 -0500 |
---|---|---|
committer | Al Viro <viro@zeniv.linux.org.uk> | 2008-02-01 14:05:28 -0500 |
commit | bfef93a5d1fb5654fe2025276c55e202d10b5255 (patch) | |
tree | 573d8153c5d5216b0c4007b652286eeddd3c0987 /kernel | |
parent | 0c11b9428f619ab377c92eff2f160a834a6585dd (diff) |
[PATCH] get rid of loginuid races
Keeping loginuid in audit_context is racy and results in messier
code. Taken to task_struct, out of the way of ->audit_context
changes.
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
Diffstat (limited to 'kernel')
-rw-r--r-- | kernel/auditsc.c | 56 |
1 files changed, 15 insertions, 41 deletions
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) | |||
783 | static inline void audit_zero_context(struct audit_context *context, | 782 | static 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 | ||
793 | static inline struct audit_context *audit_alloc_context(enum audit_state state) | 789 | static 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 | */ | ||
1807 | uid_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 | |||
1813 | EXPORT_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); |