diff options
| -rw-r--r-- | include/linux/audit.h | 2 | ||||
| -rw-r--r-- | include/linux/init_task.h | 7 | ||||
| -rw-r--r-- | include/linux/sched.h | 3 | ||||
| -rw-r--r-- | kernel/auditsc.c | 56 |
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); | |||
| 409 | extern void auditsc_get_stamp(struct audit_context *ctx, | 409 | extern void auditsc_get_stamp(struct audit_context *ctx, |
| 410 | struct timespec *t, unsigned int *serial); | 410 | struct timespec *t, unsigned int *serial); |
| 411 | extern int audit_set_loginuid(struct task_struct *task, uid_t loginuid); | 411 | extern int audit_set_loginuid(struct task_struct *task, uid_t loginuid); |
| 412 | extern uid_t audit_get_loginuid(struct task_struct *task); | 412 | #define audit_get_loginuid(t) ((t)->loginuid) |
| 413 | extern void audit_log_task_context(struct audit_buffer *ab); | 413 | extern void audit_log_task_context(struct audit_buffer *ab); |
| 414 | extern int __audit_ipc_obj(struct kern_ipc_perm *ipcp); | 414 | extern int __audit_ipc_obj(struct kern_ipc_perm *ipcp); |
| 415 | extern int __audit_ipc_set_perm(unsigned long qbytes, uid_t uid, gid_t gid, mode_t mode); | 415 | extern 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) | |||
| 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); |
