netdev.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Richard Guy Briggs <rgb@redhat.com>
To: containers@lists.linux-foundation.org, linux-api@vger.kernel.org,
	Linux-Audit Mailing List <linux-audit@redhat.com>,
	linux-fsdevel@vger.kernel.org,
	LKML <linux-kernel@vger.kernel.org>,
	netdev@vger.kernel.org, netfilter-devel@vger.kernel.org
Cc: Paul Moore <paul@paul-moore.com>,
	sgrubb@redhat.com, omosnace@redhat.com, dhowells@redhat.com,
	simo@redhat.com, eparis@parisplace.org, serge@hallyn.com,
	ebiederm@xmission.com, nhorman@tuxdriver.com, dwalsh@redhat.com,
	mpatel@redhat.com, Richard Guy Briggs <rgb@redhat.com>
Subject: [PATCH ghak90 V7 04/21] audit: convert to contid list to check for orch/engine ownership
Date: Wed, 18 Sep 2019 21:22:21 -0400	[thread overview]
Message-ID: <6fb4e270bfafef3d0477a06b0365fdcc5a5305b5.1568834524.git.rgb@redhat.com> (raw)
In-Reply-To: <cover.1568834524.git.rgb@redhat.com>
In-Reply-To: <cover.1568834524.git.rgb@redhat.com>

Store the audit container identifier in a refcounted kernel object that
is added to the master list of audit container identifiers.  This will
allow multiple container orchestrators/engines to work on the same
machine without danger of inadvertantly re-using an existing identifier.
It will also allow an orchestrator to inject a process into an existing
container by checking if the original container owner is the one
injecting the task.  A hash table list is used to optimize searches.

Signed-off-by: Richard Guy Briggs <rgb@redhat.com>
---
 include/linux/audit.h | 26 ++++++++++++++--
 kernel/audit.c        | 86 ++++++++++++++++++++++++++++++++++++++++++++++++---
 kernel/audit.h        |  8 +++++
 3 files changed, 112 insertions(+), 8 deletions(-)

