Linux-audit Archive on lore.kernel.org
 help / color / Atom feed
From: Paul Moore <paul@paul-moore.com>
To: Richard Guy Briggs <rgb@redhat.com>
Cc: nhorman@tuxdriver.com, linux-api@vger.kernel.org,
	containers@lists.linux-foundation.org,
	LKML <linux-kernel@vger.kernel.org>,
	dhowells@redhat.com,
	Linux-Audit Mailing List <linux-audit@redhat.com>,
	netfilter-devel@vger.kernel.org, ebiederm@xmission.com,
	simo@redhat.com, netdev@vger.kernel.org,
	linux-fsdevel@vger.kernel.org, Eric Paris <eparis@parisplace.org>,
	mpatel@redhat.com, Serge Hallyn <serge@hallyn.com>
Subject: Re: [PATCH ghak90 V9 06/13] audit: add contid support for signalling the audit daemon
Date: Sun, 5 Jul 2020 11:10:46 -0400
Message-ID: <CAHC9VhRPm4=_dVkZCu9iD5u5ixJOUnGNZ2wM9CL4kWwqv3GRnA@mail.gmail.com> (raw)
In-Reply-To: <f01f38dbb3190191e5914874322342700aecb9e1.1593198710.git.rgb@redhat.com>

On Sat, Jun 27, 2020 at 9:22 AM Richard Guy Briggs <rgb@redhat.com> wrote:
>
> Add audit container identifier support to the action of signalling the
> audit daemon.
>
> Since this would need to add an element to the audit_sig_info struct,
> a new record type AUDIT_SIGNAL_INFO2 was created with a new
> audit_sig_info2 struct.  Corresponding support is required in the
> userspace code to reflect the new record request and reply type.
> An older userspace won't break since it won't know to request this
> record type.
>
> Signed-off-by: Richard Guy Briggs <rgb@redhat.com>
> ---
>  include/linux/audit.h       |  8 ++++
>  include/uapi/linux/audit.h  |  1 +
>  kernel/audit.c              | 95 ++++++++++++++++++++++++++++++++++++++++++++-
>  security/selinux/nlmsgtab.c |  1 +
>  4 files changed, 104 insertions(+), 1 deletion(-)
>
> diff --git a/include/linux/audit.h b/include/linux/audit.h
> index 5eeba0efffc2..89cf7c66abe6 100644
> --- a/include/linux/audit.h
> +++ b/include/linux/audit.h
> @@ -22,6 +22,13 @@ struct audit_sig_info {
>         char            ctx[];
>  };
>
> +struct audit_sig_info2 {
> +       uid_t           uid;
> +       pid_t           pid;
> +       u32             cid_len;
> +       char            data[];
> +};
> +
>  struct audit_buffer;
>  struct audit_context;
>  struct inode;
> @@ -105,6 +112,7 @@ struct audit_contobj {
>         u64                     id;
>         struct task_struct      *owner;
>         refcount_t              refcount;
> +       refcount_t              sigflag;
>         struct rcu_head         rcu;
>  };

It seems like we need some protection in audit_set_contid() so that we
don't allow reuse of an audit container ID when "refcount == 0 &&
sigflag != 0", yes?

