summaryrefslogtreecommitdiff
path: root/kernel
diff options
context:
space:
mode:
authorSerge Hallyn <serue@us.ibm.com>2005-02-01 16:50:56 -0800
committerLinus Torvalds <torvalds@ppc970.osdl.org>2005-02-01 16:50:56 -0800
commitd5290d8844886cb66ab4a00ef3bc9cc4a7f14ce3 (patch)
tree1b77c5df022df7b9a761fd1dea760d55c55066dc /kernel
parentfe3a3a34e01c31ca6dfa4c72581e07ab2792cd22 (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.c28
-rw-r--r--kernel/auditsc.c23
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;
+}