diff --git a/include/linux/audit.h b/include/linux/audit.h
index f2e3b81f2942..e317807cdd3e 100644
--- a/include/linux/audit.h
+++ b/include/linux/audit.h
@@ -95,10 +95,18 @@ struct audit_ntp_data {
 struct audit_ntp_data {};
 #endif
 
+struct audit_cont {
+	struct list_head	list;
+	u64			id;
+	struct task_struct	*owner;
+	refcount_t              refcount;
+	struct rcu_head         rcu;
+};
+
 struct audit_task_info {
 	kuid_t			loginuid;
 	unsigned int		sessionid;
-	u64			contid;
+	struct audit_cont	*cont;
 #ifdef CONFIG_AUDITSYSCALL
 	struct audit_context	*ctx;
 #endif
@@ -203,11 +211,15 @@ static inline unsigned int audit_get_sessionid(struct task_struct *tsk)
 
 static inline u64 audit_get_contid(struct task_struct *tsk)
 {
-	if (!tsk->audit)
+	if (!tsk->audit || !tsk->audit->cont)
 		return AUDIT_CID_UNSET;
-	return tsk->audit->contid;
+	return tsk->audit->cont->id;
 }
 
+extern struct audit_cont *audit_cont(struct task_struct *tsk);
+
+extern void audit_cont_put(struct audit_cont *cont);
+
 extern u32 audit_enabled;
 
 extern int audit_signal_info(int sig, struct task_struct *t);
@@ -277,6 +289,14 @@ static inline u64 audit_get_contid(struct task_struct *tsk)
 	return AUDIT_CID_UNSET;
 }
 
+static inline struct audit_cont *audit_cont(struct task_struct *tsk)
+{
+	return NULL;
+}
+
+static inline void audit_cont_put(struct audit_cont *cont)
+{ }
+
 #define audit_enabled AUDIT_OFF
 
 static inline int audit_signal_info(int sig, struct task_struct *t)
diff --git a/kernel/audit.c b/kernel/audit.c
index a36ea57cbb61..ea0899130cc1 100644
--- a/kernel/audit.c
+++ b/kernel/audit.c
@@ -137,6 +137,8 @@ struct audit_net {
 
 /* Hash for inode-based rules */
 struct list_head audit_inode_hash[AUDIT_INODE_BUCKETS];
+/* Hash for contid-based rules */
+struct list_head audit_contid_hash[AUDIT_CONTID_BUCKETS];
 
 static struct kmem_cache *audit_buffer_cache;
 
@@ -204,6 +206,8 @@ struct audit_reply {
 
 static struct kmem_cache *audit_task_cache;
 
+static DEFINE_SPINLOCK(audit_contid_list_lock);
+
 void __init audit_task_init(void)
 {
 	audit_task_cache = kmem_cache_create("audit_task",
@@ -231,7 +235,9 @@ int audit_alloc(struct task_struct *tsk)
 	}
 	info->loginuid = audit_get_loginuid(current);
 	info->sessionid = audit_get_sessionid(current);
-	info->contid = audit_get_contid(current);
+	info->cont = audit_cont(current);
+	if (info->cont)
+		refcount_inc(&info->cont->refcount);
 	tsk->audit = info;
 
 	ret = audit_alloc_syscall(tsk);
@@ -246,7 +252,7 @@ int audit_alloc(struct task_struct *tsk)
 struct audit_task_info init_struct_audit = {
 	.loginuid = INVALID_UID,
 	.sessionid = AUDIT_SID_UNSET,
-	.contid = AUDIT_CID_UNSET,
+	.cont = NULL,
 #ifdef CONFIG_AUDITSYSCALL
 	.ctx = NULL,
 #endif
@@ -266,6 +272,9 @@ void audit_free(struct task_struct *tsk)
 	/* Freeing the audit_task_info struct must be performed after
 	 * audit_log_exit() due to need for loginuid and sessionid.
 	 */
+	spin_lock(&audit_contid_list_lock); 
+	audit_cont_put(tsk->audit->cont);
+	spin_unlock(&audit_contid_list_lock); 
 	info = tsk->audit;
 	tsk->audit = NULL;
 	kmem_cache_free(audit_task_cache, info);
@@ -1657,6 +1666,9 @@ static int __init audit_init(void)
 	for (i = 0; i < AUDIT_INODE_BUCKETS; i++)
 		INIT_LIST_HEAD(&audit_inode_hash[i]);
 
+	for (i = 0; i < AUDIT_CONTID_BUCKETS; i++)
+		INIT_LIST_HEAD(&audit_contid_hash[i]);
+
 	mutex_init(&audit_cmd_mutex.lock);
 	audit_cmd_mutex.owner = NULL;
 
@@ -2356,6 +2368,32 @@ int audit_signal_info(int sig, struct task_struct *t)
 	return audit_signal_info_syscall(t);
 }
 
+struct audit_cont *audit_cont(struct task_struct *tsk)
+{
+	if (!tsk->audit || !tsk->audit->cont)
+		return NULL;
+	return tsk->audit->cont;
+}
+
+/* audit_contid_list_lock must be held by caller */
+void audit_cont_put(struct audit_cont *cont)
+{
+	if (!cont)
+		return;
+	if (refcount_dec_and_test(&cont->refcount)) {
+		put_task_struct(cont->owner);
+		list_del_rcu(&cont->list);
+		kfree_rcu(cont, rcu);
+	}
+}
+
+static struct task_struct *audit_cont_owner(struct task_struct *tsk)
+{
+	if (tsk->audit && tsk->audit->cont)
+		return tsk->audit->cont->owner;
+	return NULL;
+}
+
 /*
  * audit_set_contid - set current task's audit contid
  * @task: target task
@@ -2382,9 +2420,12 @@ int audit_set_contid(struct task_struct *task, u64 contid)
 	}
 	oldcontid = audit_get_contid(task);
 	read_lock(&tasklist_lock);
-	/* Don't allow the audit containerid to be unset */
+	/* Don't allow the contid to be unset */
 	if (!audit_contid_valid(contid))
 		rc = -EINVAL;
+	/* Don't allow the contid to be set to the same value again */
+	else if (contid == oldcontid) {
+		rc = -EADDRINUSE;
 	/* if we don't have caps, reject */
 	else if (!capable(CAP_AUDIT_CONTROL))
 		rc = -EPERM;
@@ -2397,8 +2438,43 @@ int audit_set_contid(struct task_struct *task, u64 contid)
 	else if (audit_contid_set(task))
 		rc = -ECHILD;
 	read_unlock(&tasklist_lock);
-	if (!rc)
-		task->audit->contid = contid;
+	if (!rc) {
+		struct audit_cont *oldcont = audit_cont(task);
+		struct audit_cont *cont = NULL;
+		struct audit_cont *newcont = NULL;
+		int h = audit_hash_contid(contid);
+
+		spin_lock(&audit_contid_list_lock);
+		list_for_each_entry_rcu(cont, &audit_contid_hash[h], list)
+			if (cont->id == contid) {
+				/* task injection to existing container */
+				if (current == cont->owner) {
+					refcount_inc(&cont->refcount);
+					newcont = cont;
+				} else {
+					rc = -ENOTUNIQ;
+					goto conterror;
+				}
+			}
+		if (!newcont) {
+			newcont = kmalloc(sizeof(struct audit_cont), GFP_ATOMIC);
+			if (newcont) {
+				INIT_LIST_HEAD(&newcont->list);
+				newcont->id = contid;
+				get_task_struct(current);
+				newcont->owner = current;
+				refcount_set(&newcont->refcount, 1);
+				list_add_rcu(&newcont->list, &audit_contid_hash[h]);
+			} else {
+				rc = -ENOMEM;
+				goto conterror;
+			}
+		}
+		task->audit->cont = newcont;
+		audit_cont_put(oldcont);
+conterror:
+		spin_unlock(&audit_contid_list_lock);
+	}
 	task_unlock(task);
 
 	if (!audit_enabled)
diff --git a/kernel/audit.h b/kernel/audit.h
index 16bd03b88e0d..e4a31aa92dfe 100644
--- a/kernel/audit.h
+++ b/kernel/audit.h
@@ -211,6 +211,14 @@ static inline int audit_hash_ino(u32 ino)
 	return (ino & (AUDIT_INODE_BUCKETS-1));
 }
 
+#define AUDIT_CONTID_BUCKETS	32
+extern struct list_head audit_contid_hash[AUDIT_CONTID_BUCKETS];
+
+static inline int audit_hash_contid(u64 contid)
+{
+	return (contid & (AUDIT_CONTID_BUCKETS-1));
+}
+
 /* Indicates that audit should log the full pathname. */
 #define AUDIT_NAME_FULL -1
 
-- 
1.8.3.1


  parent reply	other threads:[~2019-09-19  1:24 UTC|newest]

Thread overview: 72+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2019-09-19  1:22 [PATCH ghak90 V7 00/21] audit: implement container identifier Richard Guy Briggs
2019-09-19  1:22 ` [PATCH ghak90 V7 01/21] audit: collect audit task parameters Richard Guy Briggs
2019-09-19  1:22 ` [PATCH ghak90 V7 02/21] audit: add container id Richard Guy Briggs
2019-09-19  1:22 ` [PATCH ghak90 V7 03/21] audit: read container ID of a process Richard Guy Briggs
2019-09-19  1:22 ` Richard Guy Briggs [this message]
2019-09-26 14:46   ` [PATCH ghak90 V7 04/21] audit: convert to contid list to check for orch/engine ownership Neil Horman
2019-10-25 20:00     ` Richard Guy Briggs
2019-10-28 12:20       ` Neil Horman
2019-10-11  0:38   ` Paul Moore
2019-10-25 21:00     ` Richard Guy Briggs
2019-11-08 18:26       ` Paul Moore
2019-09-19  1:22 ` [PATCH ghak90 V7 05/21] audit: log drop of contid on exit of last task Richard Guy Briggs
2019-10-11  0:38   ` Paul Moore
2019-10-25 19:43     ` Richard Guy Briggs
2019-09-19  1:22 ` [PATCH ghak90 V7 06/21] audit: contid limit of 32k imposed to avoid DoS Richard Guy Briggs
2019-09-27 12:51   ` Neil Horman
2019-10-11  0:38     ` Paul Moore
2019-10-24 21:23       ` Richard Guy Briggs
2019-11-08 17:49         ` Paul Moore
2019-12-17 18:45           ` Richard Guy Briggs
2019-12-17 19:25             ` Steve Grubb
2019-12-17 19:56               ` Richard Guy Briggs
2019-10-25 20:15     ` Richard Guy Briggs
2019-09-19  1:22 ` [PATCH ghak90 V7 07/21] audit: log container info of syscalls Richard Guy Briggs
2019-09-19  1:22 ` [PATCH ghak90 V7 08/21] audit: add contid support for signalling the audit daemon Richard Guy Briggs
2019-10-11  0:39   ` Paul Moore
2019-10-25 19:20     ` Richard Guy Briggs
2019-11-08 17:41       ` Paul Moore
2019-09-19  1:22 ` [PATCH ghak90 V7 09/21] audit: add support for non-syscall auxiliary records Richard Guy Briggs
2019-09-19  1:22 ` [PATCH ghak90 V7 10/21] audit: add containerid support for user records Richard Guy Briggs
2019-09-19  1:22 ` [PATCH ghak90 V7 11/21] audit: add containerid filtering Richard Guy Briggs
2019-09-19  1:22 ` [PATCH ghak90 V7 12/21] audit: add support for containerid to network namespaces Richard Guy Briggs
2019-10-11  0:39   ` Paul Moore
2019-09-19  1:22 ` [PATCH ghak90 V7 13/21] audit: NETFILTER_PKT: record each container ID associated with a netNS Richard Guy Briggs
2019-10-11  0:39   ` Paul Moore
2019-09-19  1:22 ` [PATCH ghak90 V7 14/21] audit: contid check descendancy and nesting Richard Guy Briggs
2019-10-11  0:40   ` Paul Moore
2019-10-24 22:08     ` Richard Guy Briggs
2019-10-30 20:32       ` Paul Moore
2019-09-19  1:22 ` [PATCH ghak90 V7 15/21] sched: pull task_is_descendant into kernel/sched/core.c Richard Guy Briggs
2019-10-11  0:40   ` Paul Moore
2019-09-19  1:22 ` [PATCH ghak90 V7 16/21] audit: add support for contid set/get by netlink Richard Guy Briggs
2019-10-11  0:40   ` Paul Moore
2019-09-19  1:22 ` [PATCH ghak90 V7 17/21] audit: add support for loginuid/sessionid " Richard Guy Briggs
2019-10-11  0:40   ` Paul Moore
2019-09-19  1:22 ` [PATCH ghak90 V7 18/21] audit: track container nesting Richard Guy Briggs
2019-10-11  0:40   ` Paul Moore
2019-09-19  1:22 ` [PATCH ghak90 V7 19/21] audit: check cont depth Richard Guy Briggs
2019-09-19  1:22 ` [PATCH ghak90 V7 20/21] audit: add capcontid to set contid outside init_user_ns Richard Guy Briggs
2019-10-19  1:39   ` Richard Guy Briggs
2019-10-21 19:53     ` Paul Moore
2019-10-21 21:38       ` Richard Guy Briggs
2019-10-21 21:43         ` Paul Moore
2019-10-21 23:57           ` Richard Guy Briggs
2019-10-22  0:31             ` Paul Moore
2019-10-22 12:13               ` Neil Horman
2019-10-22 14:04                 ` Paul Moore
2019-10-22 20:06                 ` Richard Guy Briggs
2019-10-22 14:27               ` Richard Guy Briggs
2019-10-22 14:34                 ` Paul Moore
2019-10-24 21:00               ` Richard Guy Briggs
2019-10-30 20:27                 ` Paul Moore
2019-10-30 22:03                   ` Richard Guy Briggs
2019-10-31 13:59                     ` Paul Moore
2019-10-31 14:50                     ` Steve Grubb
2019-10-31 23:37                       ` Paul Moore
2019-11-01  1:02                       ` Duncan Roe
2019-11-01 15:09                       ` Richard Guy Briggs
2019-11-01 15:13                         ` Steve Grubb
2019-11-01 15:21                           ` Richard Guy Briggs
2019-11-01 16:22                         ` Paul Moore
2019-09-19  1:22 ` [PATCH ghak90 V7 21/21] audit: add proc interface for capcontid Richard Guy Briggs

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=6fb4e270bfafef3d0477a06b0365fdcc5a5305b5.1568834524.git.rgb@redhat.com \
    --to=rgb@redhat.com \
    --cc=containers@lists.linux-foundation.org \
    --cc=dhowells@redhat.com \
    --cc=dwalsh@redhat.com \
    --cc=ebiederm@xmission.com \
    --cc=eparis@parisplace.org \
    --cc=linux-api@vger.kernel.org \
    --cc=linux-audit@redhat.com \
    --cc=linux-fsdevel@vger.kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=mpatel@redhat.com \
    --cc=netdev@vger.kernel.org \
    --cc=netfilter-devel@vger.kernel.org \
    --cc=nhorman@tuxdriver.com \
    --cc=omosnace@redhat.com \
    --cc=paul@paul-moore.com \
    --cc=serge@hallyn.com \
    --cc=sgrubb@redhat.com \
    --cc=simo@redhat.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).