Received: by 2002:ac0:a5a7:0:0:0:0:0 with SMTP id m36-v6csp30279imm; Tue, 31 Jul 2018 13:13:06 -0700 (PDT) X-Google-Smtp-Source: AAOMgpekQu6eDfTRbmQBCGSxJHqmjeqgoX6a+kbgZErjON6Pa5bMjixghrtdc8w1rERz/xbU1pX3 X-Received: by 2002:a63:121a:: with SMTP id h26-v6mr22159329pgl.316.1533067986718; Tue, 31 Jul 2018 13:13:06 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1533067986; cv=none; d=google.com; s=arc-20160816; b=wnM7oA73maXgmGWQULNrknjBP00ymNKcMQT5yeow2bUV5+wy3aSc85Q1h6H/1v3kJA vX6pSGKzqz7aKSBA4r/Jx0ZpYKps/Xyu8kxIKSCQ/9+D0IM1M/H6If+gGXL6QtX0hJR/ MtdNd/zaOyLtndRsxBe2JuBtqqucWXdaqFPls2dgQDLFU8KRQ4u3lmXQQeWUmXuQB6DG FhwZdtflVHgZfQ3MApK7BExKGkCEFpPT7Ufr/6xKm9W7/zap9ABA9c2LLotjfDnMa4zK xNBPsCEP630nmPVKgOwGFKTe00DK6iHgVUqq6I3xmMaccXSxQK4j9aRD9Teg1hcEtX2Q F7DA== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:references:in-reply-to:references :in-reply-to:message-id:date:subject:cc:to:from :arc-authentication-results; bh=nuESwuJkmhZ5Tc3OCC/VSgxm/n160GnbJuwqjXBDO90=; b=KeY5yxZ2kqeZC8SiWarG+g9eV0UWRsFExcXLxzgzG4MWbLkSVZyd6oekBxrKuTHwXz oklUKO5TJvKb/kQJEz2zZ0uj4hzkwx9y0hQNvNQkkWC3b4DbKAo3l624VTZFxtqmLeu0 WTnRcJdEXlEC0zPZVFvjsVLA4FzgeHCdf0vaCCvjRW6uzYmjBYrT/8d06gdkqqgQd0DS 5yg7EMhA7iDP03umxLR8GLQ+o+YNLfb/tGgal4LO4dB1U97MWn4H8YqAXd6jbjhYxBAo BIvlYCGjUmifX8duli7XutuP5orLgCI2bJHlmH1wy0b8dQgjD4eupE08FKnOBLbD2/NU uRew== ARC-Authentication-Results: i=1; mx.google.com; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=redhat.com Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id a18-v6si14057837plm.122.2018.07.31.13.12.47; Tue, 31 Jul 2018 13:13:06 -0700 (PDT) Received-SPF: pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=redhat.com Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1731637AbeGaVxX (ORCPT + 99 others); Tue, 31 Jul 2018 17:53:23 -0400 Received: from mx3-rdu2.redhat.com ([66.187.233.73]:33390 "EHLO mx1.redhat.com" rhost-flags-OK-OK-OK-FAIL) by vger.kernel.org with ESMTP id S1726580AbeGaVxW (ORCPT ); Tue, 31 Jul 2018 17:53:22 -0400 Received: from smtp.corp.redhat.com (int-mx04.intmail.prod.int.rdu2.redhat.com [10.11.54.4]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id 302517C6A9; Tue, 31 Jul 2018 20:11:23 +0000 (UTC) Received: from madcap2.tricolour.ca (ovpn-112-17.rdu2.redhat.com [10.10.112.17]) by smtp.corp.redhat.com (Postfix) with ESMTP id 2F8822026D7E; Tue, 31 Jul 2018 20:11:20 +0000 (UTC) From: Richard Guy Briggs To: containers@lists.linux-foundation.org, linux-api@vger.kernel.org, Linux-Audit Mailing List , linux-fsdevel@vger.kernel.org, LKML , netdev@vger.kernel.org, netfilter-devel@vger.kernel.org Cc: luto@kernel.org, carlos@redhat.com, viro@zeniv.linux.org.uk, dhowells@redhat.com, simo@redhat.com, eparis@parisplace.org, serge@hallyn.com, ebiederm@xmission.com, Richard Guy Briggs Subject: [PATCH ghak90 (was ghak32) V4 01/10] audit: collect audit task parameters Date: Tue, 31 Jul 2018 16:07:36 -0400 Message-Id: <8e617ab568df28a66dfbe3284452de186b42fb0f.1533065887.git.rgb@redhat.com> In-Reply-To: References: In-Reply-To: References: X-Scanned-By: MIMEDefang 2.78 on 10.11.54.4 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.11.55.2]); Tue, 31 Jul 2018 20:11:23 +0000 (UTC) X-Greylist: inspected by milter-greylist-4.5.16 (mx1.redhat.com [10.11.55.2]); Tue, 31 Jul 2018 20:11:23 +0000 (UTC) for IP:'10.11.54.4' DOMAIN:'int-mx04.intmail.prod.int.rdu2.redhat.com' HELO:'smtp.corp.redhat.com' FROM:'rgb@redhat.com' RCPT:'' Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org The audit-related parameters in struct task_struct should ideally be collected together and accessed through a standard audit API. Collect the existing loginuid, sessionid and audit_context together in a new struct audit_task_info called "audit" in struct task_struct. Use kmem_cache to manage this pool of memory. Un-inline audit_free() to be able to always recover that memory. See: https://github.com/linux-audit/audit-kernel/issues/81 Signed-off-by: Richard Guy Briggs --- include/linux/audit.h | 34 ++++++++++++++++++++++++---------- include/linux/sched.h | 5 +---- init/init_task.c | 3 +-- init/main.c | 2 ++ kernel/auditsc.c | 51 ++++++++++++++++++++++++++++++++++++++++++--------- kernel/fork.c | 4 +++- 6 files changed, 73 insertions(+), 26 deletions(-) diff --git a/include/linux/audit.h b/include/linux/audit.h index 9334fbe..8964332 100644 --- a/include/linux/audit.h +++ b/include/linux/audit.h @@ -219,8 +219,15 @@ static inline void audit_log_task_info(struct audit_buffer *ab, /* These are defined in auditsc.c */ /* Public API */ +struct audit_task_info { + kuid_t loginuid; + unsigned int sessionid; + struct audit_context *ctx; +}; +extern struct audit_task_info init_struct_audit; +extern void __init audit_task_init(void); extern int audit_alloc(struct task_struct *task); -extern void __audit_free(struct task_struct *task); +extern void audit_free(struct task_struct *task); extern void __audit_syscall_entry(int major, unsigned long a0, unsigned long a1, unsigned long a2, unsigned long a3); extern void __audit_syscall_exit(int ret_success, long ret_value); @@ -242,12 +249,15 @@ extern void audit_seccomp_actions_logged(const char *names, static inline void audit_set_context(struct task_struct *task, struct audit_context *ctx) { - task->audit_context = ctx; + task->audit->ctx = ctx; } static inline struct audit_context *audit_context(void) { - return current->audit_context; + if (current->audit) + return current->audit->ctx; + else + return NULL; } static inline bool audit_dummy_context(void) @@ -255,11 +265,7 @@ static inline bool audit_dummy_context(void) void *p = audit_context(); return !p || *(int *)p; } -static inline void audit_free(struct task_struct *task) -{ - if (unlikely(task->audit_context)) - __audit_free(task); -} + static inline void audit_syscall_entry(int major, unsigned long a0, unsigned long a1, unsigned long a2, unsigned long a3) @@ -331,12 +337,18 @@ extern int auditsc_get_stamp(struct audit_context *ctx, static inline kuid_t audit_get_loginuid(struct task_struct *tsk) { - return tsk->loginuid; + if (tsk->audit) + return tsk->audit->loginuid; + else + return INVALID_UID; } static inline unsigned int audit_get_sessionid(struct task_struct *tsk) { - return tsk->sessionid; + if (tsk->audit) + return tsk->audit->sessionid; + else + return AUDIT_SID_UNSET; } extern void __audit_ipc_obj(struct kern_ipc_perm *ipcp); @@ -461,6 +473,8 @@ static inline void audit_fanotify(unsigned int response) extern int audit_n_rules; extern int audit_signals; #else /* CONFIG_AUDITSYSCALL */ +static inline void __init audit_task_init(void) +{ } static inline int audit_alloc(struct task_struct *task) { return 0; diff --git a/include/linux/sched.h b/include/linux/sched.h index 87bf02d..e117272 100644 --- a/include/linux/sched.h +++ b/include/linux/sched.h @@ -30,7 +30,6 @@ #include /* task_struct member predeclarations (sorted alphabetically): */ -struct audit_context; struct backing_dev_info; struct bio_list; struct blk_plug; @@ -873,10 +872,8 @@ struct task_struct { struct callback_head *task_works; - struct audit_context *audit_context; #ifdef CONFIG_AUDITSYSCALL - kuid_t loginuid; - unsigned int sessionid; + struct audit_task_info *audit; #endif struct seccomp seccomp; diff --git a/init/init_task.c b/init/init_task.c index 74f60ba..4058840 100644 --- a/init/init_task.c +++ b/init/init_task.c @@ -119,8 +119,7 @@ struct task_struct init_task .thread_group = LIST_HEAD_INIT(init_task.thread_group), .thread_node = LIST_HEAD_INIT(init_signals.thread_head), #ifdef CONFIG_AUDITSYSCALL - .loginuid = INVALID_UID, - .sessionid = AUDIT_SID_UNSET, + .audit = &init_struct_audit, #endif #ifdef CONFIG_PERF_EVENTS .perf_event_mutex = __MUTEX_INITIALIZER(init_task.perf_event_mutex), diff --git a/init/main.c b/init/main.c index 3b4ada1..6aba171 100644 --- a/init/main.c +++ b/init/main.c @@ -92,6 +92,7 @@ #include #include #include +#include #include #include @@ -721,6 +722,7 @@ asmlinkage __visible void __init start_kernel(void) nsfs_init(); cpuset_init(); cgroup_init(); + audit_task_init(); taskstats_init_early(); delayacct_init(); diff --git a/kernel/auditsc.c b/kernel/auditsc.c index fb20746..88779a7 100644 --- a/kernel/auditsc.c +++ b/kernel/auditsc.c @@ -841,7 +841,7 @@ static inline struct audit_context *audit_take_context(struct task_struct *tsk, int return_valid, long return_code) { - struct audit_context *context = tsk->audit_context; + struct audit_context *context = tsk->audit->ctx; if (!context) return NULL; @@ -926,6 +926,15 @@ static inline struct audit_context *audit_alloc_context(enum audit_state state) return context; } +static struct kmem_cache *audit_task_cache; + +void __init audit_task_init(void) +{ + audit_task_cache = kmem_cache_create("audit_task", + sizeof(struct audit_task_info), + 0, SLAB_PANIC, NULL); +} + /** * audit_alloc - allocate an audit context block for a task * @tsk: task @@ -940,17 +949,28 @@ int audit_alloc(struct task_struct *tsk) struct audit_context *context; enum audit_state state; char *key = NULL; + struct audit_task_info *info; + + info = kmem_cache_zalloc(audit_task_cache, GFP_KERNEL); + if (!info) + return -ENOMEM; + info->loginuid = audit_get_loginuid(current); + info->sessionid = audit_get_sessionid(current); + tsk->audit = info; if (likely(!audit_ever_enabled)) return 0; /* Return if not auditing. */ state = audit_filter_task(tsk, &key); if (state == AUDIT_DISABLED) { + audit_set_context(tsk, NULL); clear_tsk_thread_flag(tsk, TIF_SYSCALL_AUDIT); return 0; } if (!(context = audit_alloc_context(state))) { + tsk->audit = NULL; + kmem_cache_free(audit_task_cache, info); kfree(key); audit_log_lost("out of memory in audit_alloc"); return -ENOMEM; @@ -962,6 +982,12 @@ int audit_alloc(struct task_struct *tsk) return 0; } +struct audit_task_info init_struct_audit = { + .loginuid = INVALID_UID, + .sessionid = AUDIT_SID_UNSET, + .ctx = NULL, +}; + static inline void audit_free_context(struct audit_context *context) { audit_free_names(context); @@ -1469,26 +1495,33 @@ static void audit_log_exit(struct audit_context *context, struct task_struct *ts } /** - * __audit_free - free a per-task audit context + * audit_free - free a per-task audit context * @tsk: task whose audit context block to free * * Called from copy_process and do_exit */ -void __audit_free(struct task_struct *tsk) +void audit_free(struct task_struct *tsk) { struct audit_context *context; + struct audit_task_info *info; context = audit_take_context(tsk, 0, 0); - if (!context) - return; - /* Check for system calls that do not go through the exit * function (e.g., exit_group), then free context block. * We use GFP_ATOMIC here because we might be doing this * in the context of the idle thread */ /* that can happen only if we are called from do_exit() */ - if (context->in_syscall && context->current_state == AUDIT_RECORD_CONTEXT) + if (context && context->in_syscall && + context->current_state == AUDIT_RECORD_CONTEXT) audit_log_exit(context, tsk); + /* Freeing the audit_task_info struct must be performed after + * audit_log_exit() due to need for loginuid and sessionid. + */ + info = tsk->audit; + tsk->audit = NULL; + kmem_cache_free(audit_task_cache, info); + if (!context) + return; if (!list_empty(&context->killed_trees)) audit_kill_trees(&context->killed_trees); @@ -2071,8 +2104,8 @@ int audit_set_loginuid(kuid_t loginuid) sessionid = (unsigned int)atomic_inc_return(&session_id); } - task->sessionid = sessionid; - task->loginuid = loginuid; + task->audit->sessionid = sessionid; + task->audit->loginuid = loginuid; out: audit_log_set_loginuid(oldloginuid, loginuid, oldsessionid, sessionid, rc); return rc; diff --git a/kernel/fork.c b/kernel/fork.c index 9440d61..1bfb0ff 100644 --- a/kernel/fork.c +++ b/kernel/fork.c @@ -1721,7 +1721,9 @@ static __latent_entropy struct task_struct *copy_process( p->start_time = ktime_get_ns(); p->real_start_time = ktime_get_boot_ns(); p->io_context = NULL; - audit_set_context(p, NULL); +#ifdef CONFIG_AUDITSYSCALL + p->audit = NULL; +#endif /* CONFIG_AUDITSYSCALL */ cgroup_fork(p); #ifdef CONFIG_NUMA p->mempolicy = mpol_dup(p->mempolicy); -- 1.8.3.1