diff options
| author | Serge Hallyn <serue@us.ibm.com> | 2005-02-01 16:50:56 -0800 |
|---|---|---|
| committer | Linus Torvalds <torvalds@ppc970.osdl.org> | 2005-02-01 16:50:56 -0800 |
| commit | d5290d8844886cb66ab4a00ef3bc9cc4a7f14ce3 (patch) | |
| tree | 1b77c5df022df7b9a761fd1dea760d55c55066dc /kernel | |
| parent | fe3a3a34e01c31ca6dfa4c72581e07ab2792cd22 (diff) | |
[PATCH] audit: handle loginuid through proc
The audit subsystem uses netlink messages to request loginuid changes. Due
to the sensitivity of loginuid, netlink appears to be insufficient. For
instance, it is not easy to guarantee that the loginuid message will be
handled before any other auditable actions, and there is even the remote
possibility of the process terminating and another process with the same
pid being created before the message is handled. Finally, other kernel
code, in particular selinux, is interested in easily querying the loginuid
for inclusion in its own messages.
The following patch moves loginuid handling from netlink to the
/proc/$$/loginuid file, and adds a audit_get_loginuid() function. It also
includes Stephen Smalley's patch to correctly inherit the loginuid on fork.
It has been actively discussed on the linux-audit mailing list.
Signed-off-by: Serge Hallyn <serue@us.ibm.com>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
Diffstat (limited to 'kernel')
| -rw-r--r-- | kernel/audit.c | 28 | ||||
| -rw-r--r-- | kernel/auditsc.c | 23 |
2 files changed, 24 insertions, 27 deletions
diff --git a/kernel/audit.c b/kernel/audit.c index 480b6eaa0675..9b48512a4cf5 100644 --- a/kernel/audit.c +++ b/kernel/audit.c @@ -145,6 +145,11 @@ struct audit_buffer { int count; /* Times requeued */ }; +void audit_set_type(struct audit_buffer *ab, int type) +{ + ab->type = type; +} + struct audit_entry { struct list_head list; struct audit_rule rule; @@ -312,7 +317,6 @@ static int audit_netlink_ok(kernel_cap_t eff_cap, u16 msg_type) case AUDIT_GET: case AUDIT_LIST: case AUDIT_SET: - case AUDIT_LOGIN: case AUDIT_ADD: case AUDIT_DEL: if (!cap_raised(eff_cap, CAP_AUDIT_CONTROL)) @@ -334,7 +338,6 @@ static int audit_receive_msg(struct sk_buff *skb, struct nlmsghdr *nlh) u32 uid, pid, seq; void *data; struct audit_status *status_get, status_set; - struct audit_login *login; int err; struct audit_buffer *ab; u16 msg_type = nlh->nlmsg_type; @@ -397,27 +400,6 @@ static int audit_receive_msg(struct sk_buff *skb, struct nlmsghdr *nlh) ab->pid = pid; audit_log_end(ab); break; - case AUDIT_LOGIN: - if (nlh->nlmsg_len < sizeof(struct audit_login)) - return -EINVAL; - login = (struct audit_login *)data; - ab = audit_log_start(NULL); - if (ab) { - audit_log_format(ab, "login pid=%d uid=%d loginuid=%d" - " length=%d msg='%.1024s'", - pid, uid, - login->loginuid, - login->msglen, - login->msg); - ab->type = AUDIT_LOGIN; - ab->pid = pid; - audit_log_end(ab); - } -#ifdef CONFIG_AUDITSYSCALL - err = audit_set_loginuid(current->audit_context, - login->loginuid); -#endif - break; case AUDIT_ADD: case AUDIT_DEL: if (nlh->nlmsg_len < sizeof(struct audit_rule)) diff --git a/kernel/auditsc.c b/kernel/auditsc.c index 5efa31c1dc83..c412d6779733 100644 --- a/kernel/auditsc.c +++ b/kernel/auditsc.c @@ -547,8 +547,8 @@ int audit_alloc(struct task_struct *tsk) /* Preserve login uid */ context->loginuid = -1; - if (tsk->audit_context) - context->loginuid = tsk->audit_context->loginuid; + if (current->audit_context) + context->loginuid = current->audit_context->loginuid; tsk->audit_context = context; set_tsk_thread_flag(tsk, TIF_SYSCALL_AUDIT); @@ -903,12 +903,27 @@ void audit_get_stamp(struct audit_context *ctx, } } +extern int audit_set_type(struct audit_buffer *ab, int type); + int audit_set_loginuid(struct audit_context *ctx, uid_t loginuid) { if (ctx) { - if (loginuid < 0) - return -EINVAL; + struct audit_buffer *ab; + + ab = audit_log_start(NULL); + if (ab) { + audit_log_format(ab, "login pid=%d uid=%u " + "old loginuid=%u new loginuid=%u", + ctx->pid, ctx->uid, ctx->loginuid, loginuid); + audit_set_type(ab, AUDIT_LOGIN); + audit_log_end(ab); + } ctx->loginuid = loginuid; } return 0; } + +uid_t audit_get_loginuid(struct audit_context *ctx) +{ + return ctx ? ctx->loginuid : -1; +} |