> diff --git a/include/uapi/linux/audit.h b/include/uapi/linux/audit.h
> index fd98460c983f..a56ad77069b9 100644
> --- a/include/uapi/linux/audit.h
> +++ b/include/uapi/linux/audit.h
> @@ -72,6 +72,7 @@
>  #define AUDIT_SET_FEATURE      1018    /* Turn an audit feature on or off */
>  #define AUDIT_GET_FEATURE      1019    /* Get which features are enabled */
>  #define AUDIT_CONTAINER_OP     1020    /* Define the container id and info */
> +#define AUDIT_SIGNAL_INFO2     1021    /* Get info auditd signal sender */
>
>  #define AUDIT_FIRST_USER_MSG   1100    /* Userspace messages mostly uninteresting to kernel */
>  #define AUDIT_USER_AVC         1107    /* We filter this differently */
> diff --git a/kernel/audit.c b/kernel/audit.c
> index a09f8f661234..54dd2cb69402 100644
> --- a/kernel/audit.c
> +++ b/kernel/audit.c
> @@ -126,6 +126,8 @@ struct auditd_connection {
>  kuid_t         audit_sig_uid = INVALID_UID;
>  pid_t          audit_sig_pid = -1;
>  u32            audit_sig_sid = 0;
> +static struct audit_contobj *audit_sig_cid;
> +static struct task_struct *audit_sig_atsk;

This looks like a typo, or did you mean "atsk" for some reason?

>  /* Records can be lost in several ways:
>     0) [suppressed in audit_alloc]
> @@ -239,7 +241,33 @@ void _audit_contobj_put(struct audit_contobj *cont)
>  {
>         if (!cont)
>                 return;
> -       if (refcount_dec_and_test(&cont->refcount)) {
> +       if (refcount_dec_and_test(&cont->refcount) && !refcount_read(&cont->sigflag)) {
> +               put_task_struct(cont->owner);
> +               list_del_rcu(&cont->list);
> +               kfree_rcu(cont, rcu);
> +       }
> +}

It seems like it might be a good idea to modify the corresponding
_get() to WARN on the reuse of audit container objects where refcount
is zero, similar to the comment I made above.  What do you think?

> +/* rcu_read_lock must be held by caller unless new */
> +static struct audit_contobj *_audit_contobj_get_sig(struct task_struct *tsk)
> +{
> +       struct audit_contobj *cont;
> +
> +       if (!tsk->audit)
> +               return NULL;
> +       cont = tsk->audit->cont;
> +       if (cont)
> +               refcount_set(&cont->sigflag, 1);
> +       return cont;
> +}

If you are going to use a refcount and call this a "get" function you
might as well make it do an increment and not just a set(1).  It a bit
silly with just one auditd per system, but I suppose it will make more
sense when we have multiple audit daemons.  In a related comment, you
probably want to rename "sigflag" to "sigcount" or similar.

In summary, it's either a reference that supports multiple gets/puts
or it's a flag with just an on/off; it shouldn't attempt to straddle
both, that's both confusing and fragile.

> +/* rcu_read_lock must be held by caller */
> +static void _audit_contobj_put_sig(struct audit_contobj *cont)
> +{
> +       if (!cont)
> +               return;
> +       refcount_set(&cont->sigflag, 0);
> +       if (!refcount_read(&cont->refcount)) {
>                 put_task_struct(cont->owner);
>                 list_del_rcu(&cont->list);
>                 kfree_rcu(cont, rcu);
> @@ -309,6 +337,13 @@ void audit_free(struct task_struct *tsk)
>         info = tsk->audit;
>         tsk->audit = NULL;
>         kmem_cache_free(audit_task_cache, info);
> +       rcu_read_lock();
> +       if (audit_sig_atsk == tsk) {
> +               _audit_contobj_put_sig(audit_sig_cid);
> +               audit_sig_cid = NULL;
> +               audit_sig_atsk = NULL;
> +       }
> +       rcu_read_unlock();
>  }
>
>  /**
> @@ -1132,6 +1167,7 @@ static int audit_netlink_ok(struct sk_buff *skb, u16 msg_type)
>         case AUDIT_ADD_RULE:
>         case AUDIT_DEL_RULE:
>         case AUDIT_SIGNAL_INFO:
> +       case AUDIT_SIGNAL_INFO2:
>         case AUDIT_TTY_GET:
>         case AUDIT_TTY_SET:
>         case AUDIT_TRIM:
> @@ -1294,6 +1330,7 @@ static int audit_receive_msg(struct sk_buff *skb, struct nlmsghdr *nlh)
>         struct audit_buffer     *ab;
>         u16                     msg_type = nlh->nlmsg_type;
>         struct audit_sig_info   *sig_data;
> +       struct audit_sig_info2  *sig_data2;
>         char                    *ctx = NULL;
>         u32                     len;
>
> @@ -1559,6 +1596,52 @@ static int audit_receive_msg(struct sk_buff *skb, struct nlmsghdr *nlh)
>                                  sig_data, sizeof(*sig_data) + len);
>                 kfree(sig_data);
>                 break;
> +       case AUDIT_SIGNAL_INFO2: {
> +               unsigned int contidstrlen = 0;
> +
> +               len = 0;
> +               if (audit_sig_sid) {
> +                       err = security_secid_to_secctx(audit_sig_sid, &ctx,
> +                                                      &len);
> +                       if (err)
> +                               return err;
> +               }
> +               if (audit_sig_cid) {
> +                       contidstr = kmalloc(21, GFP_KERNEL);
> +                       if (!contidstr) {
> +                               if (audit_sig_sid)
> +                                       security_release_secctx(ctx, len);
> +                               return -ENOMEM;
> +                       }
> +                       contidstrlen = scnprintf(contidstr, 20, "%llu", audit_sig_cid->id);
> +               }
> +               sig_data2 = kmalloc(sizeof(*sig_data2) + contidstrlen + len, GFP_KERNEL);
> +               if (!sig_data2) {
> +                       if (audit_sig_sid)
> +                               security_release_secctx(ctx, len);
> +                       kfree(contidstr);
> +                       return -ENOMEM;
> +               }
> +               sig_data2->uid = from_kuid(&init_user_ns, audit_sig_uid);
> +               sig_data2->pid = audit_sig_pid;
> +               if (audit_sig_cid) {
> +                       memcpy(sig_data2->data, contidstr, contidstrlen);
> +                       sig_data2->cid_len = contidstrlen;
> +                       kfree(contidstr);
> +               }
> +               if (audit_sig_sid) {
> +                       memcpy(sig_data2->data + contidstrlen, ctx, len);
> +                       security_release_secctx(ctx, len);
> +               }
> +               rcu_read_lock();
> +               _audit_contobj_put_sig(audit_sig_cid);
> +               rcu_read_unlock();

We probably want to drop the reference in the legacy/AUDIT_SIGNAL_INFO
case too, right?

> +               audit_sig_cid = NULL;
> +               audit_send_reply(skb, seq, AUDIT_SIGNAL_INFO2, 0, 0,
> +                                sig_data2, sizeof(*sig_data2) + contidstrlen + len);
> +               kfree(sig_data2);
> +               break;
> +       }
>         case AUDIT_TTY_GET: {
>                 struct audit_tty_status s;
>                 unsigned int t;
> @@ -2470,6 +2553,11 @@ int audit_signal_info(int sig, struct task_struct *t)
>                 else
>                         audit_sig_uid = uid;
>                 security_task_getsecid(current, &audit_sig_sid);
> +               rcu_read_lock();
> +               _audit_contobj_put_sig(audit_sig_cid);
> +               audit_sig_cid = _audit_contobj_get_sig(current);
> +               rcu_read_unlock();
> +               audit_sig_atsk = t;
>         }
>
>         return audit_signal_info_syscall(t);
> @@ -2532,6 +2620,11 @@ int audit_set_contid(struct task_struct *task, u64 contid)
>                         if (cont->id == contid) {
>                                 /* task injection to existing container */
>                                 if (current == cont->owner) {
> +                                       if (!refcount_read(&cont->refcount)) {
> +                                               rc = -ESHUTDOWN;

Reuse -ENOTUNIQ; I'm not overly excited about providing a lot of
detail here as these are global system objects.  If you must have a
different errno (and I would prefer you didn't), use something like
-EBUSY.


> +                                               spin_unlock(&audit_contobj_list_lock);
> +                                               goto conterror;
> +                                       }
>                                         _audit_contobj_hold(cont);
>                                         newcont = cont;
>                                 } else {
> diff --git a/security/selinux/nlmsgtab.c b/security/selinux/nlmsgtab.c
> index b69231918686..8303bb7a63d0 100644
> --- a/security/selinux/nlmsgtab.c
> +++ b/security/selinux/nlmsgtab.c
> @@ -137,6 +137,7 @@ struct nlmsg_perm {
>         { AUDIT_DEL_RULE,       NETLINK_AUDIT_SOCKET__NLMSG_WRITE    },
>         { AUDIT_USER,           NETLINK_AUDIT_SOCKET__NLMSG_RELAY    },
>         { AUDIT_SIGNAL_INFO,    NETLINK_AUDIT_SOCKET__NLMSG_READ     },
> +       { AUDIT_SIGNAL_INFO2,   NETLINK_AUDIT_SOCKET__NLMSG_READ     },
>         { AUDIT_TRIM,           NETLINK_AUDIT_SOCKET__NLMSG_WRITE    },
>         { AUDIT_MAKE_EQUIV,     NETLINK_AUDIT_SOCKET__NLMSG_WRITE    },
>         { AUDIT_TTY_GET,        NETLINK_AUDIT_SOCKET__NLMSG_READ     },

--
paul moore
www.paul-moore.com

--
Linux-audit mailing list
Linux-audit@redhat.com
https://www.redhat.com/mailman/listinfo/linux-audit


  reply index

Thread overview: 51+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2020-06-27 13:20 [PATCH ghak90 V9 00/13] audit: implement container identifier Richard Guy Briggs
2020-06-27 13:20 ` [PATCH ghak90 V9 01/13] audit: collect audit task parameters Richard Guy Briggs
2020-07-05 15:09   ` Paul Moore
2020-07-07  2:50     ` Richard Guy Briggs
2020-07-08  1:42       ` Paul Moore
2020-07-13 20:29         ` Richard Guy Briggs
2020-07-14  0:44           ` Paul Moore
2020-06-27 13:20 ` [PATCH ghak90 V9 02/13] audit: add container id Richard Guy Briggs
2020-07-04 13:29   ` Paul Moore
2020-07-04 13:30     ` Paul Moore
2020-07-05 15:09   ` Paul Moore
2020-07-29 20:05     ` Richard Guy Briggs
2020-08-21 19:36       ` Paul Moore
2020-06-27 13:20 ` [PATCH ghak90 V9 03/13] audit: read container ID of a process Richard Guy Briggs
2020-06-27 13:20 ` [PATCH ghak90 V9 04/13] audit: log drop of contid on exit of last task Richard Guy Briggs
2020-07-05 15:10   ` Paul Moore
2020-06-27 13:20 ` [PATCH ghak90 V9 05/13] audit: log container info of syscalls Richard Guy Briggs
2020-07-05 15:10   ` Paul Moore
2020-07-29 19:40     ` Richard Guy Briggs
2020-08-21 19:15       ` Paul Moore
2020-10-02 19:52         ` Richard Guy Briggs
2020-10-21 16:39           ` Richard Guy Briggs
2020-10-21 16:49             ` Steve Grubb
2020-10-21 17:53               ` Richard Guy Briggs
2020-10-23  1:21             ` Paul Moore
2020-10-23 20:40               ` Richard Guy Briggs
2020-10-28  1:35                 ` Paul Moore
2020-06-27 13:20 ` [PATCH ghak90 V9 06/13] audit: add contid support for signalling the audit daemon Richard Guy Briggs
2020-07-05 15:10   ` Paul Moore [this message]
2020-07-29 19:00     ` Richard Guy Briggs
2020-08-21 18:48       ` Paul Moore
2020-10-02 19:25         ` Richard Guy Briggs
2020-06-27 13:20 ` [PATCH ghak90 V9 07/13] audit: add support for non-syscall auxiliary records Richard Guy Briggs
2020-07-05 15:11   ` Paul Moore
2020-06-27 13:20 ` [PATCH ghak90 V9 08/13] audit: add containerid support for user records Richard Guy Briggs
2020-07-05 15:11   ` Paul Moore
2020-07-18  0:43     ` Richard Guy Briggs
2020-08-21 18:34       ` Paul Moore
2020-06-27 13:20 ` [PATCH ghak90 V9 09/13] audit: add containerid filtering Richard Guy Briggs
2020-06-27 13:20 ` [PATCH ghak90 V9 10/13] audit: add support for containerid to network namespaces Richard Guy Briggs
2020-07-05 15:11   ` Paul Moore
2020-07-21 22:05     ` Richard Guy Briggs
2020-06-27 13:20 ` [PATCH ghak90 V9 11/13] audit: contid check descendancy and nesting Richard Guy Briggs
2020-07-05 15:11   ` Paul Moore
2020-08-07 17:10     ` Richard Guy Briggs
2020-08-21 20:13       ` Paul Moore
2020-10-06 20:03         ` Richard Guy Briggs
2020-06-27 13:20 ` [PATCH ghak90 V9 12/13] audit: track container nesting Richard Guy Briggs
2020-07-05 15:11   ` Paul Moore
2020-06-27 13:20 ` [PATCH ghak90 V9 13/13] audit: add capcontid to set contid outside init_user_ns Richard Guy Briggs
2020-07-05 15:11   ` Paul Moore

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='CAHC9VhRPm4=_dVkZCu9iD5u5ixJOUnGNZ2wM9CL4kWwqv3GRnA@mail.gmail.com' \
    --to=paul@paul-moore.com \
    --cc=containers@lists.linux-foundation.org \
    --cc=dhowells@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=rgb@redhat.com \
    --cc=serge@hallyn.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

Linux-audit Archive on lore.kernel.org

Archives are clonable:
	git clone --mirror https://lore.kernel.org/linux-audit/0 linux-audit/git/0.git

	# If you have public-inbox 1.1+ installed, you may
	# initialize and index your mirror using the following commands:
	public-inbox-init -V2 linux-audit linux-audit/ https://lore.kernel.org/linux-audit \
		linux-audit@redhat.com
	public-inbox-index linux-audit

Example config snippet for mirrors

Newsgroup available over NNTP:
	nntp://nntp.lore.kernel.org/com.redhat.linux-audit


AGPL code for this site: git clone https://public-inbox.org/public-inbox.git