[PATCH] audit: drop /proc/PID/loginuid documentation Format field

2021-04-01 Thread Richard Guy Briggs
Drop the "Format:" field from the /proc/PID/loginuid documentation and
integrate the information into the Description field since it is not
recognized by the "./scripts/get_abi.pl validate" command which causes a
warning.  Documentation/ABI/README describes the valid fields.

Reported-by: Mauro Carvalho Chehab 
Signed-off-by: Richard Guy Briggs 
---
 .../ABI/stable/procfs-audit_loginuid  | 22 +--
 1 file changed, 11 insertions(+), 11 deletions(-)

diff --git a/Documentation/ABI/stable/procfs-audit_loginuid 
b/Documentation/ABI/stable/procfs-audit_loginuid
index 9d55a3ff4b34..cda405178391 100644
--- a/Documentation/ABI/stable/procfs-audit_loginuid
+++ b/Documentation/ABI/stable/procfs-audit_loginuid
@@ -2,26 +2,26 @@ What: Audit Login UID
 Date:  2005-02-01
 KernelVersion: 2.6.11-rc2 1e2d1492e178 ("[PATCH] audit: handle loginuid 
through proc")
 Contact:   linux-au...@redhat.com
-Format:%u
 Users: audit and login applications
 Description:
The /proc/$pid/loginuid pseudofile is written to set and
-   read to get the audit login UID of process $pid.  If it is
-   unset, permissions are not needed to set it.  The accessor must
-   have CAP_AUDIT_CONTROL in the initial user namespace to write
-   it if it has been set.  It cannot be written again if
-   AUDIT_FEATURE_LOGINUID_IMMUTABLE is enabled.  It cannot be
-   unset if AUDIT_FEATURE_ONLY_UNSET_LOGINUID is enabled.
-
+   read to get the audit login UID of process $pid as a
+   decimal unsigned int (%u, u32).  If it is unset,
+   permissions are not needed to set it.  The accessor must
+   have CAP_AUDIT_CONTROL in the initial user namespace to
+   write it if it has been set.  It cannot be written again
+   if AUDIT_FEATURE_LOGINUID_IMMUTABLE is enabled.  It
+   cannot be unset if AUDIT_FEATURE_ONLY_UNSET_LOGINUID is
+   enabled.
 
 What:  Audit Login Session ID
 Date:  2008-03-13
 KernelVersion: 2.6.25-rc7 1e0bd7550ea9 ("[PATCH] export sessionid alongside 
the loginuid in procfs")
 Contact:   linux-au...@redhat.com
-Format:%u
 Users: audit and login applications
 Description:
The /proc/$pid/sessionid pseudofile is read to get the
-   audit login session ID of process $pid.  It is set
-   automatically, serially assigned with each new login.
+   audit login session ID of process $pid as a decimal
+   unsigned int (%u, u32).  It is set automatically,
+   serially assigned with each new login.
 
-- 
2.27.0



Re: [PATCH v3 1/2] audit: document /proc/PID/loginuid

2021-04-01 Thread Richard Guy Briggs
On 2021-04-01 09:57, Paul Moore wrote:
> On Thu, Apr 1, 2021 at 9:48 AM Mauro Carvalho Chehab
>  wrote:
> > Em Thu, 18 Mar 2021 15:19:10 -0400
> > Richard Guy Briggs  escreveu:
> > > Describe the /proc/PID/loginuid interface in Documentation/ABI/stable that
> > > was added 2005-02-01 by commit 1e2d1492e178 ("[PATCH] audit: handle
> > > loginuid through proc")
> > >
> > > Signed-off-by: Richard Guy Briggs 
> > > ---
> > >  Documentation/ABI/stable/procfs-audit_loginuid | 15 +++
> > >  1 file changed, 15 insertions(+)
> > >  create mode 100644 Documentation/ABI/stable/procfs-audit_loginuid
> > >
> > > diff --git a/Documentation/ABI/stable/procfs-audit_loginuid 
> > > b/Documentation/ABI/stable/procfs-audit_loginuid
> > > new file mode 100644
> > > index ..e7c100b9ab18
> > > --- /dev/null
> > > +++ b/Documentation/ABI/stable/procfs-audit_loginuid
> > > @@ -0,0 +1,15 @@
> > > +What:Audit Login UID
> > > +Date:2005-02-01
> > > +KernelVersion:   2.6.11-rc2 1e2d1492e178 ("[PATCH] audit: handle 
> > > loginuid through proc")
> > > +Contact: linux-au...@redhat.com
> > > +Format:  %u
> >
> > The ABI definition doesn't include a "Format:" symbol. See:
> >
> > Documentation/ABI/README
> >
> > For the valid ones.
> >
> > This change causes a warning at the ABI parser:
> >
> >
> > $ ./scripts/get_abi.pl validate
> > Warning: file Documentation/ABI/stable/procfs-audit_loginuid#5:
> > tag 'contact' is invalid. Line
> > Format: %u
> > Warning: file Documentation/ABI/stable/procfs-audit_loginuid#21:
> > tag 'contact' is invalid. Line
> > Format: %u
> >
> > You should either drop it or add it to the parser and to the README
> > file, if the ABI maintainers are ok with such new field.
> 
> Thanks Mauro, I didn't realize there were tools that parsed these files.
> 
> Richard, please post a patch that drops the 'Format:' line from the
> newly added audit files as soon as possible so I can merge it into
> audit/next.

Ok.  I'll roll it into the description so we don't lose that
information.

> paul moore

- RGB

--
Richard Guy Briggs 
Sr. S/W Engineer, Kernel Security, Base Operating Systems
Remote, Ottawa, Red Hat Canada
IRC: rgb, SunRaycer
Voice: +1.647.777.2635, Internal: (81) 32635



Re: [PATCH v5] audit: log nftables configuration change events once per table

2021-04-01 Thread Richard Guy Briggs
On 2021-04-01 15:24, Phil Sutter wrote:
> On Fri, Mar 26, 2021 at 01:38:59PM -0400, Richard Guy Briggs wrote:
> > Reduce logging of nftables events to a level similar to iptables.
> > Restore the table field to list the table, adding the generation.
> > 
> > Indicate the op as the most significant operation in the event.
> > 
> > A couple of sample events:
> > 
> > type=PROCTITLE msg=audit(2021-03-18 09:30:49.801:143) : 
> > proctitle=/usr/bin/python3 -s /usr/sbin/firewalld --nofork --nopid
> > type=SYSCALL msg=audit(2021-03-18 09:30:49.801:143) : arch=x86_64 
> > syscall=sendmsg success=yes exit=172 a0=0x6 a1=0x7ffdcfcbe650 a2=0x0 
> > a3=0x7ffdcfcbd52c items=0 ppid=1 pid=367 auid=unset uid=root gid=root 
> > euid=root suid=root fsuid=root egid=roo
> > t sgid=root fsgid=root tty=(none) ses=unset comm=firewalld 
> > exe=/usr/bin/python3.9 subj=system_u:system_r:firewalld_t:s0 key=(null)
> > type=NETFILTER_CFG msg=audit(2021-03-18 09:30:49.801:143) : 
> > table=firewalld:2 family=ipv6 entries=1 op=nft_register_table pid=367 
> > subj=system_u:system_r:firewalld_t:s0 comm=firewalld
> > type=NETFILTER_CFG msg=audit(2021-03-18 09:30:49.801:143) : 
> > table=firewalld:2 family=ipv4 entries=1 op=nft_register_table pid=367 
> > subj=system_u:system_r:firewalld_t:s0 comm=firewalld
> > type=NETFILTER_CFG msg=audit(2021-03-18 09:30:49.801:143) : 
> > table=firewalld:2 family=inet entries=1 op=nft_register_table pid=367 
> > subj=system_u:system_r:firewalld_t:s0 comm=firewalld
> > 
> > type=PROCTITLE msg=audit(2021-03-18 09:30:49.839:144) : 
> > proctitle=/usr/bin/python3 -s /usr/sbin/firewalld --nofork --nopid
> > type=SYSCALL msg=audit(2021-03-18 09:30:49.839:144) : arch=x86_64 
> > syscall=sendmsg success=yes exit=22792 a0=0x6 a1=0x7ffdcfcbe650 a2=0x0 
> > a3=0x7ffdcfcbd52c items=0 ppid=1 pid=367 auid=unset uid=root gid=root 
> > euid=root suid=root fsuid=root egid=r
> > oot sgid=root fsgid=root tty=(none) ses=unset comm=firewalld 
> > exe=/usr/bin/python3.9 subj=system_u:system_r:firewalld_t:s0 key=(null)
> > type=NETFILTER_CFG msg=audit(2021-03-18 09:30:49.839:144) : 
> > table=firewalld:3 family=ipv6 entries=30 op=nft_register_chain pid=367 
> > subj=system_u:system_r:firewalld_t:s0 comm=firewalld
> > type=NETFILTER_CFG msg=audit(2021-03-18 09:30:49.839:144) : 
> > table=firewalld:3 family=ipv4 entries=30 op=nft_register_chain pid=367 
> > subj=system_u:system_r:firewalld_t:s0 comm=firewalld
> > type=NETFILTER_CFG msg=audit(2021-03-18 09:30:49.839:144) : 
> > table=firewalld:3 family=inet entries=165 op=nft_register_chain pid=367 
> > subj=system_u:system_r:firewalld_t:s0 comm=firewalld
> > 
> > The issue was originally documented in
> > https://github.com/linux-audit/audit-kernel/issues/124
> > 
> > Signed-off-by: Richard Guy Briggs 
> 
> Tested this patch to make sure it eliminates the slowdown of
> iptables-nft when auditd is running. With this applied, neither
> iptables-nft-restore nor 'iptables-nft -F' show a significant
> difference in run-time between running or stopped auditd, at least for
> large rulesets. Individual calls suffer from added audit logging, but
> that's expected of course.
> 
> Tested-by: Phil Sutter 

Excellent, thanks Phil for helping nail this one down and confirming the
fix.

> Thanks, Phil

- RGB

--
Richard Guy Briggs 
Sr. S/W Engineer, Kernel Security, Base Operating Systems
Remote, Ottawa, Red Hat Canada
IRC: rgb, SunRaycer
Voice: +1.647.777.2635, Internal: (81) 32635



Re: [PATCH v5] audit: log nftables configuration change events once per table

2021-03-31 Thread Richard Guy Briggs
On 2021-03-31 22:46, Pablo Neira Ayuso wrote:
> On Fri, Mar 26, 2021 at 01:38:59PM -0400, Richard Guy Briggs wrote:
> > @@ -8006,12 +7966,65 @@ static void nft_commit_notify(struct net *net, u32 
> > portid)
> > WARN_ON_ONCE(!list_empty(>nft.notify_list));
> >  }
> >  
> > +static int nf_tables_commit_audit_alloc(struct list_head *adl,
> > +struct nft_table *table)
> > +{
> > +   struct nft_audit_data *adp;
> > +
> > +   list_for_each_entry(adp, adl, list) {
> > +   if (adp->table == table)
> > +   return 0;
> > +   }
> > +   adp = kzalloc(sizeof(*adp), GFP_KERNEL);
> > +   if (!adp)
> > +   return -ENOMEM;
> > +   adp->table = table;
> > +   INIT_LIST_HEAD(>list);
> 
> This INIT_LIST_HEAD is not required for an object that is going to be
> inserted into the 'adl' list.
> 
> > +   list_add(>list, adl);
> 
> If no objections, I'll amend this patch. I'll include the UAF fix and
> remove this unnecessary INIT_LIST_HEAD.

Ok, so it is harmless other than being code noise and overhead, thanks again.

- RGB

--
Richard Guy Briggs 
Sr. S/W Engineer, Kernel Security, Base Operating Systems
Remote, Ottawa, Red Hat Canada
IRC: rgb, SunRaycer
Voice: +1.647.777.2635, Internal: (81) 32635



Re: [PATCH v5] audit: log nftables configuration change events once per table

2021-03-31 Thread Richard Guy Briggs
On 2021-03-31 22:22, Pablo Neira Ayuso wrote:
> On Fri, Mar 26, 2021 at 01:38:59PM -0400, Richard Guy Briggs wrote:
> > Reduce logging of nftables events to a level similar to iptables.
> > Restore the table field to list the table, adding the generation.
> > 
> > Indicate the op as the most significant operation in the event.
> 
> There's a UAF, Florian reported. I'm attaching an incremental fix.
> 
> nf_tables_commit_audit_collect() refers to the trans object which
> might have been already released.

Got it.  Thanks Pablo.  I didn't see it when running nft-test.py Where
was it reported?  Here I tried to stay out of the way by putting that
call at the end of the loop but that was obviously a mistake in
hindsight.  :-)

> commit e4d272948d25b66d86fc241cefd95281bfb1079e
> Author: Pablo Neira Ayuso 
> Date:   Wed Mar 31 22:19:51 2021 +0200
> 
> netfilter: nf_tables: use-after-free
> 
> Signed-off-by: Pablo Neira Ayuso 
> 
> diff --git a/net/netfilter/nf_tables_api.c b/net/netfilter/nf_tables_api.c
> index 5dd4bb7cabf5..01674c0d9103 100644
> --- a/net/netfilter/nf_tables_api.c
> +++ b/net/netfilter/nf_tables_api.c
> @@ -8063,6 +8063,8 @@ static int nf_tables_commit(struct net *net, struct 
> sk_buff *skb)
>   net->nft.gencursor = nft_gencursor_next(net);
>  
>   list_for_each_entry_safe(trans, next, >nft.commit_list, list) {
> + nf_tables_commit_audit_collect(, trans->ctx.table,
> +trans->msg_type);
>   switch (trans->msg_type) {
>   case NFT_MSG_NEWTABLE:
>   if (nft_trans_table_update(trans)) {
> @@ -8211,8 +8213,6 @@ static int nf_tables_commit(struct net *net, struct 
> sk_buff *skb)
>   }
>   break;
>   }
> - nf_tables_commit_audit_collect(, trans->ctx.table,
> -        trans->msg_type);
>   }
>  
>   nft_commit_notify(net, NETLINK_CB(skb).portid);


- RGB

--
Richard Guy Briggs 
Sr. S/W Engineer, Kernel Security, Base Operating Systems
Remote, Ottawa, Red Hat Canada
IRC: rgb, SunRaycer
Voice: +1.647.777.2635, Internal: (81) 32635



[PATCH v5] audit: log nftables configuration change events once per table

2021-03-26 Thread Richard Guy Briggs
Reduce logging of nftables events to a level similar to iptables.
Restore the table field to list the table, adding the generation.

Indicate the op as the most significant operation in the event.

A couple of sample events:

type=PROCTITLE msg=audit(2021-03-18 09:30:49.801:143) : 
proctitle=/usr/bin/python3 -s /usr/sbin/firewalld --nofork --nopid
type=SYSCALL msg=audit(2021-03-18 09:30:49.801:143) : arch=x86_64 
syscall=sendmsg success=yes exit=172 a0=0x6 a1=0x7ffdcfcbe650 a2=0x0 
a3=0x7ffdcfcbd52c items=0 ppid=1 pid=367 auid=unset uid=root gid=root euid=root 
suid=root fsuid=root egid=roo
t sgid=root fsgid=root tty=(none) ses=unset comm=firewalld 
exe=/usr/bin/python3.9 subj=system_u:system_r:firewalld_t:s0 key=(null)
type=NETFILTER_CFG msg=audit(2021-03-18 09:30:49.801:143) : table=firewalld:2 
family=ipv6 entries=1 op=nft_register_table pid=367 
subj=system_u:system_r:firewalld_t:s0 comm=firewalld
type=NETFILTER_CFG msg=audit(2021-03-18 09:30:49.801:143) : table=firewalld:2 
family=ipv4 entries=1 op=nft_register_table pid=367 
subj=system_u:system_r:firewalld_t:s0 comm=firewalld
type=NETFILTER_CFG msg=audit(2021-03-18 09:30:49.801:143) : table=firewalld:2 
family=inet entries=1 op=nft_register_table pid=367 
subj=system_u:system_r:firewalld_t:s0 comm=firewalld

type=PROCTITLE msg=audit(2021-03-18 09:30:49.839:144) : 
proctitle=/usr/bin/python3 -s /usr/sbin/firewalld --nofork --nopid
type=SYSCALL msg=audit(2021-03-18 09:30:49.839:144) : arch=x86_64 
syscall=sendmsg success=yes exit=22792 a0=0x6 a1=0x7ffdcfcbe650 a2=0x0 
a3=0x7ffdcfcbd52c items=0 ppid=1 pid=367 auid=unset uid=root gid=root euid=root 
suid=root fsuid=root egid=r
oot sgid=root fsgid=root tty=(none) ses=unset comm=firewalld 
exe=/usr/bin/python3.9 subj=system_u:system_r:firewalld_t:s0 key=(null)
type=NETFILTER_CFG msg=audit(2021-03-18 09:30:49.839:144) : table=firewalld:3 
family=ipv6 entries=30 op=nft_register_chain pid=367 
subj=system_u:system_r:firewalld_t:s0 comm=firewalld
type=NETFILTER_CFG msg=audit(2021-03-18 09:30:49.839:144) : table=firewalld:3 
family=ipv4 entries=30 op=nft_register_chain pid=367 
subj=system_u:system_r:firewalld_t:s0 comm=firewalld
type=NETFILTER_CFG msg=audit(2021-03-18 09:30:49.839:144) : table=firewalld:3 
family=inet entries=165 op=nft_register_chain pid=367 
subj=system_u:system_r:firewalld_t:s0 comm=firewalld

The issue was originally documented in
https://github.com/linux-audit/audit-kernel/issues/124

Signed-off-by: Richard Guy Briggs 
---
Changelog:
v5:
(sorry for all the noise...)
- fix kbuild missing prototype warning in 
nf_tables_commit_audit_{alloc,collect,log}() 

v4:
- move nf_tables_commit_audit_log() before nf_tables_commit_release() [fw]
- move nft2audit_op[] from audit.h to nf_tables_api.c

v3:
- fix function braces, reduce parameter scope [pna]
- pre-allocate nft_audit_data per table in step 1, bail on ENOMEM [pna]

v2:
- convert NFT ops to array indicies in nft2audit_op[] [ps]
- use linux lists [pna]
- use functions for each of collection and logging of audit data [pna]
---
 net/netfilter/nf_tables_api.c | 187 +++---
 1 file changed, 104 insertions(+), 83 deletions(-)

diff --git a/net/netfilter/nf_tables_api.c b/net/netfilter/nf_tables_api.c
index c1eb5cdb3033..ef51abe3a6d7 100644
--- a/net/netfilter/nf_tables_api.c
+++ b/net/netfilter/nf_tables_api.c
@@ -66,6 +66,41 @@ static const struct rhashtable_params nft_objname_ht_params 
= {
.automatic_shrinking= true,
 };
 
+struct nft_audit_data {
+   struct nft_table *table;
+   int entries;
+   int op;
+   struct list_head list;
+};
+
+static const u8 nft2audit_op[NFT_MSG_MAX] = { // enum nf_tables_msg_types
+   [NFT_MSG_NEWTABLE]  = AUDIT_NFT_OP_TABLE_REGISTER,
+   [NFT_MSG_GETTABLE]  = AUDIT_NFT_OP_INVALID,
+   [NFT_MSG_DELTABLE]  = AUDIT_NFT_OP_TABLE_UNREGISTER,
+   [NFT_MSG_NEWCHAIN]  = AUDIT_NFT_OP_CHAIN_REGISTER,
+   [NFT_MSG_GETCHAIN]  = AUDIT_NFT_OP_INVALID,
+   [NFT_MSG_DELCHAIN]  = AUDIT_NFT_OP_CHAIN_UNREGISTER,
+   [NFT_MSG_NEWRULE]   = AUDIT_NFT_OP_RULE_REGISTER,
+   [NFT_MSG_GETRULE]   = AUDIT_NFT_OP_INVALID,
+   [NFT_MSG_DELRULE]   = AUDIT_NFT_OP_RULE_UNREGISTER,
+   [NFT_MSG_NEWSET]= AUDIT_NFT_OP_SET_REGISTER,
+   [NFT_MSG_GETSET]= AUDIT_NFT_OP_INVALID,
+   [NFT_MSG_DELSET]= AUDIT_NFT_OP_SET_UNREGISTER,
+   [NFT_MSG_NEWSETELEM]= AUDIT_NFT_OP_SETELEM_REGISTER,
+   [NFT_MSG_GETSETELEM]= AUDIT_NFT_OP_INVALID,
+   [NFT_MSG_DELSETELEM]= AUDIT_NFT_OP_SETELEM_UNREGISTER,
+   [NFT_MSG_NEWGEN]= AUDIT_NFT_OP_GEN_REGISTER,
+   [NFT_MSG_GETGEN]= AUDIT_NFT_OP_INVALID,
+   [NFT_MSG_TRACE] = AUDIT_NFT_OP_INVALID,
+   [NFT_MSG_NEWOBJ]= AUDIT_NFT_OP_OBJ_REGISTER,
+   [NFT_MSG_GETOBJ]= AUDIT_NFT_OP_INVALID,
+   [NFT_MSG_DELOBJ]= AUDIT_NFT_OP_OBJ_UNREGISTER,
+   [NFT_MSG_GETOBJ_RESET

[PATCH v4] audit: log nftables configuration change events once per table

2021-03-24 Thread Richard Guy Briggs
Reduce logging of nftables events to a level similar to iptables.
Restore the table field to list the table, adding the generation.

Indicate the op as the most significant operation in the event.

A couple of sample events:

type=PROCTITLE msg=audit(2021-03-18 09:30:49.801:143) : 
proctitle=/usr/bin/python3 -s /usr/sbin/firewalld --nofork --nopid
type=SYSCALL msg=audit(2021-03-18 09:30:49.801:143) : arch=x86_64 
syscall=sendmsg success=yes exit=172 a0=0x6 a1=0x7ffdcfcbe650 a2=0x0 
a3=0x7ffdcfcbd52c items=0 ppid=1 pid=367 auid=unset uid=root gid=root euid=root 
suid=root fsuid=root egid=roo
t sgid=root fsgid=root tty=(none) ses=unset comm=firewalld 
exe=/usr/bin/python3.9 subj=system_u:system_r:firewalld_t:s0 key=(null)
type=NETFILTER_CFG msg=audit(2021-03-18 09:30:49.801:143) : table=firewalld:2 
family=ipv6 entries=1 op=nft_register_table pid=367 
subj=system_u:system_r:firewalld_t:s0 comm=firewalld
type=NETFILTER_CFG msg=audit(2021-03-18 09:30:49.801:143) : table=firewalld:2 
family=ipv4 entries=1 op=nft_register_table pid=367 
subj=system_u:system_r:firewalld_t:s0 comm=firewalld
type=NETFILTER_CFG msg=audit(2021-03-18 09:30:49.801:143) : table=firewalld:2 
family=inet entries=1 op=nft_register_table pid=367 
subj=system_u:system_r:firewalld_t:s0 comm=firewalld

type=PROCTITLE msg=audit(2021-03-18 09:30:49.839:144) : 
proctitle=/usr/bin/python3 -s /usr/sbin/firewalld --nofork --nopid
type=SYSCALL msg=audit(2021-03-18 09:30:49.839:144) : arch=x86_64 
syscall=sendmsg success=yes exit=22792 a0=0x6 a1=0x7ffdcfcbe650 a2=0x0 
a3=0x7ffdcfcbd52c items=0 ppid=1 pid=367 auid=unset uid=root gid=root euid=root 
suid=root fsuid=root egid=r
oot sgid=root fsgid=root tty=(none) ses=unset comm=firewalld 
exe=/usr/bin/python3.9 subj=system_u:system_r:firewalld_t:s0 key=(null)
type=NETFILTER_CFG msg=audit(2021-03-18 09:30:49.839:144) : table=firewalld:3 
family=ipv6 entries=30 op=nft_register_chain pid=367 
subj=system_u:system_r:firewalld_t:s0 comm=firewalld
type=NETFILTER_CFG msg=audit(2021-03-18 09:30:49.839:144) : table=firewalld:3 
family=ipv4 entries=30 op=nft_register_chain pid=367 
subj=system_u:system_r:firewalld_t:s0 comm=firewalld
type=NETFILTER_CFG msg=audit(2021-03-18 09:30:49.839:144) : table=firewalld:3 
family=inet entries=165 op=nft_register_chain pid=367 
subj=system_u:system_r:firewalld_t:s0 comm=firewalld

The issue was originally documented in
https://github.com/linux-audit/audit-kernel/issues/124

Signed-off-by: Richard Guy Briggs 
---
Changelog:
v4:
- move nf_tables_commit_audit_log() before nf_tables_commit_release() [fw]
- move nft2audit_op[] from audit.h to nf_tables_api.c

v3:
- fix function braces, reduce parameter scope [pna]
- pre-allocate nft_audit_data per table in step 1, bail on ENOMEM [pna]

v2:
- convert NFT ops to array indicies in nft2audit_op[] [ps]
- use linux lists [pna]
- use functions for each of collection and logging of audit data [pna]
---
 net/netfilter/nf_tables_api.c | 187 +++---
 1 file changed, 104 insertions(+), 83 deletions(-)

diff --git a/net/netfilter/nf_tables_api.c b/net/netfilter/nf_tables_api.c
index c1eb5cdb3033..9c930fe72005 100644
--- a/net/netfilter/nf_tables_api.c
+++ b/net/netfilter/nf_tables_api.c
@@ -66,6 +66,41 @@ static const struct rhashtable_params nft_objname_ht_params 
= {
.automatic_shrinking= true,
 };
 
+struct nft_audit_data {
+   struct nft_table *table;
+   int entries;
+   int op;
+   struct list_head list;
+};
+
+static const u8 nft2audit_op[NFT_MSG_MAX] = { // enum nf_tables_msg_types
+   [NFT_MSG_NEWTABLE]  = AUDIT_NFT_OP_TABLE_REGISTER,
+   [NFT_MSG_GETTABLE]  = AUDIT_NFT_OP_INVALID,
+   [NFT_MSG_DELTABLE]  = AUDIT_NFT_OP_TABLE_UNREGISTER,
+   [NFT_MSG_NEWCHAIN]  = AUDIT_NFT_OP_CHAIN_REGISTER,
+   [NFT_MSG_GETCHAIN]  = AUDIT_NFT_OP_INVALID,
+   [NFT_MSG_DELCHAIN]  = AUDIT_NFT_OP_CHAIN_UNREGISTER,
+   [NFT_MSG_NEWRULE]   = AUDIT_NFT_OP_RULE_REGISTER,
+   [NFT_MSG_GETRULE]   = AUDIT_NFT_OP_INVALID,
+   [NFT_MSG_DELRULE]   = AUDIT_NFT_OP_RULE_UNREGISTER,
+   [NFT_MSG_NEWSET]= AUDIT_NFT_OP_SET_REGISTER,
+   [NFT_MSG_GETSET]= AUDIT_NFT_OP_INVALID,
+   [NFT_MSG_DELSET]= AUDIT_NFT_OP_SET_UNREGISTER,
+   [NFT_MSG_NEWSETELEM]= AUDIT_NFT_OP_SETELEM_REGISTER,
+   [NFT_MSG_GETSETELEM]= AUDIT_NFT_OP_INVALID,
+   [NFT_MSG_DELSETELEM]= AUDIT_NFT_OP_SETELEM_UNREGISTER,
+   [NFT_MSG_NEWGEN]= AUDIT_NFT_OP_GEN_REGISTER,
+   [NFT_MSG_GETGEN]= AUDIT_NFT_OP_INVALID,
+   [NFT_MSG_TRACE] = AUDIT_NFT_OP_INVALID,
+   [NFT_MSG_NEWOBJ]= AUDIT_NFT_OP_OBJ_REGISTER,
+   [NFT_MSG_GETOBJ]= AUDIT_NFT_OP_INVALID,
+   [NFT_MSG_DELOBJ]= AUDIT_NFT_OP_OBJ_UNREGISTER,
+   [NFT_MSG_GETOBJ_RESET]  = AUDIT_NFT_OP_OBJ_RESET,
+   [NFT_MSG_NEWFLOWTABLE]  = AUDIT_NFT_OP_FLOWTABLE_REGISTER,
+   [NFT_MSG_GETFLOWTABLE

Re: [PATCH v3] audit: log nftables configuration change events once per table

2021-03-24 Thread Richard Guy Briggs
On 2021-03-24 12:32, Paul Moore wrote:
> On Tue, Mar 23, 2021 at 4:05 PM Richard Guy Briggs  wrote:
> >
> > Reduce logging of nftables events to a level similar to iptables.
> > Restore the table field to list the table, adding the generation.
> >
> > Indicate the op as the most significant operation in the event.
> >
> > A couple of sample events:
> >
> > type=PROCTITLE msg=audit(2021-03-18 09:30:49.801:143) : 
> > proctitle=/usr/bin/python3 -s /usr/sbin/firewalld --nofork --nopid
> > type=SYSCALL msg=audit(2021-03-18 09:30:49.801:143) : arch=x86_64 
> > syscall=sendmsg success=yes exit=172 a0=0x6 a1=0x7ffdcfcbe650 a2=0x0 
> > a3=0x7ffdcfcbd52c items=0 ppid=1 pid=367 auid=unset uid=root gid=root 
> > euid=root suid=root fsuid=root egid=roo
> > t sgid=root fsgid=root tty=(none) ses=unset comm=firewalld 
> > exe=/usr/bin/python3.9 subj=system_u:system_r:firewalld_t:s0 key=(null)
> > type=NETFILTER_CFG msg=audit(2021-03-18 09:30:49.801:143) : 
> > table=firewalld:2 family=ipv6 entries=1 op=nft_register_table pid=367 
> > subj=system_u:system_r:firewalld_t:s0 comm=firewalld
> > type=NETFILTER_CFG msg=audit(2021-03-18 09:30:49.801:143) : 
> > table=firewalld:2 family=ipv4 entries=1 op=nft_register_table pid=367 
> > subj=system_u:system_r:firewalld_t:s0 comm=firewalld
> > type=NETFILTER_CFG msg=audit(2021-03-18 09:30:49.801:143) : 
> > table=firewalld:2 family=inet entries=1 op=nft_register_table pid=367 
> > subj=system_u:system_r:firewalld_t:s0 comm=firewalld
> >
> > type=PROCTITLE msg=audit(2021-03-18 09:30:49.839:144) : 
> > proctitle=/usr/bin/python3 -s /usr/sbin/firewalld --nofork --nopid
> > type=SYSCALL msg=audit(2021-03-18 09:30:49.839:144) : arch=x86_64 
> > syscall=sendmsg success=yes exit=22792 a0=0x6 a1=0x7ffdcfcbe650 a2=0x0 
> > a3=0x7ffdcfcbd52c items=0 ppid=1 pid=367 auid=unset uid=root gid=root 
> > euid=root suid=root fsuid=root egid=r
> > oot sgid=root fsgid=root tty=(none) ses=unset comm=firewalld 
> > exe=/usr/bin/python3.9 subj=system_u:system_r:firewalld_t:s0 key=(null)
> > type=NETFILTER_CFG msg=audit(2021-03-18 09:30:49.839:144) : 
> > table=firewalld:3 family=ipv6 entries=30 op=nft_register_chain pid=367 
> > subj=system_u:system_r:firewalld_t:s0 comm=firewalld
> > type=NETFILTER_CFG msg=audit(2021-03-18 09:30:49.839:144) : 
> > table=firewalld:3 family=ipv4 entries=30 op=nft_register_chain pid=367 
> > subj=system_u:system_r:firewalld_t:s0 comm=firewalld
> > type=NETFILTER_CFG msg=audit(2021-03-18 09:30:49.839:144) : 
> > table=firewalld:3 family=inet entries=165 op=nft_register_chain pid=367 
> > subj=system_u:system_r:firewalld_t:s0 comm=firewalld
> >
> > The issue was originally documented in
> > https://github.com/linux-audit/audit-kernel/issues/124
> >
> > Signed-off-by: Richard Guy Briggs 
> > ---
> > Changelog:
> > v3:
> > - fix function braces, reduce parameter scope
> > - pre-allocate nft_audit_data per table in step 1, bail on ENOMEM
> >
> > v2:
> > - convert NFT ops to array indicies in nft2audit_op[]
> > - use linux lists
> > - use functions for each of collection and logging of audit data
> > ---
> >  include/linux/audit.h |  28 ++
> >  net/netfilter/nf_tables_api.c | 160 --
> >  2 files changed, 105 insertions(+), 83 deletions(-)
> 
> ...
> 
> > diff --git a/include/linux/audit.h b/include/linux/audit.h
> > index 82b7c1116a85..5fafcf4c13de 100644
> > --- a/include/linux/audit.h
> > +++ b/include/linux/audit.h
> > @@ -118,6 +118,34 @@ enum audit_nfcfgop {
> > AUDIT_NFT_OP_INVALID,
> >  };
> >
> > +static const u8 nft2audit_op[NFT_MSG_MAX] = { // enum nf_tables_msg_types
> > +   [NFT_MSG_NEWTABLE]  = AUDIT_NFT_OP_TABLE_REGISTER,
> > +   [NFT_MSG_GETTABLE]  = AUDIT_NFT_OP_INVALID,
> > +   [NFT_MSG_DELTABLE]  = AUDIT_NFT_OP_TABLE_UNREGISTER,
> > +   [NFT_MSG_NEWCHAIN]  = AUDIT_NFT_OP_CHAIN_REGISTER,
> > +   [NFT_MSG_GETCHAIN]  = AUDIT_NFT_OP_INVALID,
> > +   [NFT_MSG_DELCHAIN]  = AUDIT_NFT_OP_CHAIN_UNREGISTER,
> > +   [NFT_MSG_NEWRULE]   = AUDIT_NFT_OP_RULE_REGISTER,
> > +   [NFT_MSG_GETRULE]   = AUDIT_NFT_OP_INVALID,
> > +   [NFT_MSG_DELRULE]   = AUDIT_NFT_OP_RULE_UNREGISTER,
> > +   [NFT_MSG_NEWSET]= AUDIT_NFT_OP_SET_REGISTER,
> > +   [NFT_MSG_GETSET]= AUDIT_NFT_OP_INVALID,
> > +   [NFT_MSG_DELSET]= AUDIT_NFT_OP_SET_UNREGISTER,
> > +   [NFT_MSG_NEWSETELEM]= AUDIT_NFT_OP_SETELEM_

[PATCH v3] audit: log nftables configuration change events once per table

2021-03-23 Thread Richard Guy Briggs
Reduce logging of nftables events to a level similar to iptables.
Restore the table field to list the table, adding the generation.

Indicate the op as the most significant operation in the event.

A couple of sample events:

type=PROCTITLE msg=audit(2021-03-18 09:30:49.801:143) : 
proctitle=/usr/bin/python3 -s /usr/sbin/firewalld --nofork --nopid
type=SYSCALL msg=audit(2021-03-18 09:30:49.801:143) : arch=x86_64 
syscall=sendmsg success=yes exit=172 a0=0x6 a1=0x7ffdcfcbe650 a2=0x0 
a3=0x7ffdcfcbd52c items=0 ppid=1 pid=367 auid=unset uid=root gid=root euid=root 
suid=root fsuid=root egid=roo
t sgid=root fsgid=root tty=(none) ses=unset comm=firewalld 
exe=/usr/bin/python3.9 subj=system_u:system_r:firewalld_t:s0 key=(null)
type=NETFILTER_CFG msg=audit(2021-03-18 09:30:49.801:143) : table=firewalld:2 
family=ipv6 entries=1 op=nft_register_table pid=367 
subj=system_u:system_r:firewalld_t:s0 comm=firewalld
type=NETFILTER_CFG msg=audit(2021-03-18 09:30:49.801:143) : table=firewalld:2 
family=ipv4 entries=1 op=nft_register_table pid=367 
subj=system_u:system_r:firewalld_t:s0 comm=firewalld
type=NETFILTER_CFG msg=audit(2021-03-18 09:30:49.801:143) : table=firewalld:2 
family=inet entries=1 op=nft_register_table pid=367 
subj=system_u:system_r:firewalld_t:s0 comm=firewalld

type=PROCTITLE msg=audit(2021-03-18 09:30:49.839:144) : 
proctitle=/usr/bin/python3 -s /usr/sbin/firewalld --nofork --nopid
type=SYSCALL msg=audit(2021-03-18 09:30:49.839:144) : arch=x86_64 
syscall=sendmsg success=yes exit=22792 a0=0x6 a1=0x7ffdcfcbe650 a2=0x0 
a3=0x7ffdcfcbd52c items=0 ppid=1 pid=367 auid=unset uid=root gid=root euid=root 
suid=root fsuid=root egid=r
oot sgid=root fsgid=root tty=(none) ses=unset comm=firewalld 
exe=/usr/bin/python3.9 subj=system_u:system_r:firewalld_t:s0 key=(null)
type=NETFILTER_CFG msg=audit(2021-03-18 09:30:49.839:144) : table=firewalld:3 
family=ipv6 entries=30 op=nft_register_chain pid=367 
subj=system_u:system_r:firewalld_t:s0 comm=firewalld
type=NETFILTER_CFG msg=audit(2021-03-18 09:30:49.839:144) : table=firewalld:3 
family=ipv4 entries=30 op=nft_register_chain pid=367 
subj=system_u:system_r:firewalld_t:s0 comm=firewalld
type=NETFILTER_CFG msg=audit(2021-03-18 09:30:49.839:144) : table=firewalld:3 
family=inet entries=165 op=nft_register_chain pid=367 
subj=system_u:system_r:firewalld_t:s0 comm=firewalld

The issue was originally documented in
https://github.com/linux-audit/audit-kernel/issues/124

Signed-off-by: Richard Guy Briggs 
---
Changelog:
v3:
- fix function braces, reduce parameter scope
- pre-allocate nft_audit_data per table in step 1, bail on ENOMEM

v2:
- convert NFT ops to array indicies in nft2audit_op[]
- use linux lists
- use functions for each of collection and logging of audit data
---
 include/linux/audit.h |  28 ++
 net/netfilter/nf_tables_api.c | 160 --
 2 files changed, 105 insertions(+), 83 deletions(-)

diff --git a/include/linux/audit.h b/include/linux/audit.h
index 82b7c1116a85..5fafcf4c13de 100644
--- a/include/linux/audit.h
+++ b/include/linux/audit.h
@@ -118,6 +118,34 @@ enum audit_nfcfgop {
AUDIT_NFT_OP_INVALID,
 };
 
+static const u8 nft2audit_op[NFT_MSG_MAX] = { // enum nf_tables_msg_types
+   [NFT_MSG_NEWTABLE]  = AUDIT_NFT_OP_TABLE_REGISTER,
+   [NFT_MSG_GETTABLE]  = AUDIT_NFT_OP_INVALID,
+   [NFT_MSG_DELTABLE]  = AUDIT_NFT_OP_TABLE_UNREGISTER,
+   [NFT_MSG_NEWCHAIN]  = AUDIT_NFT_OP_CHAIN_REGISTER,
+   [NFT_MSG_GETCHAIN]  = AUDIT_NFT_OP_INVALID,
+   [NFT_MSG_DELCHAIN]  = AUDIT_NFT_OP_CHAIN_UNREGISTER,
+   [NFT_MSG_NEWRULE]   = AUDIT_NFT_OP_RULE_REGISTER,
+   [NFT_MSG_GETRULE]   = AUDIT_NFT_OP_INVALID,
+   [NFT_MSG_DELRULE]   = AUDIT_NFT_OP_RULE_UNREGISTER,
+   [NFT_MSG_NEWSET]= AUDIT_NFT_OP_SET_REGISTER,
+   [NFT_MSG_GETSET]= AUDIT_NFT_OP_INVALID,
+   [NFT_MSG_DELSET]= AUDIT_NFT_OP_SET_UNREGISTER,
+   [NFT_MSG_NEWSETELEM]= AUDIT_NFT_OP_SETELEM_REGISTER,
+   [NFT_MSG_GETSETELEM]= AUDIT_NFT_OP_INVALID,
+   [NFT_MSG_DELSETELEM]= AUDIT_NFT_OP_SETELEM_UNREGISTER,
+   [NFT_MSG_NEWGEN]= AUDIT_NFT_OP_GEN_REGISTER,
+   [NFT_MSG_GETGEN]= AUDIT_NFT_OP_INVALID,
+   [NFT_MSG_TRACE] = AUDIT_NFT_OP_INVALID,
+   [NFT_MSG_NEWOBJ]= AUDIT_NFT_OP_OBJ_REGISTER,
+   [NFT_MSG_GETOBJ]= AUDIT_NFT_OP_INVALID,
+   [NFT_MSG_DELOBJ]= AUDIT_NFT_OP_OBJ_UNREGISTER,
+   [NFT_MSG_GETOBJ_RESET]  = AUDIT_NFT_OP_OBJ_RESET,
+   [NFT_MSG_NEWFLOWTABLE]  = AUDIT_NFT_OP_FLOWTABLE_REGISTER,
+   [NFT_MSG_GETFLOWTABLE]  = AUDIT_NFT_OP_INVALID,
+   [NFT_MSG_DELFLOWTABLE]  = AUDIT_NFT_OP_FLOWTABLE_UNREGISTER,
+};
+
 extern int is_audit_feature_set(int which);
 
 extern int __init audit_register_class(int class, unsigned *list);
diff --git a/net/netfilter/nf_tables_api.c b/net/netfilter/nf_tables_api.c
index c1eb5cdb3033..e48554a5c14e 100644

Re: [PATCH v2] audit: log nftables configuration change events once per table

2021-03-23 Thread Richard Guy Briggs
On 2021-03-22 23:57, Pablo Neira Ayuso wrote:
> On Mon, Mar 22, 2021 at 04:49:04PM -0400, Richard Guy Briggs wrote:
> > diff --git a/net/netfilter/nf_tables_api.c b/net/netfilter/nf_tables_api.c
> > index c1eb5cdb3033..42ba44890523 100644
> > --- a/net/netfilter/nf_tables_api.c
> > +++ b/net/netfilter/nf_tables_api.c
> [...]
> > @@ -8006,12 +7938,47 @@ static void nft_commit_notify(struct net *net, u32 
> > portid)
> > WARN_ON_ONCE(!list_empty(>nft.notify_list));
> >  }
> >  
> > +void nf_tables_commit_audit_collect(struct list_head *adl,
> > +   struct nft_trans *trans) {
> 
> nitpick: curly brace starts in the line.

Duh, whoops!  Brain fart.  Too much muckin' in other codebases...

> > +   struct nft_audit_data *adp;
> > +
> > +   list_for_each_entry(adp, adl, list) {
> > +   if (adp->table == trans->ctx.table)
> > +   goto found;
> > +   }
> > +   adp = kzalloc(sizeof(*adp), GFP_KERNEL);
> 
> if (!adp)
> ...

This will need a bit more work since by the time this is called,
nf_tables_commit() is not prepared to accept any errors, so I'll need to
either ignore the error and continue, or allocate the table entries
before step 3.

> > +   adp->table = trans->ctx.table;
> > +   INIT_LIST_HEAD(>list);
> > +   list_add(>list, adl);
> > +found:
> > +   adp->entries++;
> > +   if (!adp->op || adp->op > trans->msg_type)
> > +   adp->op = trans->msg_type;
> > +}
> > +
> > +#define AUNFTABLENAMELEN (NFT_TABLE_MAXNAMELEN + 22)
> > +
> > +void nf_tables_commit_audit_log(struct list_head *adl, u32 generation) {
>   ^
> same thing here
> 
> > +   struct nft_audit_data *adp, *adn;
> > +   char aubuf[AUNFTABLENAMELEN];
> > +
> > +   list_for_each_entry_safe(adp, adn, adl, list) {
> > +   snprintf(aubuf, AUNFTABLENAMELEN, "%s:%u", adp->table->name,
> > +generation);
> > +   audit_log_nfcfg(aubuf, adp->table->family, adp->entries,
> > +   nft2audit_op[adp->op], GFP_KERNEL);
> > +   list_del(>list);
> > +   kfree(adp);
> > +   }
> > +}
> > +
> >  static int nf_tables_commit(struct net *net, struct sk_buff *skb)
> >  {
> > struct nft_trans *trans, *next;
> > struct nft_trans_elem *te;
> > struct nft_chain *chain;
> > struct nft_table *table;
> > +   LIST_HEAD(adl);
> > int err;
> >  
> > if (list_empty(>nft.commit_list)) {
> > @@ -8206,12 +8173,15 @@ static int nf_tables_commit(struct net *net, struct 
> > sk_buff *skb)
> > }
> > break;
> > }
> > +   nf_tables_commit_audit_collect(, trans);
> > }
> >  
> > nft_commit_notify(net, NETLINK_CB(skb).portid);
> > nf_tables_gen_notify(net, skb, NFT_MSG_NEWGEN);
> > nf_tables_commit_release(net);
> >  
> > +   nf_tables_commit_audit_log(, net->nft.base_seq);
> > +
> 
> This looks more self-contained and nicer, thanks.
> 
> --
> Linux-audit mailing list
> linux-au...@redhat.com
> https://listman.redhat.com/mailman/listinfo/linux-audit

- RGB

--
Richard Guy Briggs 
Sr. S/W Engineer, Kernel Security, Base Operating Systems
Remote, Ottawa, Red Hat Canada
IRC: rgb, SunRaycer
Voice: +1.647.777.2635, Internal: (81) 32635



[PATCH v2] audit: log nftables configuration change events once per table

2021-03-22 Thread Richard Guy Briggs
Reduce logging of nftables events to a level similar to iptables.
Restore the table field to list the table, adding the generation.

Indicate the op as the most significant operation in the event.

A couple of sample events:

type=PROCTITLE msg=audit(2021-03-18 09:30:49.801:143) : 
proctitle=/usr/bin/python3 -s /usr/sbin/firewalld --nofork --nopid
type=SYSCALL msg=audit(2021-03-18 09:30:49.801:143) : arch=x86_64 
syscall=sendmsg success=yes exit=172 a0=0x6 a1=0x7ffdcfcbe650 a2=0x0 
a3=0x7ffdcfcbd52c items=0 ppid=1 pid=367 auid=unset uid=root gid=root euid=root 
suid=root fsuid=root egid=roo
t sgid=root fsgid=root tty=(none) ses=unset comm=firewalld 
exe=/usr/bin/python3.9 subj=system_u:system_r:firewalld_t:s0 key=(null)
type=NETFILTER_CFG msg=audit(2021-03-18 09:30:49.801:143) : table=firewalld:2 
family=ipv6 entries=1 op=nft_register_table pid=367 
subj=system_u:system_r:firewalld_t:s0 comm=firewalld
type=NETFILTER_CFG msg=audit(2021-03-18 09:30:49.801:143) : table=firewalld:2 
family=ipv4 entries=1 op=nft_register_table pid=367 
subj=system_u:system_r:firewalld_t:s0 comm=firewalld
type=NETFILTER_CFG msg=audit(2021-03-18 09:30:49.801:143) : table=firewalld:2 
family=inet entries=1 op=nft_register_table pid=367 
subj=system_u:system_r:firewalld_t:s0 comm=firewalld

type=PROCTITLE msg=audit(2021-03-18 09:30:49.839:144) : 
proctitle=/usr/bin/python3 -s /usr/sbin/firewalld --nofork --nopid
type=SYSCALL msg=audit(2021-03-18 09:30:49.839:144) : arch=x86_64 
syscall=sendmsg success=yes exit=22792 a0=0x6 a1=0x7ffdcfcbe650 a2=0x0 
a3=0x7ffdcfcbd52c items=0 ppid=1 pid=367 auid=unset uid=root gid=root euid=root 
suid=root fsuid=root egid=r
oot sgid=root fsgid=root tty=(none) ses=unset comm=firewalld 
exe=/usr/bin/python3.9 subj=system_u:system_r:firewalld_t:s0 key=(null)
type=NETFILTER_CFG msg=audit(2021-03-18 09:30:49.839:144) : table=firewalld:3 
family=ipv6 entries=30 op=nft_register_chain pid=367 
subj=system_u:system_r:firewalld_t:s0 comm=firewalld
type=NETFILTER_CFG msg=audit(2021-03-18 09:30:49.839:144) : table=firewalld:3 
family=ipv4 entries=30 op=nft_register_chain pid=367 
subj=system_u:system_r:firewalld_t:s0 comm=firewalld
type=NETFILTER_CFG msg=audit(2021-03-18 09:30:49.839:144) : table=firewalld:3 
family=inet entries=165 op=nft_register_chain pid=367 
subj=system_u:system_r:firewalld_t:s0 comm=firewalld

The issue was originally documented in
https://github.com/linux-audit/audit-kernel/issues/124

Signed-off-by: Richard Guy Briggs 
---
Changelog
v2:
- convert NFT ops to array indicies in nft2audit_op[]
- use linux lists
- use functions for each of collection and logging of audit data
---
 include/linux/audit.h |  28 +++
 net/netfilter/nf_tables_api.c | 136 +-
 2 files changed, 81 insertions(+), 83 deletions(-)

diff --git a/include/linux/audit.h b/include/linux/audit.h
index 82b7c1116a85..5fafcf4c13de 100644
--- a/include/linux/audit.h
+++ b/include/linux/audit.h
@@ -118,6 +118,34 @@ enum audit_nfcfgop {
AUDIT_NFT_OP_INVALID,
 };
 
+static const u8 nft2audit_op[NFT_MSG_MAX] = { // enum nf_tables_msg_types
+   [NFT_MSG_NEWTABLE]  = AUDIT_NFT_OP_TABLE_REGISTER,
+   [NFT_MSG_GETTABLE]  = AUDIT_NFT_OP_INVALID,
+   [NFT_MSG_DELTABLE]  = AUDIT_NFT_OP_TABLE_UNREGISTER,
+   [NFT_MSG_NEWCHAIN]  = AUDIT_NFT_OP_CHAIN_REGISTER,
+   [NFT_MSG_GETCHAIN]  = AUDIT_NFT_OP_INVALID,
+   [NFT_MSG_DELCHAIN]  = AUDIT_NFT_OP_CHAIN_UNREGISTER,
+   [NFT_MSG_NEWRULE]   = AUDIT_NFT_OP_RULE_REGISTER,
+   [NFT_MSG_GETRULE]   = AUDIT_NFT_OP_INVALID,
+   [NFT_MSG_DELRULE]   = AUDIT_NFT_OP_RULE_UNREGISTER,
+   [NFT_MSG_NEWSET]= AUDIT_NFT_OP_SET_REGISTER,
+   [NFT_MSG_GETSET]= AUDIT_NFT_OP_INVALID,
+   [NFT_MSG_DELSET]= AUDIT_NFT_OP_SET_UNREGISTER,
+   [NFT_MSG_NEWSETELEM]= AUDIT_NFT_OP_SETELEM_REGISTER,
+   [NFT_MSG_GETSETELEM]= AUDIT_NFT_OP_INVALID,
+   [NFT_MSG_DELSETELEM]= AUDIT_NFT_OP_SETELEM_UNREGISTER,
+   [NFT_MSG_NEWGEN]= AUDIT_NFT_OP_GEN_REGISTER,
+   [NFT_MSG_GETGEN]= AUDIT_NFT_OP_INVALID,
+   [NFT_MSG_TRACE] = AUDIT_NFT_OP_INVALID,
+   [NFT_MSG_NEWOBJ]= AUDIT_NFT_OP_OBJ_REGISTER,
+   [NFT_MSG_GETOBJ]= AUDIT_NFT_OP_INVALID,
+   [NFT_MSG_DELOBJ]= AUDIT_NFT_OP_OBJ_UNREGISTER,
+   [NFT_MSG_GETOBJ_RESET]  = AUDIT_NFT_OP_OBJ_RESET,
+   [NFT_MSG_NEWFLOWTABLE]  = AUDIT_NFT_OP_FLOWTABLE_REGISTER,
+   [NFT_MSG_GETFLOWTABLE]  = AUDIT_NFT_OP_INVALID,
+   [NFT_MSG_DELFLOWTABLE]  = AUDIT_NFT_OP_FLOWTABLE_UNREGISTER,
+};
+
 extern int is_audit_feature_set(int which);
 
 extern int __init audit_register_class(int class, unsigned *list);
diff --git a/net/netfilter/nf_tables_api.c b/net/netfilter/nf_tables_api.c
index c1eb5cdb3033..42ba44890523 100644
--- a/net/netfilter/nf_tables_api.c
+++ b/net/netfilter/nf_tables_api.c
@@ -66,6 +66,13 @@ static const struct

Re: [PATCH] [v2] audit: avoid -Wempty-body warning

2021-03-22 Thread Richard Guy Briggs
On 2021-03-22 17:27, Arnd Bergmann wrote:
> From: Arnd Bergmann 
> 
> gcc warns about an empty statement when audit_remove_mark is defined to
> nothing:
> 
> kernel/auditfilter.c: In function 'audit_data_to_entry':
> kernel/auditfilter.c:609:51: error: suggest braces around empty body in an 
> 'if' statement [-Werror=empty-body]
>   609 | audit_remove_mark(entry->rule.exe); /* that's the 
> template one */
>   |   ^
> 
> Change the macros to use the usual "do { } while (0)" instead, and change a
> few more that were (void)0, for consistency.
> 
> Signed-off-by: Arnd Bergmann 

Acked-by: Richard Guy Briggs 

> ---
> v2: convert two more macros
> ---
>  kernel/audit.h | 12 ++--
>  1 file changed, 6 insertions(+), 6 deletions(-)
> 
> diff --git a/kernel/audit.h b/kernel/audit.h
> index 3b9c0945225a..1522e100fd17 100644
> --- a/kernel/audit.h
> +++ b/kernel/audit.h
> @@ -292,8 +292,8 @@ extern void audit_filter_inodes(struct task_struct *tsk,
>  extern struct list_head *audit_killed_trees(void);
>  #else /* CONFIG_AUDITSYSCALL */
>  #define auditsc_get_stamp(c, t, s) 0
> -#define audit_put_watch(w) {}
> -#define audit_get_watch(w) {}
> +#define audit_put_watch(w) do { } while (0)
> +#define audit_get_watch(w) do { } while (0)
>  #define audit_to_watch(k, p, l, o) (-EINVAL)
>  #define audit_add_watch(k, l) (-EINVAL)
>  #define audit_remove_watch_rule(k) BUG()
> @@ -302,8 +302,8 @@ extern struct list_head *audit_killed_trees(void);
>  
>  #define audit_alloc_mark(k, p, l) (ERR_PTR(-EINVAL))
>  #define audit_mark_path(m) ""
> -#define audit_remove_mark(m)
> -#define audit_remove_mark_rule(k)
> +#define audit_remove_mark(m) do { } while (0)
> +#define audit_remove_mark_rule(k) do { } while (0)
>  #define audit_mark_compare(m, i, d) 0
>  #define audit_exe_compare(t, m) (-EINVAL)
>  #define audit_dupe_exe(n, o) (-EINVAL)
> @@ -311,8 +311,8 @@ extern struct list_head *audit_killed_trees(void);
>  #define audit_remove_tree_rule(rule) BUG()
>  #define audit_add_tree_rule(rule) -EINVAL
>  #define audit_make_tree(rule, str, op) -EINVAL
> -#define audit_trim_trees() (void)0
> -#define audit_put_tree(tree) (void)0
> +#define audit_trim_trees() do { } while (0)
> +#define audit_put_tree(tree) do { } while (0)
>  #define audit_tag_tree(old, new) -EINVAL
>  #define audit_tree_path(rule) "" /* never called */
>  #define audit_kill_trees(context) BUG()
> -- 
> 2.29.2
> 

- RGB

--
Richard Guy Briggs 
Sr. S/W Engineer, Kernel Security, Base Operating Systems
Remote, Ottawa, Red Hat Canada
IRC: rgb, SunRaycer
Voice: +1.647.777.2635, Internal: (81) 32635



Re: [PATCH] audit: avoid -Wempty-body warning

2021-03-22 Thread Richard Guy Briggs
On 2021-03-22 17:28, Arnd Bergmann wrote:
> On Mon, Mar 22, 2021 at 3:33 PM Richard Guy Briggs  wrote:
> > > Change the macros to use the usual "do { } while (0)" instead, and change 
> > > a
> > > few more that were (void)0, for consistency.
> >
> > So what about audit_put_watch() and audit_get_watch() which are set to
> > {}?   (And all of include/linux/audit.h that uses the latter...)  Does
> > this only matter if they are the only action called in an if or loop?
> 
> I missed those, thanks for pointing it out. I sent a v2 patch now.

Ok, cool, that looks more consistent.  Can you answer my question about
include/linux/audit.h and exactly what conditions require
"do { } while (0)" over "{ }"?

>  Arnd

- RGB

--
Richard Guy Briggs 
Sr. S/W Engineer, Kernel Security, Base Operating Systems
Remote, Ottawa, Red Hat Canada
IRC: rgb, SunRaycer
Voice: +1.647.777.2635, Internal: (81) 32635



Re: [PATCH] audit: avoid -Wempty-body warning

2021-03-22 Thread Richard Guy Briggs
On 2021-03-22 12:45, Arnd Bergmann wrote:
> From: Arnd Bergmann 
> 
> gcc warns about an empty statement when audit_remove_mark is defined to
> nothing:
> 
> kernel/auditfilter.c: In function 'audit_data_to_entry':
> kernel/auditfilter.c:609:51: error: suggest braces around empty body in an 
> 'if' statement [-Werror=empty-body]
>   609 | audit_remove_mark(entry->rule.exe); /* that's the 
> template one */
>   |   ^
> 
> Change the macros to use the usual "do { } while (0)" instead, and change a
> few more that were (void)0, for consistency.

So what about audit_put_watch() and audit_get_watch() which are set to
{}?   (And all of include/linux/audit.h that uses the latter...)  Does
this only matter if they are the only action called in an if or loop?

> Signed-off-by: Arnd Bergmann 
> ---
>  kernel/audit.h | 8 
>  1 file changed, 4 insertions(+), 4 deletions(-)
> 
> diff --git a/kernel/audit.h b/kernel/audit.h
> index 3b9c0945225a..c39c5f3b8422 100644
> --- a/kernel/audit.h
> +++ b/kernel/audit.h
> @@ -302,8 +302,8 @@ extern struct list_head *audit_killed_trees(void);
>  
>  #define audit_alloc_mark(k, p, l) (ERR_PTR(-EINVAL))
>  #define audit_mark_path(m) ""
> -#define audit_remove_mark(m)
> -#define audit_remove_mark_rule(k)
> +#define audit_remove_mark(m) do { } while (0)
> +#define audit_remove_mark_rule(k) do { } while (0)
>  #define audit_mark_compare(m, i, d) 0
>  #define audit_exe_compare(t, m) (-EINVAL)
>  #define audit_dupe_exe(n, o) (-EINVAL)
> @@ -311,8 +311,8 @@ extern struct list_head *audit_killed_trees(void);
>  #define audit_remove_tree_rule(rule) BUG()
>  #define audit_add_tree_rule(rule) -EINVAL
>  #define audit_make_tree(rule, str, op) -EINVAL
> -#define audit_trim_trees() (void)0
> -#define audit_put_tree(tree) (void)0
> +#define audit_trim_trees() do { } while (0)
> +#define audit_put_tree(tree) do { } while (0)
>  #define audit_tag_tree(old, new) -EINVAL
>  #define audit_tree_path(rule) "" /* never called */
>  #define audit_kill_trees(context) BUG()
> -- 
> 2.29.2
> 

- RGB

--
Richard Guy Briggs 
Sr. S/W Engineer, Kernel Security, Base Operating Systems
Remote, Ottawa, Red Hat Canada
IRC: rgb, SunRaycer
Voice: +1.647.777.2635, Internal: (81) 32635



Re: [PATCH] audit: log nftables configuration change events once per table

2021-03-19 Thread Richard Guy Briggs
On 2021-03-19 13:52, Phil Sutter wrote:
> On Thu, Mar 18, 2021 at 02:37:03PM -0400, Richard Guy Briggs wrote:
> > On 2021-03-18 17:30, Phil Sutter wrote:
> [...]
> > > Why did you leave the object-related logs in place? They should reappear
> > > at commit time just like chains and sets for instance, no?
> > 
> > There are other paths that can trigger these messages that don't go
> > through nf_tables_commit() that affect the configuration data.  The
> > counters are considered config data for auditing purposes and the act of
> > resetting them is audittable.  And the only time we want to emit a
> > record is when they are being reset.
> 
> Oh, I see. I wasn't aware 'nft reset' bypasses the transaction logic,
> thanks for clarifying!

That's my current understanding.  If someone else has a better
understanding I'd be grateful if they could correct me.

> Cheers, Phil

- RGB

--
Richard Guy Briggs 
Sr. S/W Engineer, Kernel Security, Base Operating Systems
Remote, Ottawa, Red Hat Canada
IRC: rgb, SunRaycer
Voice: +1.647.777.2635, Internal: (81) 32635



[PATCH v3 1/2] audit: document /proc/PID/loginuid

2021-03-18 Thread Richard Guy Briggs
Describe the /proc/PID/loginuid interface in Documentation/ABI/stable that
was added 2005-02-01 by commit 1e2d1492e178 ("[PATCH] audit: handle
loginuid through proc")

Signed-off-by: Richard Guy Briggs 
---
 Documentation/ABI/stable/procfs-audit_loginuid | 15 +++
 1 file changed, 15 insertions(+)
 create mode 100644 Documentation/ABI/stable/procfs-audit_loginuid

diff --git a/Documentation/ABI/stable/procfs-audit_loginuid 
b/Documentation/ABI/stable/procfs-audit_loginuid
new file mode 100644
index ..e7c100b9ab18
--- /dev/null
+++ b/Documentation/ABI/stable/procfs-audit_loginuid
@@ -0,0 +1,15 @@
+What:  Audit Login UID
+Date:  2005-02-01
+KernelVersion: 2.6.11-rc2 1e2d1492e178 ("[PATCH] audit: handle loginuid 
through proc")
+Contact:   linux-au...@redhat.com
+Format:%u
+Users: audit and login applications
+Description:
+   The /proc/$pid/loginuid pseudofile is written to set and
+   read to get the audit login UID of process $pid.  If it is
+   unset, permissions are not needed to set it.  The accessor must
+   have CAP_AUDIT_CONTROL in the initial user namespace to write
+   it if it has been set.  It cannot be written again if
+   AUDIT_FEATURE_LOGINUID_IMMUTABLE is enabled.  It cannot be
+   unset if AUDIT_FEATURE_ONLY_UNSET_LOGINUID is enabled.
+
-- 
2.27.0



[PATCH v3 2/2] audit: document /proc/PID/sessionid

2021-03-18 Thread Richard Guy Briggs
Describe the /proc/PID/loginuid interface in Documentation/ABI/stable that
was added 2008-03-13 in commit 1e0bd7550ea9 ("[PATCH] export sessionid
alongside the loginuid in procfs")

Signed-off-by: Richard Guy Briggs 
---
 Documentation/ABI/stable/procfs-audit_loginuid | 12 
 1 file changed, 12 insertions(+)

diff --git a/Documentation/ABI/stable/procfs-audit_loginuid 
b/Documentation/ABI/stable/procfs-audit_loginuid
index e7c100b9ab18..9d55a3ff4b34 100644
--- a/Documentation/ABI/stable/procfs-audit_loginuid
+++ b/Documentation/ABI/stable/procfs-audit_loginuid
@@ -13,3 +13,15 @@ Description:
AUDIT_FEATURE_LOGINUID_IMMUTABLE is enabled.  It cannot be
unset if AUDIT_FEATURE_ONLY_UNSET_LOGINUID is enabled.
 
+
+What:  Audit Login Session ID
+Date:  2008-03-13
+KernelVersion: 2.6.25-rc7 1e0bd7550ea9 ("[PATCH] export sessionid alongside 
the loginuid in procfs")
+Contact:   linux-au...@redhat.com
+Format:%u
+Users: audit and login applications
+Description:
+   The /proc/$pid/sessionid pseudofile is read to get the
+   audit login session ID of process $pid.  It is set
+   automatically, serially assigned with each new login.
+
-- 
2.27.0



[PATCH v3 0/2] audit: add documentation for /proc/PID/stable interfaces

2021-03-18 Thread Richard Guy Briggs
Add Documentation/ABI entries for audit interfaces in /proc/PID/ that have
been stable for more than a decade.

Richard Guy Briggs (2):
  audit: document /proc/PID/loginuid
  audit: document /proc/PID/sessionid

 .../ABI/stable/procfs-audit_loginuid  | 27 +++
 1 file changed, 27 insertions(+)
 create mode 100644 Documentation/ABI/stable/procfs-audit_loginuid

-- 
2.27.0



Re: [PATCH] audit: log nftables configuration change events once per table

2021-03-18 Thread Richard Guy Briggs
On 2021-03-18 17:30, Phil Sutter wrote:
> Hi,
> 
> On Thu, Mar 18, 2021 at 11:39:52AM -0400, Richard Guy Briggs wrote:
> > Reduce logging of nftables events to a level similar to iptables.
> > Restore the table field to list the table, adding the generation.
> 
> This looks much better, a few remarks below:
> 
> [...]
> > +static const u8 nft2audit_op[] = { // enum nf_tables_msg_types
> > +   /* NFT_MSG_NEWTABLE */  AUDIT_NFT_OP_TABLE_REGISTER,
> > +   /* NFT_MSG_GETTABLE */  AUDIT_NFT_OP_INVALID,
> > +   /* NFT_MSG_DELTABLE */  AUDIT_NFT_OP_TABLE_UNREGISTER,
> > +   /* NFT_MSG_NEWCHAIN */  AUDIT_NFT_OP_CHAIN_REGISTER,
> > +   /* NFT_MSG_GETCHAIN */  AUDIT_NFT_OP_INVALID,
> > +   /* NFT_MSG_DELCHAIN */  AUDIT_NFT_OP_CHAIN_UNREGISTER,
> > +   /* NFT_MSG_NEWRULE  */  AUDIT_NFT_OP_RULE_REGISTER,
> > +   /* NFT_MSG_GETRULE  */  AUDIT_NFT_OP_INVALID,
> > +   /* NFT_MSG_DELRULE  */  AUDIT_NFT_OP_RULE_UNREGISTER,
> > +   /* NFT_MSG_NEWSET   */  AUDIT_NFT_OP_SET_REGISTER,
> > +   /* NFT_MSG_GETSET   */  AUDIT_NFT_OP_INVALID,
> > +   /* NFT_MSG_DELSET   */  AUDIT_NFT_OP_SET_UNREGISTER,
> > +   /* NFT_MSG_NEWSETELEM   */  AUDIT_NFT_OP_SETELEM_REGISTER,
> > +   /* NFT_MSG_GETSETELEM   */  AUDIT_NFT_OP_INVALID,
> > +   /* NFT_MSG_DELSETELEM   */  AUDIT_NFT_OP_SETELEM_UNREGISTER,
> > +   /* NFT_MSG_NEWGEN   */  AUDIT_NFT_OP_GEN_REGISTER,
> > +   /* NFT_MSG_GETGEN   */  AUDIT_NFT_OP_INVALID,
> > +   /* NFT_MSG_TRACE*/  AUDIT_NFT_OP_INVALID,
> > +   /* NFT_MSG_NEWOBJ   */  AUDIT_NFT_OP_OBJ_REGISTER,
> > +   /* NFT_MSG_GETOBJ   */  AUDIT_NFT_OP_INVALID,
> > +   /* NFT_MSG_DELOBJ   */  AUDIT_NFT_OP_OBJ_UNREGISTER,
> > +   /* NFT_MSG_GETOBJ_RESET */  AUDIT_NFT_OP_OBJ_RESET,
> > +   /* NFT_MSG_NEWFLOWTABLE */  AUDIT_NFT_OP_FLOWTABLE_REGISTER,
> > +   /* NFT_MSG_GETFLOWTABLE */  AUDIT_NFT_OP_INVALID,
> > +   /* NFT_MSG_DELFLOWTABLE */  AUDIT_NFT_OP_FLOWTABLE_UNREGISTER,
> > +   /* NFT_MSG_MAX  */  AUDIT_NFT_OP_INVALID,
> > +};
> 
> NFT_MSG_MAX is itself not a valid message, it serves merely as an upper
> bound for arrays, loops or sanity checks. You will never see it in
> trans->msg_type.
> 
> Since enum nf_tables_msg_types contains consecutive values from 0 to
> NFT_MSG_MAX, you could write the above more explicitly:
> 
> | static const u8 nft2audit_op[NFT_MSG_MAX] = {
> | [NFT_MSG_NEWTABLE]  = AUDIT_NFT_OP_TABLE_REGISTER,
> | [NFT_MSG_GETTABLE]  = AUDIT_NFT_OP_INVALID,
> | [NFT_MSG_DELTABLE]  = AUDIT_NFT_OP_TABLE_UNREGISTER,
> (And so forth.)
> 
> Not a must, but it clarifies the 1:1 mapping between index and said
> enum. Sadly, AUDIT_NFT_OP_INVALID is non-zero. Otherwise one could skip
> all uninteresting ones.

Yes, ok, I prefer your suggested way of listing them.

Yeah, the fact the values for op= already have a precedent in xtables
limits us.

> [...]
> > @@ -6278,12 +6219,11 @@ static int nf_tables_dump_obj(struct sk_buff *skb, 
> > struct netlink_callback *cb)
> > filter->type != NFT_OBJECT_UNSPEC &&
> > obj->ops->type->type != filter->type)
> > goto cont;
> > -
> > if (reset) {
> > char *buf = kasprintf(GFP_ATOMIC,
> > - "%s:%llu;?:0",
> > + "%s:%u",
> >   table->name,
> > - table->handle);
> > + net->nft.base_seq);
> >  
> > audit_log_nfcfg(buf,
> > family,
> 
> Why did you leave the object-related logs in place? They should reappear
> at commit time just like chains and sets for instance, no?

There are other paths that can trigger these messages that don't go
through nf_tables_commit() that affect the configuration data.  The
counters are considered config data for auditing purposes and the act of
resetting them is audittable.  And the only time we want to emit a
record is when they are being reset.

> Thanks, Phil

- RGB

--
Richard Guy Briggs 
Sr. S/W Engineer, Kernel Security, Base Operating Systems
Remote, Ottawa, Red Hat Canada
IRC: rgb, SunRaycer
Voice: +1.647.777.2635, Internal: (81) 32635



[PATCH] audit: log nftables configuration change events once per table

2021-03-18 Thread Richard Guy Briggs
Reduce logging of nftables events to a level similar to iptables.
Restore the table field to list the table, adding the generation.

Indicate the op as the most significant operation in the event.

A couple of sample events:

type=PROCTITLE msg=audit(2021-03-18 09:30:49.801:143) : 
proctitle=/usr/bin/python3 -s /usr/sbin/firewalld --nofork --nopid
type=SYSCALL msg=audit(2021-03-18 09:30:49.801:143) : arch=x86_64 
syscall=sendmsg success=yes exit=172 a0=0x6 a1=0x7ffdcfcbe650 a2=0x0 
a3=0x7ffdcfcbd52c items=0 ppid=1 pid=367 auid=unset uid=root gid=root euid=root 
suid=root fsuid=root egid=roo
t sgid=root fsgid=root tty=(none) ses=unset comm=firewalld 
exe=/usr/bin/python3.9 subj=system_u:system_r:firewalld_t:s0 key=(null)
type=NETFILTER_CFG msg=audit(2021-03-18 09:30:49.801:143) : table=firewalld:2 
family=ipv6 entries=1 op=nft_register_table pid=367 
subj=system_u:system_r:firewalld_t:s0 comm=firewalld
type=NETFILTER_CFG msg=audit(2021-03-18 09:30:49.801:143) : table=firewalld:2 
family=ipv4 entries=1 op=nft_register_table pid=367 
subj=system_u:system_r:firewalld_t:s0 comm=firewalld
type=NETFILTER_CFG msg=audit(2021-03-18 09:30:49.801:143) : table=firewalld:2 
family=inet entries=1 op=nft_register_table pid=367 
subj=system_u:system_r:firewalld_t:s0 comm=firewalld

type=PROCTITLE msg=audit(2021-03-18 09:30:49.839:144) : 
proctitle=/usr/bin/python3 -s /usr/sbin/firewalld --nofork --nopid
type=SYSCALL msg=audit(2021-03-18 09:30:49.839:144) : arch=x86_64 
syscall=sendmsg success=yes exit=22792 a0=0x6 a1=0x7ffdcfcbe650 a2=0x0 
a3=0x7ffdcfcbd52c items=0 ppid=1 pid=367 auid=unset uid=root gid=root euid=root 
suid=root fsuid=root egid=r
oot sgid=root fsgid=root tty=(none) ses=unset comm=firewalld 
exe=/usr/bin/python3.9 subj=system_u:system_r:firewalld_t:s0 key=(null)
type=NETFILTER_CFG msg=audit(2021-03-18 09:30:49.839:144) : table=firewalld:3 
family=ipv6 entries=30 op=nft_register_chain pid=367 
subj=system_u:system_r:firewalld_t:s0 comm=firewalld
type=NETFILTER_CFG msg=audit(2021-03-18 09:30:49.839:144) : table=firewalld:3 
family=ipv4 entries=30 op=nft_register_chain pid=367 
subj=system_u:system_r:firewalld_t:s0 comm=firewalld
type=NETFILTER_CFG msg=audit(2021-03-18 09:30:49.839:144) : table=firewalld:3 
family=inet entries=165 op=nft_register_chain pid=367 
subj=system_u:system_r:firewalld_t:s0 comm=firewalld

The issue was originally documented in
https://github.com/linux-audit/audit-kernel/issues/124

Signed-off-by: Richard Guy Briggs 
---
 include/linux/audit.h |  29 
 net/netfilter/nf_tables_api.c | 132 +-
 2 files changed, 78 insertions(+), 83 deletions(-)

diff --git a/include/linux/audit.h b/include/linux/audit.h
index 82b7c1116a85..bba6a0386742 100644
--- a/include/linux/audit.h
+++ b/include/linux/audit.h
@@ -118,6 +118,35 @@ enum audit_nfcfgop {
AUDIT_NFT_OP_INVALID,
 };
 
+static const u8 nft2audit_op[] = { // enum nf_tables_msg_types
+   /* NFT_MSG_NEWTABLE */  AUDIT_NFT_OP_TABLE_REGISTER,
+   /* NFT_MSG_GETTABLE */  AUDIT_NFT_OP_INVALID,
+   /* NFT_MSG_DELTABLE */  AUDIT_NFT_OP_TABLE_UNREGISTER,
+   /* NFT_MSG_NEWCHAIN */  AUDIT_NFT_OP_CHAIN_REGISTER,
+   /* NFT_MSG_GETCHAIN */  AUDIT_NFT_OP_INVALID,
+   /* NFT_MSG_DELCHAIN */  AUDIT_NFT_OP_CHAIN_UNREGISTER,
+   /* NFT_MSG_NEWRULE  */  AUDIT_NFT_OP_RULE_REGISTER,
+   /* NFT_MSG_GETRULE  */  AUDIT_NFT_OP_INVALID,
+   /* NFT_MSG_DELRULE  */  AUDIT_NFT_OP_RULE_UNREGISTER,
+   /* NFT_MSG_NEWSET   */  AUDIT_NFT_OP_SET_REGISTER,
+   /* NFT_MSG_GETSET   */  AUDIT_NFT_OP_INVALID,
+   /* NFT_MSG_DELSET   */  AUDIT_NFT_OP_SET_UNREGISTER,
+   /* NFT_MSG_NEWSETELEM   */  AUDIT_NFT_OP_SETELEM_REGISTER,
+   /* NFT_MSG_GETSETELEM   */  AUDIT_NFT_OP_INVALID,
+   /* NFT_MSG_DELSETELEM   */  AUDIT_NFT_OP_SETELEM_UNREGISTER,
+   /* NFT_MSG_NEWGEN   */  AUDIT_NFT_OP_GEN_REGISTER,
+   /* NFT_MSG_GETGEN   */  AUDIT_NFT_OP_INVALID,
+   /* NFT_MSG_TRACE*/  AUDIT_NFT_OP_INVALID,
+   /* NFT_MSG_NEWOBJ   */  AUDIT_NFT_OP_OBJ_REGISTER,
+   /* NFT_MSG_GETOBJ   */  AUDIT_NFT_OP_INVALID,
+   /* NFT_MSG_DELOBJ   */  AUDIT_NFT_OP_OBJ_UNREGISTER,
+   /* NFT_MSG_GETOBJ_RESET */  AUDIT_NFT_OP_OBJ_RESET,
+   /* NFT_MSG_NEWFLOWTABLE */  AUDIT_NFT_OP_FLOWTABLE_REGISTER,
+   /* NFT_MSG_GETFLOWTABLE */  AUDIT_NFT_OP_INVALID,
+   /* NFT_MSG_DELFLOWTABLE */  AUDIT_NFT_OP_FLOWTABLE_UNREGISTER,
+   /* NFT_MSG_MAX  */  AUDIT_NFT_OP_INVALID,
+};
+
 extern int is_audit_feature_set(int which);
 
 extern int __init audit_register_class(int class, unsigned *list);
diff --git a/net/netfilter/nf_tables_api.c b/net/netfilter/nf_tables_api.c
index 8d5aa0ac45f4..ad31d8876169 100644
--- a/net/netfilter/nf_tables_api.c
+++ b/net/netfilter/nf_tables_api.c

Re: [PATCH 1/2] audit: add support for the openat2 syscall

2021-03-18 Thread Richard Guy Briggs
On 2021-03-18 11:48, Christian Brauner wrote:
> [+Cc Aleksa, the author of openat2()]

Ah!  Thanks for pulling in Aleksa.  I thought I caught everyone...

> and a comment below. :)

Same...

> On Wed, Mar 17, 2021 at 09:47:17PM -0400, Richard Guy Briggs wrote:
> > The openat2(2) syscall was added in kernel v5.6 with commit fddb5d430ad9
> > ("open: introduce openat2(2) syscall")
> > 
> > Add the openat2(2) syscall to the audit syscall classifier.
> > 
> > See the github issue
> > https://github.com/linux-audit/audit-kernel/issues/67
> > 
> > Signed-off-by: Richard Guy Briggs 
> > ---
> >  arch/alpha/kernel/audit.c  | 2 ++
> >  arch/ia64/kernel/audit.c   | 2 ++
> >  arch/parisc/kernel/audit.c | 2 ++
> >  arch/parisc/kernel/compat_audit.c  | 2 ++
> >  arch/powerpc/kernel/audit.c| 2 ++
> >  arch/powerpc/kernel/compat_audit.c | 2 ++
> >  arch/s390/kernel/audit.c   | 2 ++
> >  arch/s390/kernel/compat_audit.c| 2 ++
> >  arch/sparc/kernel/audit.c  | 2 ++
> >  arch/sparc/kernel/compat_audit.c   | 2 ++
> >  arch/x86/ia32/audit.c  | 2 ++
> >  arch/x86/kernel/audit_64.c | 2 ++
> >  kernel/auditsc.c   | 3 +++
> >  lib/audit.c| 4 
> >  lib/compat_audit.c | 4 
> >  15 files changed, 35 insertions(+)
> > 
> > diff --git a/arch/alpha/kernel/audit.c b/arch/alpha/kernel/audit.c
> > index 96a9d18ff4c4..06a911b685d1 100644
> > --- a/arch/alpha/kernel/audit.c
> > +++ b/arch/alpha/kernel/audit.c
> > @@ -42,6 +42,8 @@ int audit_classify_syscall(int abi, unsigned syscall)
> > return 3;
> > case __NR_execve:
> > return 5;
> > +   case __NR_openat2:
> > +   return 6;
> > default:
> > return 0;
> > }
> > diff --git a/arch/ia64/kernel/audit.c b/arch/ia64/kernel/audit.c
> > index 5192ca899fe6..5eaa888c8fd3 100644
> > --- a/arch/ia64/kernel/audit.c
> > +++ b/arch/ia64/kernel/audit.c
> > @@ -43,6 +43,8 @@ int audit_classify_syscall(int abi, unsigned syscall)
> > return 3;
> > case __NR_execve:
> > return 5;
> > +   case __NR_openat2:
> > +   return 6;
> > default:
> > return 0;
> > }
> > diff --git a/arch/parisc/kernel/audit.c b/arch/parisc/kernel/audit.c
> > index 9eb47b2225d2..fc721a7727ba 100644
> > --- a/arch/parisc/kernel/audit.c
> > +++ b/arch/parisc/kernel/audit.c
> > @@ -52,6 +52,8 @@ int audit_classify_syscall(int abi, unsigned syscall)
> > return 3;
> > case __NR_execve:
> > return 5;
> > +   case __NR_openat2:
> > +   return 6;
> > default:
> > return 0;
> > }
> > diff --git a/arch/parisc/kernel/compat_audit.c 
> > b/arch/parisc/kernel/compat_audit.c
> > index 20c39c9d86a9..fc6d35918c44 100644
> > --- a/arch/parisc/kernel/compat_audit.c
> > +++ b/arch/parisc/kernel/compat_audit.c
> > @@ -35,6 +35,8 @@ int parisc32_classify_syscall(unsigned syscall)
> > return 3;
> > case __NR_execve:
> > return 5;
> > +   case __NR_openat2:
> > +   return 6;
> > default:
> > return 1;
> > }
> > diff --git a/arch/powerpc/kernel/audit.c b/arch/powerpc/kernel/audit.c
> > index a27f3d09..8f32700b0baa 100644
> > --- a/arch/powerpc/kernel/audit.c
> > +++ b/arch/powerpc/kernel/audit.c
> > @@ -54,6 +54,8 @@ int audit_classify_syscall(int abi, unsigned syscall)
> > return 4;
> > case __NR_execve:
> > return 5;
> > +   case __NR_openat2:
> > +   return 6;
> > default:
> > return 0;
> > }
> > diff --git a/arch/powerpc/kernel/compat_audit.c 
> > b/arch/powerpc/kernel/compat_audit.c
> > index 55c6ccda0a85..ebe45534b1c9 100644
> > --- a/arch/powerpc/kernel/compat_audit.c
> > +++ b/arch/powerpc/kernel/compat_audit.c
> > @@ -38,6 +38,8 @@ int ppc32_classify_syscall(unsigned syscall)
> > return 4;
> > case __NR_execve:
> > return 5;
> > +   case __NR_openat2:
> > +   return 6;
> > default:
> > return 1;
> > }
> > diff --git a/arch/s390/kernel/audit.c b/arch/s390/kernel/audit.c
> > index d395c6c9944c..d964cb94cfaf 100644
> > --- a/arch/s390/kernel/audit.c
> > +++ b/arch/s390/kernel/audit.c
> > @@ -54,6 +54,8 @@ i

Re: [PATCH 1/2] audit: add support for the openat2 syscall

2021-03-18 Thread Richard Guy Briggs
On 2021-03-18 11:52, Christian Brauner wrote:
> On Thu, Mar 18, 2021 at 11:48:45AM +0100, Christian Brauner wrote:
> > On Wed, Mar 17, 2021 at 09:47:17PM -0400, Richard Guy Briggs wrote:
> > > The openat2(2) syscall was added in kernel v5.6 with commit fddb5d430ad9
> > > ("open: introduce openat2(2) syscall")
> > > Add the openat2(2) syscall to the audit syscall classifier.
> > > See the github issue
> > > https://github.com/linux-audit/audit-kernel/issues/67
> > > Signed-off-by: Richard Guy Briggs 

...

> And one more comment, why return a hard-coded integer from all of these
> architectures instead of introducing an enum in a central place with
> proper names idk:

Oh, believe me, I tried hard to do that because I really don't like
hard-coded magic values, but for expediency I continued the same
approach until I could sort out the header file mess.  There was an
extra preparatory patch (attached) in this patchset with a different
audit syscall perms patch (also attached).  By including "#include
" in each of the compat source files there were warnings
of redefinitions of every __NR_* syscall number.  The easiest way to get
rid of it would have been to pull the new AUDITSC_* definitions into a
new  file and include that from  and
each of the arch/*/*/*audit.c (and lib/*audit.c) files.

> enum audit_match_perm_t {
>   .
>   .
>   .
>   AUDIT_MATCH_PERM_EXECVE = 5,
>   AUDIT_MATCH_PERM_OPENAT2 = 6,
>   .
>   .
>   .
> }
> 
> Then you can drop these hard-coded comments too and it's way less
> brittle overall.

Totally agree.

> Christian

- RGB

--
Richard Guy Briggs 
Sr. S/W Engineer, Kernel Security, Base Operating Systems
Remote, Ottawa, Red Hat Canada
IRC: rgb, SunRaycer
Voice: +1.647.777.2635, Internal: (81) 32635
>From 599ae48091296a3ad3eb4259e7af39cdf0f743c7 Mon Sep 17 00:00:00 2001
Message-Id: 
<599ae48091296a3ad3eb4259e7af39cdf0f743c7.1616067847.git@redhat.com>
In-Reply-To: 
References: 
From: Richard Guy Briggs 
Date: Fri, 22 Jan 2021 16:27:42 -0500
Subject: [PATCH 1/3] audit: replace magic audit syscall class numbers with
 macros

Replace the magic numbers used to indicate audit syscall classes with macros.

Signed-off-by: Richard Guy Briggs 
---
 arch/alpha/kernel/audit.c  |  8 
 arch/ia64/kernel/audit.c   |  8 
 arch/parisc/kernel/audit.c |  8 
 arch/parisc/kernel/compat_audit.c  |  9 +
 arch/powerpc/kernel/audit.c| 10 +-
 arch/powerpc/kernel/compat_audit.c | 11 ++-
 arch/s390/kernel/audit.c   | 10 +-
 arch/s390/kernel/compat_audit.c| 11 ++-
 arch/sparc/kernel/audit.c  | 10 +-
 arch/sparc/kernel/compat_audit.c   | 11 ++-
 arch/x86/ia32/audit.c  | 11 ++-
 arch/x86/kernel/audit_64.c |  8 
 include/linux/audit.h  |  7 +++
 kernel/auditsc.c   | 12 ++--
 lib/audit.c| 10 +-
 lib/compat_audit.c | 11 ++-
 16 files changed, 84 insertions(+), 71 deletions(-)

diff --git a/arch/alpha/kernel/audit.c b/arch/alpha/kernel/audit.c
index 96a9d18ff4c4..81cbd804e375 100644
--- a/arch/alpha/kernel/audit.c
+++ b/arch/alpha/kernel/audit.c
@@ -37,13 +37,13 @@ int audit_classify_syscall(int abi, unsigned syscall)
 {
switch(syscall) {
case __NR_open:
-   return 2;
+   return AUDITSC_OPEN;
case __NR_openat:
-   return 3;
+   return AUDITSC_OPENAT;
case __NR_execve:
-   return 5;
+   return AUDITSC_EXECVE;
default:
-   return 0;
+   return AUDITSC_NATIVE;
}
 }
 
diff --git a/arch/ia64/kernel/audit.c b/arch/ia64/kernel/audit.c
index 5192ca899fe6..dba6a74c9ab3 100644
--- a/arch/ia64/kernel/audit.c
+++ b/arch/ia64/kernel/audit.c
@@ -38,13 +38,13 @@ int audit_classify_syscall(int abi, unsigned syscall)
 {
switch(syscall) {
case __NR_open:
-   return 2;
+   return AUDITSC_OPEN;
case __NR_openat:
-   return 3;
+   return AUDITSC_OPENAT;
case __NR_execve:
-   return 5;
+   return AUDITSC_EXECVE;
default:
-   return 0;
+   return AUDITSC_NATIVE;
}
 }
 
diff --git a/arch/parisc/kernel/audit.c b/arch/parisc/kernel/audit.c
index 9eb47b2225d2..14244e83db75 100644
--- a/arch/parisc/kernel/audit.c
+++ b/arch/parisc/kernel/audit.c
@@ -47,13 +47,13 @@ int audit_classify_syscall(int abi, unsigned syscall)
 #endif
switch (syscall) {
case __NR_open:
-   return 2;
+   return AUDITSC_OPEN;
case __NR_openat:
-   return 3;
+   return AUDIT

[PATCH v2 2/2] audit: document /proc/PID/sessionid

2021-03-17 Thread Richard Guy Briggs
Describe the /proc/PID/loginuid interface in Documentation/ABI/stable that
was added 2008-03-13 in commit 1e0bd7550ea9 ("[PATCH] export sessionid
alongside the loginuid in procfs")

Signed-off-by: Richard Guy Briggs 
---
 Documentation/ABI/stable/procfs-audit_loginuid | 12 
 1 file changed, 12 insertions(+)

diff --git a/Documentation/ABI/stable/procfs-audit_loginuid 
b/Documentation/ABI/stable/procfs-audit_loginuid
index 013bc1d74854..5d09637a4ae2 100644
--- a/Documentation/ABI/stable/procfs-audit_loginuid
+++ b/Documentation/ABI/stable/procfs-audit_loginuid
@@ -13,3 +13,15 @@ Description:
AUDIT_FEATURE_LOGINUID_IMMUTABLE is enabled.  It cannot be
unset if AUDIT_FEATURE_ONLY_UNSET_LOGINUID is enabled.
 
+
+What:  Audit Login Session ID
+Date:  2008-03-13
+KernelVersion: 2.6.25-rc7 1e0bd7550ea9 ("[PATCH] export sessionid alongside 
the loginuid in procfs")
+Contact:   linux-au...@redhat.com
+Format:%u (u32)
+Users: auditd, libaudit, audit-testsuite, login
+Description:
+   The /proc/$pid/sessionid pseudofile is read to get the
+   audit login session ID of process $pid.  It is set
+   automatically, serially assigned with each new login.
+
-- 
2.27.0



[PATCH v2 0/2] audit: add documentation for /proc/PID/stable interfaces

2021-03-17 Thread Richard Guy Briggs
Add Documentation/ABI entries for audit interfaces in /proc/PID/ that have
been stable for more than a decade.

Richard Guy Briggs (2):
  audit: document /proc/PID/loginuid
  audit: document /proc/PID/sessionid

 .../ABI/stable/procfs-audit_loginuid  | 27 +++
 1 file changed, 27 insertions(+)
 create mode 100644 Documentation/ABI/stable/procfs-audit_loginuid

-- 
2.27.0



[PATCH v2 1/2] audit: document /proc/PID/loginuid

2021-03-17 Thread Richard Guy Briggs
Describe the /proc/PID/loginuid interface in Documentation/ABI/stable that
was added 2005-02-01 by commit 1e2d1492e178 ("[PATCH] audit: handle
loginuid through proc")

Signed-off-by: Richard Guy Briggs 
---
 Documentation/ABI/stable/procfs-audit_loginuid | 15 +++
 1 file changed, 15 insertions(+)
 create mode 100644 Documentation/ABI/stable/procfs-audit_loginuid

diff --git a/Documentation/ABI/stable/procfs-audit_loginuid 
b/Documentation/ABI/stable/procfs-audit_loginuid
new file mode 100644
index ..013bc1d74854
--- /dev/null
+++ b/Documentation/ABI/stable/procfs-audit_loginuid
@@ -0,0 +1,15 @@
+What:  Audit Login UID
+Date:  2005-02-01
+KernelVersion: 2.6.11-rc2 1e2d1492e178 ("[PATCH] audit: handle loginuid 
through proc")
+Contact:   linux-au...@redhat.com
+Format:%u (u32)
+Users: auditd, libaudit, audit-testsuite, login
+Description:
+   The /proc/$pid/loginuid pseudofile is written to set and
+   read to get the audit login UID of process $pid.  If it is
+   unset, permissions are not needed to set it.  The accessor must
+   have CAP_AUDIT_CONTROL in the initial user namespace to write
+   it if it has been set.  It cannot be written again if
+   AUDIT_FEATURE_LOGINUID_IMMUTABLE is enabled.  It cannot be
+   unset if AUDIT_FEATURE_ONLY_UNSET_LOGINUID is enabled.
+
-- 
2.27.0



[PATCH v2] MAINTAINERS: update audit files

2021-03-17 Thread Richard Guy Briggs
Add files maintaned by the audit subsystem.

Files from arch/*/*/*audit*.[ch] and arch/x86/include/asm/audit.h were not
added due to concern of the list not holding up over time.  There exist
already exceptions that caused the need for this specificity.

Signed-off-by: Richard Guy Briggs 
---
 MAINTAINERS | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/MAINTAINERS b/MAINTAINERS
index d92f85ca831d..1249655459d3 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -2979,9 +2979,11 @@ L:   linux-au...@redhat.com (moderated for 
non-subscribers)
 S: Supported
 W: https://github.com/linux-audit
 T: git git://git.kernel.org/pub/scm/linux/kernel/git/pcmoore/audit.git
+F: include/asm-generic/audit_*.h
 F: include/linux/audit.h
 F: include/uapi/linux/audit.h
 F: kernel/audit*
+F: lib/*audit.c
 
 AUXILIARY DISPLAY DRIVERS
 M: Miguel Ojeda 
-- 
2.27.0



[PATCH 1/2] audit: add support for the openat2 syscall

2021-03-17 Thread Richard Guy Briggs
The openat2(2) syscall was added in kernel v5.6 with commit fddb5d430ad9
("open: introduce openat2(2) syscall")

Add the openat2(2) syscall to the audit syscall classifier.

See the github issue
https://github.com/linux-audit/audit-kernel/issues/67

Signed-off-by: Richard Guy Briggs 
---
 arch/alpha/kernel/audit.c  | 2 ++
 arch/ia64/kernel/audit.c   | 2 ++
 arch/parisc/kernel/audit.c | 2 ++
 arch/parisc/kernel/compat_audit.c  | 2 ++
 arch/powerpc/kernel/audit.c| 2 ++
 arch/powerpc/kernel/compat_audit.c | 2 ++
 arch/s390/kernel/audit.c   | 2 ++
 arch/s390/kernel/compat_audit.c| 2 ++
 arch/sparc/kernel/audit.c  | 2 ++
 arch/sparc/kernel/compat_audit.c   | 2 ++
 arch/x86/ia32/audit.c  | 2 ++
 arch/x86/kernel/audit_64.c | 2 ++
 kernel/auditsc.c   | 3 +++
 lib/audit.c| 4 
 lib/compat_audit.c | 4 
 15 files changed, 35 insertions(+)

diff --git a/arch/alpha/kernel/audit.c b/arch/alpha/kernel/audit.c
index 96a9d18ff4c4..06a911b685d1 100644
--- a/arch/alpha/kernel/audit.c
+++ b/arch/alpha/kernel/audit.c
@@ -42,6 +42,8 @@ int audit_classify_syscall(int abi, unsigned syscall)
return 3;
case __NR_execve:
return 5;
+   case __NR_openat2:
+   return 6;
default:
return 0;
}
diff --git a/arch/ia64/kernel/audit.c b/arch/ia64/kernel/audit.c
index 5192ca899fe6..5eaa888c8fd3 100644
--- a/arch/ia64/kernel/audit.c
+++ b/arch/ia64/kernel/audit.c
@@ -43,6 +43,8 @@ int audit_classify_syscall(int abi, unsigned syscall)
return 3;
case __NR_execve:
return 5;
+   case __NR_openat2:
+   return 6;
default:
return 0;
}
diff --git a/arch/parisc/kernel/audit.c b/arch/parisc/kernel/audit.c
index 9eb47b2225d2..fc721a7727ba 100644
--- a/arch/parisc/kernel/audit.c
+++ b/arch/parisc/kernel/audit.c
@@ -52,6 +52,8 @@ int audit_classify_syscall(int abi, unsigned syscall)
return 3;
case __NR_execve:
return 5;
+   case __NR_openat2:
+   return 6;
default:
return 0;
}
diff --git a/arch/parisc/kernel/compat_audit.c 
b/arch/parisc/kernel/compat_audit.c
index 20c39c9d86a9..fc6d35918c44 100644
--- a/arch/parisc/kernel/compat_audit.c
+++ b/arch/parisc/kernel/compat_audit.c
@@ -35,6 +35,8 @@ int parisc32_classify_syscall(unsigned syscall)
return 3;
case __NR_execve:
return 5;
+   case __NR_openat2:
+   return 6;
default:
return 1;
}
diff --git a/arch/powerpc/kernel/audit.c b/arch/powerpc/kernel/audit.c
index a27f3d09..8f32700b0baa 100644
--- a/arch/powerpc/kernel/audit.c
+++ b/arch/powerpc/kernel/audit.c
@@ -54,6 +54,8 @@ int audit_classify_syscall(int abi, unsigned syscall)
return 4;
case __NR_execve:
return 5;
+   case __NR_openat2:
+   return 6;
default:
return 0;
}
diff --git a/arch/powerpc/kernel/compat_audit.c 
b/arch/powerpc/kernel/compat_audit.c
index 55c6ccda0a85..ebe45534b1c9 100644
--- a/arch/powerpc/kernel/compat_audit.c
+++ b/arch/powerpc/kernel/compat_audit.c
@@ -38,6 +38,8 @@ int ppc32_classify_syscall(unsigned syscall)
return 4;
case __NR_execve:
return 5;
+   case __NR_openat2:
+   return 6;
default:
return 1;
}
diff --git a/arch/s390/kernel/audit.c b/arch/s390/kernel/audit.c
index d395c6c9944c..d964cb94cfaf 100644
--- a/arch/s390/kernel/audit.c
+++ b/arch/s390/kernel/audit.c
@@ -54,6 +54,8 @@ int audit_classify_syscall(int abi, unsigned syscall)
return 4;
case __NR_execve:
return 5;
+   case __NR_openat2:
+   return 6;
default:
return 0;
}
diff --git a/arch/s390/kernel/compat_audit.c b/arch/s390/kernel/compat_audit.c
index 444fb1f66944..f7b32933ce0e 100644
--- a/arch/s390/kernel/compat_audit.c
+++ b/arch/s390/kernel/compat_audit.c
@@ -39,6 +39,8 @@ int s390_classify_syscall(unsigned syscall)
return 4;
case __NR_execve:
return 5;
+   case __NR_openat2:
+   return 6;
default:
return 1;
}
diff --git a/arch/sparc/kernel/audit.c b/arch/sparc/kernel/audit.c
index a6e91bf34d48..b6dcca9c6520 100644
--- a/arch/sparc/kernel/audit.c
+++ b/arch/sparc/kernel/audit.c
@@ -55,6 +55,8 @@ int audit_classify_syscall(int abi, unsigned int syscall)
return 4;
case __NR_execve:
return 5;
+   case __NR_openat2:
+   return 6;
default:
return 0;
}
diff --git a/arch/sparc/kernel/compat_audit.c b/arch/sparc/kernel/compat_audit.c
index 10

[PATCH 0/2] audit: add support for openat2

2021-03-17 Thread Richard Guy Briggs
The openat2(2) syscall was added in v5.6.  Add support for openat2 to the
audit syscall classifier and for recording openat2 parameters that cannot
be captured in the syscall parameters of the SYSCALL record.

Supporting userspace code can be found in
https://github.com/rgbriggs/audit-userspace/tree/ghau-openat2

Supporting test case can be found in
https://github.com/linux-audit/audit-testsuite/pull/103

Richard Guy Briggs (2):
  audit: add support for the openat2 syscall
  audit: add OPENAT2 record to list how

 arch/alpha/kernel/audit.c  |  2 ++
 arch/ia64/kernel/audit.c   |  2 ++
 arch/parisc/kernel/audit.c |  2 ++
 arch/parisc/kernel/compat_audit.c  |  2 ++
 arch/powerpc/kernel/audit.c|  2 ++
 arch/powerpc/kernel/compat_audit.c |  2 ++
 arch/s390/kernel/audit.c   |  2 ++
 arch/s390/kernel/compat_audit.c|  2 ++
 arch/sparc/kernel/audit.c  |  2 ++
 arch/sparc/kernel/compat_audit.c   |  2 ++
 arch/x86/ia32/audit.c  |  2 ++
 arch/x86/kernel/audit_64.c |  2 ++
 fs/open.c  |  2 ++
 include/linux/audit.h  | 10 ++
 include/uapi/linux/audit.h |  1 +
 kernel/audit.h |  2 ++
 kernel/auditsc.c   | 19 +++
 lib/audit.c|  4 
 lib/compat_audit.c |  4 
 19 files changed, 66 insertions(+)

-- 
2.27.0



[PATCH 2/2] audit: add OPENAT2 record to list how

2021-03-17 Thread Richard Guy Briggs
Since the openat2(2) syscall uses a struct open_how pointer to communicate
its parameters they are not usefully recorded by the audit SYSCALL record's
four existing arguments.

Add a new audit record type OPENAT2 that reports the parameters in its
third argument, struct open_how with fields oflag, mode and resolve.

The new record in the context of an event would look like:
time->Wed Mar 17 16:28:53 2021
type=PROCTITLE msg=audit(1616012933.531:184): 
proctitle=73797363616C6C735F66696C652F6F70656E617432002F746D702F61756469742D7465737473756974652D737641440066696C652D6F70656E617432
type=PATH msg=audit(1616012933.531:184): item=1 name="file-openat2" inode=29 
dev=00:1f mode=0100600 ouid=0 ogid=0 rdev=00:00 
obj=unconfined_u:object_r:user_tmp_t:s0 nametype=CREATE cap_fp=0 cap_fi=0 
cap_fe=0 cap_fver=0 cap_frootid=0
type=PATH msg=audit(1616012933.531:184): item=0 
name="/root/rgb/git/audit-testsuite/tests" inode=25 dev=00:1f mode=040700 
ouid=0 ogid=0 rdev=00:00 obj=unconfined_u:object_r:user_tmp_t:s0 
nametype=PARENT cap_fp=0 cap_fi=0 cap_fe=0 cap_fver=0 cap_frootid=0
type=CWD msg=audit(1616012933.531:184): 
cwd="/root/rgb/git/audit-testsuite/tests"
type=OPENAT2 msg=audit(1616012933.531:184): oflag=0100302 mode=0600 resolve=0xa
type=SYSCALL msg=audit(1616012933.531:184): arch=c03e syscall=437 
success=yes exit=4 a0=3 a1=7ffe315f1c53 a2=7ffe315f1550 a3=18 items=2 ppid=528 
pid=540 auid=0 uid=0 gid=0 euid=0 suid=0 fsuid=0 egid=0 sgid=0 fsgid=0 
tty=ttyS0 ses=1 comm="openat2" 
exe="/root/rgb/git/audit-testsuite/tests/syscalls_file/openat2" 
subj=unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c1023 
key="testsuite-1616012933-bjAUcEPO"

Signed-off-by: Richard Guy Briggs 
---
 fs/open.c  |  2 ++
 include/linux/audit.h  | 10 ++
 include/uapi/linux/audit.h |  1 +
 kernel/audit.h |  2 ++
 kernel/auditsc.c   | 18 +-
 5 files changed, 32 insertions(+), 1 deletion(-)

diff --git a/fs/open.c b/fs/open.c
index e53af13b5835..2a15bec0cf6d 100644
--- a/fs/open.c
+++ b/fs/open.c
@@ -1235,6 +1235,8 @@ SYSCALL_DEFINE4(openat2, int, dfd, const char __user *, 
filename,
if (err)
return err;
 
+   audit_openat2_how();
+
/* O_LARGEFILE is only allowed for non-O_PATH. */
if (!(tmp.flags & O_PATH) && force_o_largefile())
tmp.flags |= O_LARGEFILE;
diff --git a/include/linux/audit.h b/include/linux/audit.h
index 82b7c1116a85..4c9bc387f7b3 100644
--- a/include/linux/audit.h
+++ b/include/linux/audit.h
@@ -398,6 +398,7 @@ extern int __audit_log_bprm_fcaps(struct linux_binprm *bprm,
  const struct cred *old);
 extern void __audit_log_capset(const struct cred *new, const struct cred *old);
 extern void __audit_mmap_fd(int fd, int flags);
+extern void __audit_openat2_how(struct open_how *how);
 extern void __audit_log_kern_module(char *name);
 extern void __audit_fanotify(unsigned int response);
 extern void __audit_tk_injoffset(struct timespec64 offset);
@@ -494,6 +495,12 @@ static inline void audit_mmap_fd(int fd, int flags)
__audit_mmap_fd(fd, flags);
 }
 
+static inline void audit_openat2_how(struct open_how *how)
+{
+   if (unlikely(!audit_dummy_context()))
+   __audit_openat2_how(how);
+}
+
 static inline void audit_log_kern_module(char *name)
 {
if (!audit_dummy_context())
@@ -645,6 +652,9 @@ static inline void audit_log_capset(const struct cred *new,
 static inline void audit_mmap_fd(int fd, int flags)
 { }
 
+static inline void audit_openat2_how(struct open_how *how)
+{ }
+
 static inline void audit_log_kern_module(char *name)
 {
 }
diff --git a/include/uapi/linux/audit.h b/include/uapi/linux/audit.h
index cd2d8279a5e4..67aea2370c6d 100644
--- a/include/uapi/linux/audit.h
+++ b/include/uapi/linux/audit.h
@@ -118,6 +118,7 @@
 #define AUDIT_TIME_ADJNTPVAL   1333/* NTP value adjustment */
 #define AUDIT_BPF  1334/* BPF subsystem */
 #define AUDIT_EVENT_LISTENER   1335/* Task joined multicast read socket */
+#define AUDIT_OPENAT2  1336/* Record showing openat2 how args */
 
 #define AUDIT_AVC  1400/* SE Linux avc denial or grant */
 #define AUDIT_SELINUX_ERR  1401/* Internal SE Linux Errors */
diff --git a/kernel/audit.h b/kernel/audit.h
index 3b9c0945225a..97db994155e0 100644
--- a/kernel/audit.h
+++ b/kernel/audit.h
@@ -11,6 +11,7 @@
 #include 
 #include 
 #include 
+#include  // struct open_how
 
 /* AUDIT_NAMES is the number of slots we reserve in the audit_context
  * for saving names from getname().  If we get more names we will allocate
@@ -185,6 +186,7 @@ struct audit_context {
int fd;
int flags;
} mmap;
+   struct open_how openat2;
struct {

Re: [PATCH 1/2] audit: document /proc/PID/loginuid

2021-03-17 Thread Richard Guy Briggs
On 2021-03-12 14:15, Paul Moore wrote:
> On Thu, Mar 11, 2021 at 11:41 AM Richard Guy Briggs  wrote:
> > Describe the /proc/PID/loginuid interface in Documentation/ABI/stable that
> > was added 2005-02-01 by commit 1e2d1492e178 ("[PATCH] audit: handle
> > loginuid through proc")
> >
> > Signed-off-by: Richard Guy Briggs 
> > ---
> >  Documentation/ABI/stable/procfs-audit_loginuid | 15 +++
> >  1 file changed, 15 insertions(+)
> >  create mode 100644 Documentation/ABI/stable/procfs-audit_loginuid
> 
> After ~15 years, it might be time ;)
> 
> > diff --git a/Documentation/ABI/stable/procfs-audit_loginuid 
> > b/Documentation/ABI/stable/procfs-audit_loginuid
> > new file mode 100664
> > index ..fae63bef2970
> > --- /dev/null
> > +++ b/Documentation/ABI/stable/procfs-audit_loginuid
> > @@ -0,0 +1,15 @@
> > +What:  Audit Login UID
> > +Date:  2005-02-01
> > +KernelVersion: 2.6.11-rc2 1e2d1492e178 ("[PATCH] audit: handle loginuid 
> > through proc")
> > +Contact:   linux-au...@redhat.com
> > +Format:u32
> 
> I haven't applied the patch, but I'm going to assume that the "u32"
> lines up correctly with the rest of the entries, right?

Yes, they do.  I'm wondering if they should read instead "%u" since the
internal kernel representation isn't as important as what format (number
base) is expected and presented.

> > +Users: auditd, libaudit, audit-testsuite, login
> 
> I think these entries are a bit too specific as I expect the kernel to
> outlive most userspace libraries and applications.  I would suggest
> "audit and login applications" or something similar.

In other examples, users range from a description to an email address,
to a URI, to a repository name or address, to a package name, to
specific files.  I'd prefer to be as specific as reasonably possible
without going into gory detail.

> > +Description:
> > +   The /proc/$pid/loginuid pseudofile is written to set and
> 
> I'm really in no position to critique someone's English grammar, but
> if we're talking about changes I might add a comma after "set", "...
> is written to set, and read to get ...".

This would be the Oxford comma debate, and has a sronger preference by
USA-ians that Brits.  It can help disambiguate meaning in a list of
three or more items.

> > +   read to get the audit login UID of process $pid.  If it is
> > +   unset, permissions are not needed to set it.  The accessor 
> > must
> > +   have CAP_AUDIT_CONTROL in the initial user namespace to 
> > write
> > +   it if it has been set.  It cannot be written again if
> > +   AUDIT_FEATURE_LOGINUID_IMMUTABLE is enabled.  It cannot be
> > +   unset if AUDIT_FEATURE_ONLY_UNSET_LOGINUID is enabled.
> 
> paul moore

- RGB

--
Richard Guy Briggs 
Sr. S/W Engineer, Kernel Security, Base Operating Systems
Remote, Ottawa, Red Hat Canada
IRC: rgb, SunRaycer
Voice: +1.647.777.2635, Internal: (81) 32635



Re: [PATCH] MAINTAINERS: update audit files

2021-03-12 Thread Richard Guy Briggs
On 2021-03-12 16:38, Paul Moore wrote:
> On Thu, Mar 11, 2021 at 11:41 AM Richard Guy Briggs  wrote:
> > Add files maintaned by the audit subsystem.
> >
> > Signed-off-by: Richard Guy Briggs 
> > ---
> >  MAINTAINERS | 4 
> >  1 file changed, 4 insertions(+)
> >
> > diff --git a/MAINTAINERS b/MAINTAINERS
> > index 6eff4f720c72..a17532559665 100644
> > --- a/MAINTAINERS
> > +++ b/MAINTAINERS
> > @@ -3015,9 +3015,13 @@ L:   linux-au...@redhat.com (moderated for 
> > non-subscribers)
> >  S: Supported
> >  W: https://github.com/linux-audit
> >  T: git git://git.kernel.org/pub/scm/linux/kernel/git/pcmoore/audit.git
> > +F: arch/*/*/*audit*.[ch]
> 
> That looks like it has about two too many wildcards to hold up over time :)
> 
> I understand what you're trying to do here, and while I don't disagree
> in principle, I worry that the arch specific paths vary enough that
> trying to handle it here is going to be a bit of a mess.
> 
> > +F: arch/x86/include/asm/audit.h
> 
> The fact that we need a special entry for the single header under x86
> tends to reinforce that.  The other additions make sense, but I think
> it may be best to leave the arch specific areas alone for now.

Ok, I should have labelled this "RFC".  :-)

> > +F: include/asm-generic/audit_*.h
> >  F: include/linux/audit.h
> >  F: include/uapi/linux/audit.h
> >  F: kernel/audit*
> > +F: lib/*audit.c
> >
> >  AUXILIARY DISPLAY DRIVERS
> >  M: Miguel Ojeda Sandonis 
> > --
> > 2.27.0
> 
> paul moore

- RGB

--
Richard Guy Briggs 
Sr. S/W Engineer, Kernel Security, Base Operating Systems
Remote, Ottawa, Red Hat Canada
IRC: rgb, SunRaycer
Voice: +1.647.777.2635, Internal: (81) 32635



[PATCH 2/2] audit: document /proc/PID/sessionid

2021-03-11 Thread Richard Guy Briggs
Describe the /proc/PID/loginuid interface in Documentation/ABI/stable that
was added 2008-03-13 in commit 1e0bd7550ea9 ("[PATCH] export sessionid
alongside the loginuid in procfs")

Signed-off-by: Richard Guy Briggs 
---
 Documentation/ABI/stable/procfs-audit_loginuid | 12 
 1 file changed, 12 insertions(+)

diff --git a/Documentation/ABI/stable/procfs-audit_loginuid 
b/Documentation/ABI/stable/procfs-audit_loginuid
index fae63bef2970..175ee6ec3695 100644
--- a/Documentation/ABI/stable/procfs-audit_loginuid
+++ b/Documentation/ABI/stable/procfs-audit_loginuid
@@ -13,3 +13,15 @@ Description:
AUDIT_FEATURE_LOGINUID_IMMUTABLE is enabled.  It cannot be
unset if AUDIT_FEATURE_ONLY_UNSET_LOGINUID is enabled.
 
+
+What:  Audit Login Session ID
+Date:  2008-03-13
+KernelVersion: 2.6.25-rc7 1e0bd7550ea9 ("[PATCH] export sessionid alongside 
the loginuid in procfs")
+Contact:   linux-au...@redhat.com
+Format:u32
+Users: auditd, libaudit, audit-testsuite, login
+Description:
+   The /proc/$pid/sessionid pseudofile is read to get the
+   audit login session ID of process $pid.  It is set
+   automatically, serially assigned with each new login.
+
-- 
2.27.0



[PATCH 0/2] audit: add documentation for /proc/PID/stable interfaces

2021-03-11 Thread Richard Guy Briggs
Add Documentation/ABI entries for audit interfaces in /proc/PID/ that have
been stable for more than a decade.

Richard Guy Briggs (2):
  audit: document /proc/PID/loginuid
  audit: document /proc/PID/sessionid

 .../ABI/stable/procfs-audit_loginuid  | 27 +++
 1 file changed, 27 insertions(+)
 create mode 100644 Documentation/ABI/stable/procfs-audit_loginuid

-- 
2.27.0



[PATCH 1/2] audit: document /proc/PID/loginuid

2021-03-11 Thread Richard Guy Briggs
Describe the /proc/PID/loginuid interface in Documentation/ABI/stable that
was added 2005-02-01 by commit 1e2d1492e178 ("[PATCH] audit: handle
loginuid through proc")

Signed-off-by: Richard Guy Briggs 
---
 Documentation/ABI/stable/procfs-audit_loginuid | 15 +++
 1 file changed, 15 insertions(+)
 create mode 100644 Documentation/ABI/stable/procfs-audit_loginuid

diff --git a/Documentation/ABI/stable/procfs-audit_loginuid 
b/Documentation/ABI/stable/procfs-audit_loginuid
new file mode 100664
index ..fae63bef2970
--- /dev/null
+++ b/Documentation/ABI/stable/procfs-audit_loginuid
@@ -0,0 +1,15 @@
+What:  Audit Login UID
+Date:  2005-02-01
+KernelVersion: 2.6.11-rc2 1e2d1492e178 ("[PATCH] audit: handle loginuid 
through proc")
+Contact:   linux-au...@redhat.com
+Format:u32
+Users: auditd, libaudit, audit-testsuite, login
+Description:
+   The /proc/$pid/loginuid pseudofile is written to set and
+   read to get the audit login UID of process $pid.  If it is
+   unset, permissions are not needed to set it.  The accessor must
+   have CAP_AUDIT_CONTROL in the initial user namespace to write
+   it if it has been set.  It cannot be written again if
+   AUDIT_FEATURE_LOGINUID_IMMUTABLE is enabled.  It cannot be
+   unset if AUDIT_FEATURE_ONLY_UNSET_LOGINUID is enabled.
+
-- 
2.27.0



[PATCH] MAINTAINERS: update audit files

2021-03-11 Thread Richard Guy Briggs
Add files maintaned by the audit subsystem.

Signed-off-by: Richard Guy Briggs 
---
 MAINTAINERS | 4 
 1 file changed, 4 insertions(+)

diff --git a/MAINTAINERS b/MAINTAINERS
index 6eff4f720c72..a17532559665 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -3015,9 +3015,13 @@ L:   linux-au...@redhat.com (moderated for 
non-subscribers)
 S: Supported
 W: https://github.com/linux-audit
 T: git git://git.kernel.org/pub/scm/linux/kernel/git/pcmoore/audit.git
+F: arch/*/*/*audit*.[ch]
+F: arch/x86/include/asm/audit.h
+F: include/asm-generic/audit_*.h
 F: include/linux/audit.h
 F: include/uapi/linux/audit.h
 F: kernel/audit*
+F: lib/*audit.c
 
 AUXILIARY DISPLAY DRIVERS
 M: Miguel Ojeda Sandonis 
-- 
2.27.0



[PATCH] audit: further cleanup of AUDIT_FILTER_ENTRY deprecation

2021-03-11 Thread Richard Guy Briggs
Remove the list parameter from the function call since the exit filter
list is the only remaining list used by this function.

This cleans up commit 5260ecc2e048
("audit: deprecate the AUDIT_FILTER_ENTRY filter")

Signed-off-by: Richard Guy Briggs 
---
 kernel/auditsc.c | 11 ---
 1 file changed, 4 insertions(+), 7 deletions(-)

diff --git a/kernel/auditsc.c b/kernel/auditsc.c
index 434337ab6b2b..71ead2969eeb 100644
--- a/kernel/auditsc.c
+++ b/kernel/auditsc.c
@@ -805,8 +805,7 @@ static int audit_in_mask(const struct audit_krule *rule, 
unsigned long val)
  * (i.e., the state is AUDIT_SETUP_CONTEXT or AUDIT_BUILD_CONTEXT).
  */
 static void audit_filter_syscall(struct task_struct *tsk,
-struct audit_context *ctx,
-struct list_head *list)
+struct audit_context *ctx)
 {
struct audit_entry *e;
enum audit_state state;
@@ -815,7 +814,7 @@ static void audit_filter_syscall(struct task_struct *tsk,
return;
 
rcu_read_lock();
-   list_for_each_entry_rcu(e, list, list) {
+   list_for_each_entry_rcu(e, _filter_list[AUDIT_FILTER_EXIT], list) 
{
if (audit_in_mask(>rule, ctx->major) &&
audit_filter_rules(tsk, >rule, ctx, NULL,
   , false)) {
@@ -1627,8 +1626,7 @@ void __audit_free(struct task_struct *tsk)
context->return_valid = AUDITSC_INVALID;
context->return_code = 0;
 
-   audit_filter_syscall(tsk, context,
-_filter_list[AUDIT_FILTER_EXIT]);
+   audit_filter_syscall(tsk, context);
audit_filter_inodes(tsk, context);
if (context->current_state == AUDIT_RECORD_CONTEXT)
audit_log_exit();
@@ -1735,8 +1733,7 @@ void __audit_syscall_exit(int success, long return_code)
else
context->return_code  = return_code;
 
-   audit_filter_syscall(current, context,
-_filter_list[AUDIT_FILTER_EXIT]);
+   audit_filter_syscall(current, context);
audit_filter_inodes(current, context);
if (context->current_state == AUDIT_RECORD_CONTEXT)
audit_log_exit();
-- 
2.27.0



Re: [PATCH ghak124 v3] audit: log nftables configuration change events

2021-02-19 Thread Richard Guy Briggs
On 2021-02-19 01:26, Richard Guy Briggs wrote:
> On 2021-02-18 23:42, Florian Westphal wrote:
> > Richard Guy Briggs  wrote:
> > > > If they appear in a batch tehy will be ignored, if the batch consists of
> > > > such non-modifying ops only then nf_tables_commit() returns early
> > > > because the transaction list is empty (nothing to do/change).
> > > 
> > > Ok, one little inconvenient question: what about GETOBJ_RESET?  That
> > > looks like a hybrid that modifies kernel table counters and reports
> > > synchronously.  That could be a special case call in
> > > nf_tables_dump_obj() and nf_tables_getobj().  Will that cause a storm
> > > per commit?
> > 
> > No, since they can't be part of a commit (they don't implement the
> > 'call_batch' function).
> 
> Ok, good, so they should be safe (but still needs the gfp param to
> audit_log_nfcfg() for atomic alloc in that obj reset callback).

I just noticed that nft_quota_obj_eval() misses logging NFT_MSG_NEWOBJ
in nf_tables_commit(), so that looks like it should be added.

> - RGB

- RGB

--
Richard Guy Briggs 
Sr. S/W Engineer, Kernel Security, Base Operating Systems
Remote, Ottawa, Red Hat Canada
IRC: rgb, SunRaycer
Voice: +1.647.777.2635, Internal: (81) 32635



Re: [PATCH ghak124 v3] audit: log nftables configuration change events

2021-02-18 Thread Richard Guy Briggs
On 2021-02-18 23:42, Florian Westphal wrote:
> Richard Guy Briggs  wrote:
> > > If they appear in a batch tehy will be ignored, if the batch consists of
> > > such non-modifying ops only then nf_tables_commit() returns early
> > > because the transaction list is empty (nothing to do/change).
> > 
> > Ok, one little inconvenient question: what about GETOBJ_RESET?  That
> > looks like a hybrid that modifies kernel table counters and reports
> > synchronously.  That could be a special case call in
> > nf_tables_dump_obj() and nf_tables_getobj().  Will that cause a storm
> > per commit?
> 
> No, since they can't be part of a commit (they don't implement the
> 'call_batch' function).

Ok, good, so they should be safe (but still needs the gfp param to
audit_log_nfcfg() for atomic alloc in that obj reset callback).

> I'm not sure GETOBJ_RESET should be reported in the first place:
> RESET only affects expr internal state, and that state changes all the time
> anyway in response to network traffic.

We report audit lost messages reset as a config change since it affects
the view that an admin has about a system.  An unaccounted for reset
could mislead an administrator into thinking things are alright when
some messages were lost and there was nothing to show for it.  I could
see similar situations with network entity counters.

- RGB

--
Richard Guy Briggs 
Sr. S/W Engineer, Kernel Security, Base Operating Systems
Remote, Ottawa, Red Hat Canada
IRC: rgb, SunRaycer
Voice: +1.647.777.2635, Internal: (81) 32635



Re: [PATCH ghak124 v3] audit: log nftables configuration change events

2021-02-18 Thread Richard Guy Briggs
On 2021-02-18 13:52, Florian Westphal wrote:
> Richard Guy Briggs  wrote:
> > On 2021-02-18 09:22, Florian Westphal wrote:
> > > > It seems I'd need to filter out the NFT_MSG_GET_* ops.
> > > 
> > > No need, the GET ops do not cause changes and will not trigger a
> > > generation id change.
> > 
> > Ah, so it could trigger on generation change.  Would GET ops be included
> > in any other change
> 
> No, GET ops are standalone, they cannot be part of a transaction.
> If you look at
> 
> static const struct nfnl_callback nf_tables_cb[NFT_MSG_MAX] = {
> 
> array in nf_tables_api.c, then those ops with a '.call_batch' can
> appear in transaction (i.e., can cause modification).
> 
> The other ones (.call_rcu) are read-only.
> 
> If they appear in a batch tehy will be ignored, if the batch consists of
> such non-modifying ops only then nf_tables_commit() returns early
> because the transaction list is empty (nothing to do/change).

Ok, one little inconvenient question: what about GETOBJ_RESET?  That
looks like a hybrid that modifies kernel table counters and reports
synchronously.  That could be a special case call in
nf_tables_dump_obj() and nf_tables_getobj().  Will that cause a storm
per commit?

> > such that it would be desirable to filter them out
> > to reduce noise in that single log line if it is attempted to list all
> > the change ops?  It almost sounds like it would be better to do one
> > audit log line for each table for each family, and possibly for each op
> > to avoid the need to change userspace.  This would already be a
> > significant improvement picking the highest ranking op.
> 
> I think i understand what you'd like to do.  Yes, that would reduce
> the log output a lot.

Coded, testing...

- RGB

--
Richard Guy Briggs 
Sr. S/W Engineer, Kernel Security, Base Operating Systems
Remote, Ottawa, Red Hat Canada
IRC: rgb, SunRaycer
Voice: +1.647.777.2635, Internal: (81) 32635



Re: [PATCH ghak124 v3] audit: log nftables configuration change events

2021-02-18 Thread Richard Guy Briggs
On 2021-02-18 13:52, Florian Westphal wrote:
> Richard Guy Briggs  wrote:
> > On 2021-02-18 09:22, Florian Westphal wrote:
> > > No.  There is a hierarchy, e.g. you can't add a chain without first
> > > adding a table, BUT in case the table was already created by an earlier
> > > transaction it can also be stand-alone.
> > 
> > Ok, so there could be a stand-alone chain mod with one table, then a
> > table add of a different one with a "higher ranking" op...
> 
> Yes, that can happen.

Ok, can I get one more clarification on this "hierarchy"?  Is it roughly
in the order they appear in nf_tables_commit() after step 3?  It appears
it might be mostly already.  If it isn't already, would it be reasonable
to re-order them?  Would you suggest a different order?

(snip GET bits, that's now clear, thank you)

> > such that it would be desirable to filter them out
> > to reduce noise in that single log line if it is attempted to list all
> > the change ops?  It almost sounds like it would be better to do one
> > audit log line for each table for each family, and possibly for each op
> > to avoid the need to change userspace.  This would already be a
> > significant improvement picking the highest ranking op.
> 
> I think i understand what you'd like to do.  Yes, that would reduce
> the log output a lot.

Would the generation change id be useful outside the kernel?  What
exactly does it look like?  I don't quite understand the genmask purpose.

- RGB

--
Richard Guy Briggs 
Sr. S/W Engineer, Kernel Security, Base Operating Systems
Remote, Ottawa, Red Hat Canada
IRC: rgb, SunRaycer
Voice: +1.647.777.2635, Internal: (81) 32635



Re: [PATCH ghak124 v3] audit: log nftables configuration change events

2021-02-18 Thread Richard Guy Briggs
On 2021-02-18 09:22, Florian Westphal wrote:
> Richard Guy Briggs  wrote:
> > On 2021-02-11 23:09, Florian Westphal wrote:
> > > So, if just a summary is needed a single audit_log_nfcfg()
> > > after 'step 3' and outside of the list_for_each_entry_safe() is all
> > > that is needed.
> > 
> > Ok, so it should not matter if it is before or after that
> > list_for_each_entry_safe(), which could be used to collect that summary.
> 
> Right, it won't matter.
> 
> > > If a summary is wanted as well one could fe. count the number of
> > > transaction types in the batch, e.g. table adds, chain adds, rule
> > > adds etc. and then log a summary count instead.
> > 
> > The current fields are "table", "family", "entries", "op".
> > 
> > Could one batch change more than one table?  (I think it could?)
> 
> Yes.

Ok, listing all tables involved in one commit with deduplication will be
a bit of a nuisance.

> > It appears it can change more than one family.
> > "family" is currently a single integer, so that might need to be changed
> > to a list, or something to indicate multi-family.
> 
> Yes, it can also affect different families.
> 
> > Listing all the ops seems a bit onerous.  Is there a hierarchy to the
> > ops and if so, are they in that order in a batch or in nf_tables_commit()?
> 
> No.  There is a hierarchy, e.g. you can't add a chain without first
> adding a table, BUT in case the table was already created by an earlier
> transaction it can also be stand-alone.

Ok, so there could be a stand-alone chain mod with one table, then a
table add of a different one with a "higher ranking" op...

> > It seems I'd need to filter out the NFT_MSG_GET_* ops.
> 
> No need, the GET ops do not cause changes and will not trigger a
> generation id change.

Ah, so it could trigger on generation change.  Would GET ops be included
in any other change, such that it would be desirable to filter them out
to reduce noise in that single log line if it is attempted to list all
the change ops?  It almost sounds like it would be better to do one
audit log line for each table for each family, and possibly for each op
to avoid the need to change userspace.  This would already be a
significant improvement picking the highest ranking op.

- RGB

--
Richard Guy Briggs 
Sr. S/W Engineer, Kernel Security, Base Operating Systems
Remote, Ottawa, Red Hat Canada
IRC: rgb, SunRaycer
Voice: +1.647.777.2635, Internal: (81) 32635



Re: [PATCH ghak124 v3] audit: log nftables configuration change events

2021-02-17 Thread Richard Guy Briggs
On 2021-02-11 23:09, Florian Westphal wrote:
> Richard Guy Briggs  wrote:
> > > > I personally would notify once per transaction. This is easy and quick.
> > 
> > This was the goal.  iptables was atomic.  nftables appears to no longer
> > be so.  If I have this wrong, please show how that works.
> 
> nftables transactions are atomic, either the entire batch takes effect or not
> at all.
> 
> The audit_log_nfcfg() calls got added to the the nft monitor infra which
> is designed to allow userspace to follow the entire content of the
> transaction log.
> 
> So, if its just a 'something was changed' event that is needed all of
> them can be removed. ATM the audit_log_nfcfg() looks like this:
> 
> /* step 3. Start new generation, rules_gen_X now in use. */
> net->nft.gencursor = nft_gencursor_next(net);
> 
> list_for_each_entry_safe(trans, next, >nft.commit_list, list) {
> switch (trans->msg_type) {
> case NFT_MSG_NEWTABLE:
>   audit_log_nfcfg();
>   ...
>   case NFT_MSG_...
>   audit_log_nfcfg();
>   ..
>   }
> 
> which gives an audit_log for every single change in the batch.
> 
> So, if just a summary is needed a single audit_log_nfcfg()
> after 'step 3' and outside of the list_for_each_entry_safe() is all
> that is needed.

Ok, so it should not matter if it is before or after that
list_for_each_entry_safe(), which could be used to collect that summary.

> If a summary is wanted as well one could fe. count the number of
> transaction types in the batch, e.g. table adds, chain adds, rule
> adds etc. and then log a summary count instead.

The current fields are "table", "family", "entries", "op".

Could one batch change more than one table?  (I think it could?)

It appears it can change more than one family.
"family" is currently a single integer, so that might need to be changed
to a list, or something to indicate multi-family.

A batch can certainly change more than one chain, but that was already a
bonus.

"entries" would be the obvious place for the summary count.

Listing all the ops seems a bit onerous.  Is there a hierarchy to the
ops and if so, are they in that order in a batch or in nf_tables_commit()?
It seems I'd need to filter out the NFT_MSG_GET_* ops.


- RGB

--
Richard Guy Briggs 
Sr. S/W Engineer, Kernel Security, Base Operating Systems
Remote, Ottawa, Red Hat Canada
IRC: rgb, SunRaycer
Voice: +1.647.777.2635, Internal: (81) 32635



Re: [PATCH ghak124 v3] audit: log nftables configuration change events

2021-02-12 Thread Richard Guy Briggs
On 2021-02-12 13:11, Phil Sutter wrote:
> Hi,
> 
> On Thu, Feb 11, 2021 at 04:02:55PM -0500, Steve Grubb wrote:
> > On Thursday, February 11, 2021 11:29:34 AM EST Paul Moore wrote:
> > > > If I'm not mistaken, iptables emits a single audit log per table, ipset
> > > > doesn't support audit at all. So I wonder how much audit logging is
> > > > required at all (for certification or whatever reason). How much
> > > > granularity is desired?
> >  
> >
> > 
> > > I believe the netfilter auditing was mostly a nice-to-have bit of
> > > functionality to help add to the completeness of the audit logs, but I
> > > could very easily be mistaken.  Richard put together those patches, he
> > > can probably provide the background/motivation for the effort.
> > 
> > There are certifications which levy requirements on information flow 
> > control. 
> > The firewall can decide if information should flow or be blocked. 
> > Information 
> > flow decisions need to be auditable - which we have with the audit target. 
> 
> In nftables, this is realized via 'log level audit' statement.
> Functionality should by all means be identical to that of xtables' AUDIT
> target.
> 
> > That then swings in requirements on the configuration of the information 
> > flow 
> > policy.
> > 
> > The requirements state a need to audit any management activity - meaning 
> > the 
> > creation, modification, and/or deletion of a "firewall ruleset". Because it 
> > talks constantly about a ruleset and then individual rules, I suspect only 
> > 1 
> > summary event is needed to say something happened, who did it, and the 
> > outcome. This would be in line with how selinux is treated: we have 1 
> > summary 
> > event for loading/modifying/unloading selinux policy.
> 
> So the central element are firewall rules for audit purposes and
> NETFILTER_CFG notifications merely serve asserting changes to those
> rules are noticed by the auditing system. Looking at xtables again, this
> seems coherent: Any change causes the whole table blob to be replaced
> (while others stay in place). So table replace/create is the most common
> place for a change notification. In nftables, the most common one is
> generation dump - all tables are treated as elements of the same
> ruleset, not individually like in xtables.
> 
> Richard, assuming the above is correct, are you fine with reducing
> nftables auditing to a single notification per transaction then? I guess
> Florian sufficiently illustrated how this would be implemented.

Yes, that should be possible.

> > Hope this helps...
> 
> It does, thanks a lot for the information!
> 
> Thanks, Phil

- RGB

--
Richard Guy Briggs 
Sr. S/W Engineer, Kernel Security, Base Operating Systems
Remote, Ottawa, Red Hat Canada
IRC: rgb, SunRaycer
Voice: +1.647.777.2635, Internal: (81) 32635



Re: [PATCH ghak124 v3] audit: log nftables configuration change events

2021-02-12 Thread Richard Guy Briggs
On 2021-02-11 15:26, Richard Guy Briggs wrote:
> On 2021-02-11 11:29, Paul Moore wrote:
> > On Thu, Feb 11, 2021 at 10:16 AM Phil Sutter  wrote:
> > > Hi,
> > >
> > > On Thu, Jun 04, 2020 at 09:20:49AM -0400, Richard Guy Briggs wrote:
> > > > iptables, ip6tables, arptables and ebtables table registration,
> > > > replacement and unregistration configuration events are logged for the
> > > > native (legacy) iptables setsockopt api, but not for the
> > > > nftables netlink api which is used by the nft-variant of iptables in
> > > > addition to nftables itself.
> > > >
> > > > Add calls to log the configuration actions in the nftables netlink api.
> > >
> > > As discussed offline already, these audit notifications are pretty hefty
> > > performance-wise. In an internal report, 300% restore time of a ruleset
> > > containing 70k set elements is measured.
> > 
> > If you're going to reference offline/off-list discussions in a post to
> > a public list, perhaps the original discussion shouldn't have been
> > off-list ;)  If you don't involve us in the discussion, we have to
> > waste a lot of time getting caught up.
> 
> Here's part of that discussion:
>   https://bugzilla.redhat.com/show_bug.cgi?id=1918013

Here's the rest:
 https://bugzilla.redhat.com/show_bug.cgi?id=1921624

> > > If I'm not mistaken, iptables emits a single audit log per table, ipset
> > > doesn't support audit at all. So I wonder how much audit logging is
> > > required at all (for certification or whatever reason). How much
> > > granularity is desired?
> > 
> > That's a question for the people who track these certification
> > requirements, which is thankfully not me at the moment.  Unless
> > somebody else wants to speak up, Steve Grubb is probably the only
> > person who tracks that sort of stuff and comments here.
> > 
> > I believe the netfilter auditing was mostly a nice-to-have bit of
> > functionality to help add to the completeness of the audit logs, but I
> > could very easily be mistaken.  Richard put together those patches, he
> > can probably provide the background/motivation for the effort.
> 
> It was added because an audit test that normally produced records from
> iptables on one distro stopped producing any records on another.
> Investigation led to the fact that on the first it was using
> iptables-legacy API and on the other it was using iptables-nft API.
> 
> > > I personally would notify once per transaction. This is easy and quick.
> 
> This was the goal.  iptables was atomic.  nftables appears to no longer
> be so.  If I have this wrong, please show how that works.
> 
> > > Once per table or chain should be acceptable, as well. At the very
> > > least, we should not have to notify once per each element. This is the
> > > last resort of fast ruleset adjustments. If we lose it, people are
> > > better off with ipset IMHO.
> > >
> > > Unlike nft monitor, auditd is not designed to be disabled "at will". So
> > > turning it off for performance-critical workloads is no option.
> 
> If it were to be disabled "at will" it would defeat the purpose of
> audit.  Those records can already be filtered, or audit can be disabled,
> but let us look at rationalizing the current nftables records first.
> 
> > Patches are always welcome, but it might be wise to get to the bottom
> > of the certification requirements first.
> > 
> > paul moore
> 
> - RGB

- RGB

--
Richard Guy Briggs 
Sr. S/W Engineer, Kernel Security, Base Operating Systems
Remote, Ottawa, Red Hat Canada
IRC: rgb, SunRaycer
Voice: +1.647.777.2635, Internal: (81) 32635



Re: [PATCH ghak124 v3] audit: log nftables configuration change events

2021-02-11 Thread Richard Guy Briggs
On 2021-02-11 11:29, Paul Moore wrote:
> On Thu, Feb 11, 2021 at 10:16 AM Phil Sutter  wrote:
> > Hi,
> >
> > On Thu, Jun 04, 2020 at 09:20:49AM -0400, Richard Guy Briggs wrote:
> > > iptables, ip6tables, arptables and ebtables table registration,
> > > replacement and unregistration configuration events are logged for the
> > > native (legacy) iptables setsockopt api, but not for the
> > > nftables netlink api which is used by the nft-variant of iptables in
> > > addition to nftables itself.
> > >
> > > Add calls to log the configuration actions in the nftables netlink api.
> >
> > As discussed offline already, these audit notifications are pretty hefty
> > performance-wise. In an internal report, 300% restore time of a ruleset
> > containing 70k set elements is measured.
> 
> If you're going to reference offline/off-list discussions in a post to
> a public list, perhaps the original discussion shouldn't have been
> off-list ;)  If you don't involve us in the discussion, we have to
> waste a lot of time getting caught up.

Here's part of that discussion:
https://bugzilla.redhat.com/show_bug.cgi?id=1918013

> > If I'm not mistaken, iptables emits a single audit log per table, ipset
> > doesn't support audit at all. So I wonder how much audit logging is
> > required at all (for certification or whatever reason). How much
> > granularity is desired?
> 
> That's a question for the people who track these certification
> requirements, which is thankfully not me at the moment.  Unless
> somebody else wants to speak up, Steve Grubb is probably the only
> person who tracks that sort of stuff and comments here.
> 
> I believe the netfilter auditing was mostly a nice-to-have bit of
> functionality to help add to the completeness of the audit logs, but I
> could very easily be mistaken.  Richard put together those patches, he
> can probably provide the background/motivation for the effort.

It was added because an audit test that normally produced records from
iptables on one distro stopped producing any records on another.
Investigation led to the fact that on the first it was using
iptables-legacy API and on the other it was using iptables-nft API.

> > I personally would notify once per transaction. This is easy and quick.

This was the goal.  iptables was atomic.  nftables appears to no longer
be so.  If I have this wrong, please show how that works.

> > Once per table or chain should be acceptable, as well. At the very
> > least, we should not have to notify once per each element. This is the
> > last resort of fast ruleset adjustments. If we lose it, people are
> > better off with ipset IMHO.
> >
> > Unlike nft monitor, auditd is not designed to be disabled "at will". So
> > turning it off for performance-critical workloads is no option.

If it were to be disabled "at will" it would defeat the purpose of
audit.  Those records can already be filtered, or audit can be disabled,
but let us look at rationalizing the current nftables records first.

> Patches are always welcome, but it might be wise to get to the bottom
> of the certification requirements first.
> 
> -- 
> paul moore
> www.paul-moore.com
> 
> --
> Linux-audit mailing list
> linux-au...@redhat.com
> https://www.redhat.com/mailman/listinfo/linux-audit

- RGB

--
Richard Guy Briggs 
Sr. S/W Engineer, Kernel Security, Base Operating Systems
Remote, Ottawa, Red Hat Canada
IRC: rgb, SunRaycer
Voice: +1.647.777.2635, Internal: (81) 32635



Re: [PATCH v24 21/25] audit: add support for non-syscall auxiliary records

2021-01-26 Thread Richard Guy Briggs
On 2021-01-26 10:58, Casey Schaufler wrote:
> On 1/26/2021 10:42 AM, Richard Guy Briggs wrote:
> > On 2021-01-26 08:41, Casey Schaufler wrote:
> >> Standalone audit records have the timestamp and serial number generated
> >> on the fly and as such are unique, making them standalone.  This new
> >> function audit_alloc_local() generates a local audit context that will
> >> be used only for a standalone record and its auxiliary record(s).  The
> >> context is discarded immediately after the local associated records are
> >> produced.
> >>
> >> Signed-off-by: Richard Guy Briggs 
> >> Signed-off-by: Casey Schaufler 
> >> Cc: linux-au...@redhat.com
> >> To: Richard Guy Briggs 
> > This has been minorly bothering me for several revisions...  Is there a
> > way for the development/authorship to be accurately reflected
> > if/when this patch is merged before the contid patch set?
> 
> I don't know the right way to do that because I had to pull
> some of what was in the original patch out. Any way you would
> like it done is fine with me.

Other than diff context, it appears to be identical to the patch in the
v9 contid patchset (with one tiny cut/paste below, I don't know how it
compiles...).  There are minor updates to bring it up to v11.

> >> ---
> >>  include/linux/audit.h |  8 
> >>  kernel/audit.h|  1 +
> >>  kernel/auditsc.c  | 33 -
> >>  3 files changed, 37 insertions(+), 5 deletions(-)
> >>
> >> diff --git a/include/linux/audit.h b/include/linux/audit.h
> >> index 418a485af114..97cd7471e572 100644
> >> --- a/include/linux/audit.h
> >> +++ b/include/linux/audit.h
> >> @@ -289,6 +289,8 @@ static inline int audit_signal_info(int sig, struct 
> >> task_struct *t)
> >>/* Public API */
> >>  extern int  audit_alloc(struct task_struct *task);
> >>  extern void __audit_free(struct task_struct *task);
> >> +extern struct audit_context *audit_alloc_local(gfp_t gfpflags);
> >> +extern void audit_free_context(struct audit_context *context);
> >>  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);
> >> @@ -552,6 +554,12 @@ static inline void audit_log_nfcfg(const char *name, 
> >> u8 af,
> >>  extern int audit_n_rules;
> >>  extern int audit_signals;
> >>  #else /* CONFIG_AUDITSYSCALL */
> >> ++static inline struct audit_context *audit_alloc_local(gfp_t gfpflags)

This extra "+" that ends up at the beginning of the line looks
unintentional and I'd have expected the compiler to complain.

> >> +{
> >> +  return NULL;
> >> +}
> >> +static inline void audit_free_context(struct audit_context *context)
> >> +{ }
> >>  static inline int audit_alloc(struct task_struct *task)
> >>  {
> >>return 0;
> >> diff --git a/kernel/audit.h b/kernel/audit.h
> >> index ce41886807bb..3f2285e1c6e0 100644
> >> --- a/kernel/audit.h
> >> +++ b/kernel/audit.h
> >> @@ -99,6 +99,7 @@ struct audit_proctitle {
> >>  struct audit_context {
> >>int dummy;  /* must be the first element */
> >>int in_syscall; /* 1 if task is in a syscall */
> >> +  boollocal;  /* local context needed */
> >>enum audit_statestate, current_state;
> >>unsigned intserial; /* serial number for record */
> >>int major;  /* syscall number */
> >> diff --git a/kernel/auditsc.c b/kernel/auditsc.c
> >> index de2b2ecb3aea..479b3933d788 100644
> >> --- a/kernel/auditsc.c
> >> +++ b/kernel/auditsc.c
> >> @@ -927,11 +927,13 @@ static inline void audit_free_aux(struct 
> >> audit_context *context)
> >>}
> >>  }
> >>  
> >> -static inline struct audit_context *audit_alloc_context(enum audit_state 
> >> state)
> >> +static inline struct audit_context *audit_alloc_context(enum audit_state 
> >> state,
> >> +  gfp_t gfpflags)
> >>  {
> >>struct audit_context *context;
> >>  
> >> -  context = kzalloc(sizeof(*context), GFP_KERNEL);
> >> +  /* We can be called in atomic context via audit_tg() */
> >> +  context = kzalloc(size

Re: [PATCH] audit: Make audit_filter_syscall() return void

2021-01-26 Thread Richard Guy Briggs
On 2021-01-26 05:11, menglong8.d...@gmail.com wrote:
> From: Yang Yang 
> 
> No invoker users the return value of audit_filter_syscall().
> So make it return void.

That was my oversight when ripping out the AUDIT_FILTER_ENTRY list:
5260ecc2e048  2018-02-14 ("audit: deprecate the 
AUDIT_FILTER_ENTRY filter")

Might as well also amend the function comment block to remove the
reference to syscall entry since that is no longer relevant.

> Signed-off-by: Yang Yang 

Reviewed-by: Richard Guy Briggs 

> ---
>  kernel/auditsc.c | 8 
>  1 file changed, 4 insertions(+), 4 deletions(-)
> 
> diff --git a/kernel/auditsc.c b/kernel/auditsc.c
> index ce8c9e2279ba..c8e16b9c0f21 100644
> --- a/kernel/auditsc.c
> +++ b/kernel/auditsc.c
> @@ -804,7 +804,7 @@ static int audit_in_mask(const struct audit_krule *rule, 
> unsigned long val)
>   * also not high enough that we already know we have to write an audit
>   * record (i.e., the state is AUDIT_SETUP_CONTEXT or AUDIT_BUILD_CONTEXT).
>   */
> -static enum audit_state audit_filter_syscall(struct task_struct *tsk,
> +static void audit_filter_syscall(struct task_struct *tsk,
>struct audit_context *ctx,
>struct list_head *list)
>  {
> @@ -812,7 +812,7 @@ static enum audit_state audit_filter_syscall(struct 
> task_struct *tsk,
>   enum audit_state state;
>  
>   if (auditd_test_task(tsk))
> - return AUDIT_DISABLED;
> + return;
>  
>   rcu_read_lock();
>   list_for_each_entry_rcu(e, list, list) {
> @@ -821,11 +821,11 @@ static enum audit_state audit_filter_syscall(struct 
> task_struct *tsk,
>  , false)) {
>   rcu_read_unlock();
>   ctx->current_state = state;
> - return state;
> + return;
>   }
>   }
>   rcu_read_unlock();
> - return AUDIT_BUILD_CONTEXT;
> + return;
>  }
>  
>  /*
> -- 
> 2.25.1
> 
> --
> Linux-audit mailing list
> linux-au...@redhat.com
> https://www.redhat.com/mailman/listinfo/linux-audit

- RGB

--
Richard Guy Briggs 
Sr. S/W Engineer, Kernel Security, Base Operating Systems
Remote, Ottawa, Red Hat Canada
IRC: rgb, SunRaycer
Voice: +1.647.777.2635, Internal: (81) 32635



Re: [PATCH v24 21/25] audit: add support for non-syscall auxiliary records

2021-01-26 Thread Richard Guy Briggs
On 2021-01-26 08:41, Casey Schaufler wrote:
> Standalone audit records have the timestamp and serial number generated
> on the fly and as such are unique, making them standalone.  This new
> function audit_alloc_local() generates a local audit context that will
> be used only for a standalone record and its auxiliary record(s).  The
> context is discarded immediately after the local associated records are
> produced.
> 
> Signed-off-by: Richard Guy Briggs 
> Signed-off-by: Casey Schaufler 
> Cc: linux-au...@redhat.com
> To: Richard Guy Briggs 

This has been minorly bothering me for several revisions...  Is there a
way for the development/authorship to be accurately reflected
if/when this patch is merged before the contid patch set?

> ---
>  include/linux/audit.h |  8 
>  kernel/audit.h|  1 +
>  kernel/auditsc.c  | 33 -
>  3 files changed, 37 insertions(+), 5 deletions(-)
> 
> diff --git a/include/linux/audit.h b/include/linux/audit.h
> index 418a485af114..97cd7471e572 100644
> --- a/include/linux/audit.h
> +++ b/include/linux/audit.h
> @@ -289,6 +289,8 @@ static inline int audit_signal_info(int sig, struct 
> task_struct *t)
>   /* Public API */
>  extern int  audit_alloc(struct task_struct *task);
>  extern void __audit_free(struct task_struct *task);
> +extern struct audit_context *audit_alloc_local(gfp_t gfpflags);
> +extern void audit_free_context(struct audit_context *context);
>  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);
> @@ -552,6 +554,12 @@ static inline void audit_log_nfcfg(const char *name, u8 
> af,
>  extern int audit_n_rules;
>  extern int audit_signals;
>  #else /* CONFIG_AUDITSYSCALL */
> ++static inline struct audit_context *audit_alloc_local(gfp_t gfpflags)
> +{
> + return NULL;
> +}
> +static inline void audit_free_context(struct audit_context *context)
> +{ }
>  static inline int audit_alloc(struct task_struct *task)
>  {
>   return 0;
> diff --git a/kernel/audit.h b/kernel/audit.h
> index ce41886807bb..3f2285e1c6e0 100644
> --- a/kernel/audit.h
> +++ b/kernel/audit.h
> @@ -99,6 +99,7 @@ struct audit_proctitle {
>  struct audit_context {
>   int dummy;  /* must be the first element */
>   int in_syscall; /* 1 if task is in a syscall */
> + boollocal;  /* local context needed */
>   enum audit_statestate, current_state;
>   unsigned intserial; /* serial number for record */
>   int major;  /* syscall number */
> diff --git a/kernel/auditsc.c b/kernel/auditsc.c
> index de2b2ecb3aea..479b3933d788 100644
> --- a/kernel/auditsc.c
> +++ b/kernel/auditsc.c
> @@ -927,11 +927,13 @@ static inline void audit_free_aux(struct audit_context 
> *context)
>   }
>  }
>  
> -static inline struct audit_context *audit_alloc_context(enum audit_state 
> state)
> +static inline struct audit_context *audit_alloc_context(enum audit_state 
> state,
> + gfp_t gfpflags)
>  {
>   struct audit_context *context;
>  
> - context = kzalloc(sizeof(*context), GFP_KERNEL);
> + /* We can be called in atomic context via audit_tg() */
> + context = kzalloc(sizeof(*context), gfpflags);
>   if (!context)
>   return NULL;
>   context->state = state;
> @@ -967,7 +969,8 @@ int audit_alloc(struct task_struct *tsk)
>   return 0;
>   }
>  
> - if (!(context = audit_alloc_context(state))) {
> + context = audit_alloc_context(state, GFP_KERNEL);
> + if (!context) {
>   kfree(key);
>   audit_log_lost("out of memory in audit_alloc");
>   return -ENOMEM;
> @@ -979,8 +982,27 @@ int audit_alloc(struct task_struct *tsk)
>   return 0;
>  }
>  
> -static inline void audit_free_context(struct audit_context *context)
> +struct audit_context *audit_alloc_local(gfp_t gfpflags)
>  {
> + struct audit_context *context = NULL;
> +
> + context = audit_alloc_context(AUDIT_RECORD_CONTEXT, gfpflags);
> + if (!context) {
> + audit_log_lost("out of memory in audit_alloc_local");
> + goto out;
> + }
> + context->serial = audit_serial();
> + ktime_get_coarse_real_ts64(>ctime);
> + context->local = true;
> +out:
> + return context;
> +}
> +EXPORT_SYMBOL(audit_alloc_local);
> +
> +vo

[PATCH ghak90 v11 04/11] audit: add contid support for signalling the audit daemon

2021-01-12 Thread Richard Guy Briggs
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 
---
Acks from nhorman/omosnace should have been added in v6.
Acks dropped due to restructure audit_sig_info2 for nesting, sigcount, reap 
adtsk
---
 include/linux/audit.h   |   7 +++
 include/uapi/linux/audit.h  |   1 +
 kernel/audit.c  | 118 +---
 security/selinux/nlmsgtab.c |   1 +
 4 files changed, 119 insertions(+), 8 deletions(-)

diff --git a/include/linux/audit.h b/include/linux/audit.h
index 30c55e6b6a3c..7c1928e75cfe 100644
--- a/include/linux/audit.h
+++ b/include/linux/audit.h
@@ -23,6 +23,13 @@ struct audit_sig_info {
charctx[];
 };
 
+struct audit_sig_info2 {
+   uid_t   uid;
+   pid_t   pid;
+   u32 cid_len;
+   chardata[];
+};
+
 struct audit_buffer;
 struct audit_context;
 struct inode;
diff --git a/include/uapi/linux/audit.h b/include/uapi/linux/audit.h
index c56335e828dc..94dcf3085658 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 5495b69bc505..314af418bf67 100644
--- a/kernel/audit.c
+++ b/kernel/audit.c
@@ -123,9 +123,11 @@ static u32 audit_backlog_limit = 64;
 static u32 audit_backlog_wait_time = AUDIT_BACKLOG_WAIT_TIME;
 
 /* The identity of the user shutting down the audit system. */
-static kuid_t  audit_sig_uid = INVALID_UID;
-static pid_t   audit_sig_pid = -1;
-static u32 audit_sig_sid;
+static kuid_t  audit_sig_uid = INVALID_UID;
+static pid_t   audit_sig_pid = -1;
+static u32 audit_sig_sid;
+static struct audit_contobj*audit_sig_cid;
+static struct task_struct  *audit_sig_adtsk;
 
 /* Records can be lost in several ways:
0) [suppressed in audit_alloc]
@@ -222,6 +224,7 @@ struct audit_contobj {
u64 id;
struct task_struct  *owner;
refcount_t  refcount;
+   refcount_t  sigcount;
struct rcu_head rcu;
 };
 
@@ -330,9 +333,39 @@ static void _audit_contobj_put(struct audit_contobj *cont)
if (!cont)
return;
if (refcount_dec_and_test(>refcount)) {
-   put_task_struct(cont->owner);
-   list_del_rcu(>list);
-   kfree_rcu(cont, rcu);
+   if (!refcount_read(>sigcount)) {
+   put_task_struct(cont->owner);
+   list_del_rcu(>list);
+   kfree_rcu(cont, rcu);
+   }
+   }
+}
+
+/* rcu_read_lock must be held by caller unless new */
+static struct audit_contobj *_audit_contobj_get_sig_bytask(struct task_struct 
*tsk)
+{
+   struct audit_contobj *cont;
+   struct audit_task_info *info = tsk->audit;
+
+   if (!info)
+   return NULL;
+   cont = info->cont;
+   if (cont)
+   refcount_inc(>sigcount);
+   return cont;
+}
+
+/* rcu_read_lock must be held by caller */
+static void _audit_contobj_put_sig(struct audit_contobj *cont)
+{
+   if (!cont)
+   return;
+   if (refcount_dec_and_test(>sigcount)) {
+   if (!refcount_read(>refcount)) {
+   put_task_struct(cont->owner);
+   list_del_rcu(>list);
+   kfree_rcu(cont, rcu);
+   }
}
 }
 
@@ -430,6 +463,15 @@ void audit_free(struct task_struct *tsk)
 */
tsk->audit = NULL;
kmem_cache_free(audit_task_cache, info);
+   rcu_read_lock();
+   if (audit_sig_adtsk == tsk) {
+   spin_lock(&_audit_contobj_list_lock);
+   _audit_contobj_put_sig(audit_sig_cid);
+   spin_unlock(&_audit_contobj_list_lock);
+   audit_sig_cid = NULL;
+   audit_sig_adtsk = NULL;
+   }
+   rcu_read_unlock();
 }
 
 /**
@@ -1252,6 +1294,7 @@ static int audit_netlink_ok(struct sk_buff *skb, u16 
msg_type)
  

[PATCH ghak90 v11 10/11] audit: track container nesting

2021-01-12 Thread Richard Guy Briggs
Track the parent container of a container to be able to filter and
report nesting.

Now that we have a way to track and check the parent container of a
container, modify the contid field format to be able to report that
nesting using a carrat ("^") modifier to indicate nesting.  The
original field format was "contid=" for task-associated records
and "contid=[,[...]]" for network-namespace-associated
records.  The new field format is
"contid=[,^[...]][,[...]]".

For task event example, an orchestrator in contid 1 spawns tasks in contid
2 and contid 3, then the task in contid 2 spawns a task in contid 4.  An
event happens in the task in contid 4:
type=SYSCALL ...
type=CONTAINER_ID msg=audit(:): contid=4,^2,^1

For a network namespace event example, an orchestrator in contid 1 in
network namespace A spawns peer tasks 2 and 3 in network namespace B.  An
event happens in network namespace B:
type=NETFILTER_PKT ...
type=CONTAINER_ID msg=audit(:): contid=2,^1,3,^1

Signed-off-by: Richard Guy Briggs 
---
 kernel/audit.c | 75 +-
 1 file changed, 62 insertions(+), 13 deletions(-)

diff --git a/kernel/audit.c b/kernel/audit.c
index fcb78a6d8e4a..d2e9d803e5fd 100644
--- a/kernel/audit.c
+++ b/kernel/audit.c
@@ -231,6 +231,7 @@ struct audit_contobj {
refcount_t  refcount;
refcount_t  sigcount;
struct rcu_head rcu;
+   struct audit_contobj*parent;
 };
 
 struct audit_task_info {
@@ -253,6 +254,7 @@ struct audit_contobj_netns {
 
 static void audit_netns_contid_add(struct net *net, struct audit_contobj 
*cont);
 static void audit_netns_contid_del(struct net *net, struct audit_contobj 
*cont);
+static void audit_log_contid(struct audit_buffer *ab, struct audit_contobj 
*cont);
 
 void __init audit_task_init(void)
 {
@@ -378,6 +380,7 @@ static void _audit_contobj_put_sig(struct audit_contobj 
*cont)
if (refcount_dec_and_test(>sigcount)) {
if (!refcount_read(>refcount)) {
put_task_struct(cont->owner);
+   _audit_contobj_put(cont->parent);
list_del_rcu(>list);
kfree_rcu(cont, rcu);
}
@@ -722,11 +725,11 @@ int audit_log_netns_contid_list(struct net *net, struct 
audit_context *context)
audit_log_lost("out of memory in 
audit_log_netns_contid_list");
goto out;
}
-   audit_log_format(ab, "record=1 contid=%llu",
-cont->obj->id);
+   audit_log_format(ab, "record=1 contid=");
} else {
-   audit_log_format(ab, ",%llu", cont->obj->id);
+   audit_log_format(ab, ",");
}
+   audit_log_contid(ab, cont->obj);
}
audit_log_end(ab);
 out:
@@ -1906,6 +1909,7 @@ static int audit_receive_msg(struct sk_buff *skb, struct 
nlmsghdr *nlh)
case AUDIT_SIGNAL_INFO2: {
char *contidstr = NULL;
unsigned int contidstrlen = 0;
+   struct audit_contobj *cont = audit_sig_cid;
 
len = 0;
if (audit_sig_sid) {
@@ -1915,13 +1919,27 @@ static int audit_receive_msg(struct sk_buff *skb, 
struct nlmsghdr *nlh)
return err;
}
if (audit_sig_cid) {
-   contidstr = kmalloc(21, GFP_KERNEL);
+   contidstr = kmalloc(AUDIT_MESSAGE_TEXT_MAX, GFP_KERNEL);
if (!contidstr) {
if (audit_sig_sid)
security_release_secctx(ctx, len);
return -ENOMEM;
}
-   contidstrlen = scnprintf(contidstr, 20, "%llu", 
audit_sig_cid->id);
+   rcu_read_lock();
+   while (cont) {
+   if (cont->parent)
+   contidstrlen += scnprintf(contidstr,
+ 
AUDIT_MESSAGE_TEXT_MAX -
+ contidstrlen,
+ "%llu,^", 
cont->id);
+   else
+   contidstrlen += scnprintf(contidstr,
+ 
AUDIT_MESSAGE_TEXT_MAX -
+ contidstrlen,
+ "%llu", 
cont->id);
+  

[PATCH ghak90 v11 11/11] audit: add capcontid to set contid outside init_user_ns

2021-01-12 Thread Richard Guy Briggs
Provide a mechanism similar to CAP_AUDIT_CONTROL to explicitly give a
process in a non-init user namespace the capability to set audit
container identifiers of individual children.

Provide the /proc/$PID/audit_capcontid interface to capcontid.
Valid values are: 1==enabled, 0==disabled

Writing a "1" to this special file for the target process $PID will
enable the target process to set audit container identifiers of its
descendants.

A process must already have CAP_AUDIT_CONTROL in the initial user
namespace or have had audit_capcontid enabled by a previous use of this
feature by its parent on this process in order to be able to enable it
for another process.  The target process must be a descendant of the
calling process.

Report this action in new message type AUDIT_SET_CAPCONTID 1022 with
fields opid= capcontid= old-capcontid=

Add an entry to Documentation/ABI.

Signed-off-by: Richard Guy Briggs 
---
 .../ABI/testing/procfs-audit_containerid  | 16 +
 fs/proc/base.c| 54 +++
 include/linux/audit.h |  4 +-
 include/uapi/linux/audit.h|  1 +
 kernel/audit.c| 65 ++-
 5 files changed, 137 insertions(+), 3 deletions(-)

diff --git a/Documentation/ABI/testing/procfs-audit_containerid 
b/Documentation/ABI/testing/procfs-audit_containerid
index 30ea64790473..c697d7da0ad1 100644
--- a/Documentation/ABI/testing/procfs-audit_containerid
+++ b/Documentation/ABI/testing/procfs-audit_containerid
@@ -11,3 +11,19 @@ Description:
or have its own /proc/$pid/capcontainerid set to write
or read.
 
+
+What:  Capability to set or get the Audit Container Identifier
+Date:  2020-??
+KernelVersion: 5.10?
+Contact:   linux-au...@redhat.com
+Format:u32
+Users: auditd, libaudit, audit-testsuite, podman(?), container 
orchestrators
+Description:
+   The /proc/$pid/audit_capcontainerid pseudofile is
+   written to set and is read to get the capability of
+   process $pid to write or to read the /proc/$pid/containerid
+   audit container identifier of any of its descendants.
+   "1" allows and "0" denies that capability.  This
+   property is an extension to CAP_AUDIT_CONTROL outside of
+   the initial user namespace.
+
diff --git a/fs/proc/base.c b/fs/proc/base.c
index bf447e7932d2..7495eec1c73b 100644
--- a/fs/proc/base.c
+++ b/fs/proc/base.c
@@ -1383,6 +1383,58 @@ static const struct file_operations 
proc_contid_operations = {
.write  = proc_contid_write,
.llseek = generic_file_llseek,
 };
+
+static ssize_t proc_capcontid_read(struct file *file, char __user *buf,
+ size_t count, loff_t *ppos)
+{
+   struct inode *inode = file_inode(file);
+   struct task_struct *task = get_proc_task(inode);
+   ssize_t length;
+   char tmpbuf[TMPBUFLEN];
+
+   if (!task)
+   return -ESRCH;
+   length = audit_get_capcontid_proc(tmpbuf, TMPBUFLEN, task);
+   put_task_struct(task);
+   if (length < 0)
+   return length;
+   return simple_read_from_buffer(buf, count, ppos, tmpbuf, length);
+}
+
+static ssize_t proc_capcontid_write(struct file *file, const char __user *buf,
+  size_t count, loff_t *ppos)
+{
+   struct inode *inode = file_inode(file);
+   u32 capcontid;
+   int rv;
+   struct task_struct *task = get_proc_task(inode);
+
+   if (!task)
+   return -ESRCH;
+   if (*ppos != 0) {
+   /* No partial writes. */
+   put_task_struct(task);
+   return -EINVAL;
+   }
+
+   rv = kstrtou32_from_user(buf, count, 10, );
+   if (rv < 0) {
+   put_task_struct(task);
+   return rv;
+   }
+
+   rv = audit_set_capcontid(task, capcontid);
+   put_task_struct(task);
+   if (rv < 0)
+   return rv;
+   return count;
+}
+
+static const struct file_operations proc_capcontid_operations = {
+   .read   = proc_capcontid_read,
+   .write  = proc_capcontid_write,
+   .llseek = generic_file_llseek,
+};
 #endif
 
 #ifdef CONFIG_FAULT_INJECTION
@@ -3286,6 +3338,7 @@ static const struct pid_entry tgid_base_stuff[] = {
REG("loginuid",   S_IWUSR|S_IRUGO, proc_loginuid_operations),
REG("sessionid",  S_IRUGO, proc_sessionid_operations),
REG("audit_containerid", S_IWUSR|S_IRUSR, proc_contid_operations),
+   REG("audit_capcontainerid", S_IWUSR|S_IRUSR, proc_capcontid_operations),
 #endif
 #ifdef CONFIG_FAULT_INJECTION
REG("make-it-fail", S_IRUGO|S_IWUSR, proc_fault_inject_operations),
@@ -3629,6 +3682,7 @@ st

[PATCH ghak90 v11 08/11] audit: add support for containerid to network namespaces

2021-01-12 Thread Richard Guy Briggs
This also adds support to qualify NETFILTER_PKT records.

Audit events could happen in a network namespace outside of a task
context due to packets received from the net that trigger an auditing
rule prior to being associated with a running task.  The network
namespace could be in use by multiple containers by association to the
tasks in that network namespace.  We still want a way to attribute
these events to any potential containers.  Keep a list per network
namespace to track these audit container identifiiers.

Add/increment the audit container identifier on:
- initial setting of the audit container identifier via /proc
- clone/fork call that inherits an audit container identifier
- unshare call that inherits an audit container identifier
- setns call that inherits an audit container identifier
Delete/decrement the audit container identifier on:
- an inherited audit container identifier dropped when child set
- process exit
- unshare call that drops a net namespace
- setns call that drops a net namespace

Add audit container identifier auxiliary record(s) to NETFILTER_PKT
event standalone records.  Iterate through all potential audit container
identifiers associated with a network namespace.  Add the "record=" field to the

A sample event:
  time->Thu Nov 26 10:24:47 2020
  type=NETFILTER_PKT msg=audit(1606404287.984:174549): mark=0x15766399 
saddr=127.0.0.1 daddr=127.0.0.1 proto=1 record=1
  type=CONTAINER_ID msg=audit(1606404287.984:174549): record=1 
contid=4112973747854606336,1916436506412318720

Please see the github audit kernel issue for contid net support:
  https://github.com/linux-audit/audit-kernel/issues/92
Please see the github audit testsuiite issue for the test case:
  https://github.com/linux-audit/audit-testsuite/issues/64
Please see the github audit wiki for the feature overview:
  https://github.com/linux-audit/audit-kernel/wiki/RFE-Audit-Container-ID
Signed-off-by: Richard Guy Briggs 
---
Acks removed due to redo rcu/spin locking:
Acked-by: Neil Horman 
Reviewed-by: Ondrej Mosnacek 
---
 include/linux/audit.h|  17 +++
 kernel/audit.c   | 229 ++-
 kernel/nsproxy.c |   4 +
 net/netfilter/nft_log.c  |  14 ++-
 net/netfilter/xt_AUDIT.c |  14 ++-
 5 files changed, 249 insertions(+), 29 deletions(-)

diff --git a/include/linux/audit.h b/include/linux/audit.h
index 056a7c9a12a2..014f73296fec 100644
--- a/include/linux/audit.h
+++ b/include/linux/audit.h
@@ -217,6 +217,12 @@ extern int audit_get_contid_proc(char *tmpbuf, int 
TMPBUFLEN,
 
 extern int audit_set_contid(struct task_struct *tsk, u64 contid);
 
+extern void audit_copy_namespaces(struct net *net, struct task_struct *tsk);
+extern void audit_switch_task_namespaces(struct nsproxy *ns,
+struct task_struct *p);
+extern int audit_log_netns_contid_list(struct net *net,
+   struct audit_context *context);
+
 extern u32 audit_enabled;
 
 extern int audit_signal_info(int sig, struct task_struct *t);
@@ -281,6 +287,17 @@ static inline unsigned int audit_get_sessionid(struct 
task_struct *tsk)
return AUDIT_SID_UNSET;
 }
 
+static inline void audit_copy_namespaces(struct net *net, struct task_struct 
*tsk)
+{ }
+static inline void audit_switch_task_namespaces(struct nsproxy *ns,
+   struct task_struct *p)
+{ }
+static inline int audit_log_netns_contid_list(struct net *net,
+  struct audit_context *context)
+{
+   return 0;
+}
+
 #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 533254167abf..c30bcd525dad 100644
--- a/kernel/audit.c
+++ b/kernel/audit.c
@@ -59,6 +59,7 @@
 #include 
 #include 
 #include 
+#include 
 
 #include "audit.h"
 
@@ -86,9 +87,13 @@ static unsigned int audit_net_id;
 /**
  * struct audit_net - audit private network namespace data
  * @sk: communication socket
+ * @contobj_list: audit container identifier list
+ * @contobj_list_lock audit container identifier list lock
  */
 struct audit_net {
struct sock *sk;
+   struct list_head contobj_list;
+   spinlock_t contobj_list_lock;
 };
 
 /**
@@ -239,6 +244,16 @@ struct audit_task_info {
 
 static struct kmem_cache *audit_task_cache;
 
+struct audit_contobj_netns {
+   struct list_headlist;
+   struct audit_contobj*obj;
+   int count;
+   struct rcu_head rcu;
+};
+
+static void audit_netns_contid_add(struct net *net, struct audit_contobj 
*cont);
+static void audit_netns_contid_del(struct net *net, struct audit_contobj 
*cont);
+
 void __init audit_task_init(void)
 {
audit_task_cache = kmem_cache_create("audit_task",
@@ -373,11 +388,12 @@ void audit_contobj_put(void **cont, int count)
 {
int i;
struct audit_contobj 

[PATCH ghak90 v11 09/11] audit: contid check descendancy and nesting

2021-01-12 Thread Richard Guy Briggs
Require the target task to be a descendant of the container
orchestrator/engine.

You would only change the audit container ID from one set or inherited
value to another if you were nesting containers.

If changing the contid, the container orchestrator/engine must be a
descendant and not same orchestrator as the one that set it so it is not
possible to change the contid of another orchestrator's container.

Since the task_is_descendant() function is used in YAMA and in audit,
remove the duplication and pull the function into kernel/core/sched.c

Signed-off-by: Richard Guy Briggs 
---
 include/linux/sched.h|  3 +++
 kernel/audit.c   | 26 +++---
 kernel/sched/core.c  | 33 +
 security/yama/yama_lsm.c | 33 -
 4 files changed, 59 insertions(+), 36 deletions(-)

diff --git a/include/linux/sched.h b/include/linux/sched.h
index 1d10d81b8fd5..b30bbfec31ab 100644
--- a/include/linux/sched.h
+++ b/include/linux/sched.h
@@ -2097,4 +2097,7 @@ int sched_trace_rq_nr_running(struct rq *rq);
 
 const struct cpumask *sched_trace_rd_span(struct root_domain *rd);
 
+extern int task_is_descendant(struct task_struct *parent,
+ struct task_struct *child);
+
 #endif
diff --git a/kernel/audit.c b/kernel/audit.c
index c30bcd525dad..fcb78a6d8e4a 100644
--- a/kernel/audit.c
+++ b/kernel/audit.c
@@ -476,11 +476,13 @@ void audit_free(struct task_struct *tsk)
rcu_read_lock();
cont = _audit_contobj_get_bytask(tsk);
rcu_read_unlock();
-   spin_lock_irqsave(&_audit_contobj_list_lock, flags);
if (ns) {
audit_netns_contid_del(ns->net_ns, cont);
+   spin_lock_irqsave(&_audit_contobj_list_lock, flags);
_audit_contobj_put(cont);
+   spin_unlock_irqrestore(&_audit_contobj_list_lock, flags);
}
+   spin_lock_irqsave(&_audit_contobj_list_lock, flags);
_audit_contobj_put(cont);
spin_unlock_irqrestore(&_audit_contobj_list_lock, flags);
audit_free_syscall(tsk);
@@ -2924,6 +2926,21 @@ int audit_signal_info(int sig, struct task_struct *t)
return audit_signal_info_syscall(t);
 }
 
+static bool audit_contid_isnesting(struct task_struct *tsk)
+{
+   bool isowner = false;
+   bool ownerisparent = false;
+   struct audit_task_info *info = tsk->audit;
+
+   rcu_read_lock();
+   if (info && info->cont) {
+   isowner = current == info->cont->owner;
+   ownerisparent = task_is_descendant(info->cont->owner, current);
+   }
+   rcu_read_unlock();
+   return !isowner && ownerisparent;
+}
+
 /*
  * audit_set_contid - set current task's audit contid
  * @tsk: target task
@@ -2964,8 +2981,11 @@ int audit_set_contid(struct task_struct *tsk, u64 contid)
   !(thread_group_leader(tsk) && thread_group_empty(tsk))) {
/* if task has children or is not single-threaded, deny */
rc = -EBUSY;
-   } else if (info->cont) {
-   /* if contid is already set, deny */
+   } else if (tsk == current || !task_is_descendant(current, tsk)) {
+   /* if task is not descendant, block */
+   rc = -EXDEV;
+   } else if (info->cont && !audit_contid_isnesting(tsk)) {
+   /* only allow contid setting again if nesting */
rc = -EEXIST;
}
rcu_read_lock();
diff --git a/kernel/sched/core.c b/kernel/sched/core.c
index 15d2562118d1..f769bcba4ee8 100644
--- a/kernel/sched/core.c
+++ b/kernel/sched/core.c
@@ -9072,6 +9072,39 @@ void dump_cpu_task(int cpu)
sched_show_task(cpu_curr(cpu));
 }
 
+/*
+ * task_is_descendant - walk up a process family tree looking for a match
+ * @parent: the process to compare against while walking up from child
+ * @child: the process to start from while looking upwards for parent
+ *
+ * Returns 1 if child is a descendant of parent, 0 if not.
+ */
+int task_is_descendant(struct task_struct *parent,
+ struct task_struct *child)
+{
+   int rc = 0;
+   struct task_struct *walker = child;
+
+   if (!parent || !child)
+   return 0;
+
+   rcu_read_lock();
+   if (!thread_group_leader(parent))
+   parent = rcu_dereference(parent->group_leader);
+   while (walker->pid > 0) {
+   if (!thread_group_leader(walker))
+   walker = rcu_dereference(walker->group_leader);
+   if (walker == parent) {
+   rc = 1;
+   break;
+   }
+   walker = rcu_dereference(walker->real_parent);
+   }
+   rcu_read_unlock();
+
+   return rc;
+}
+
 /*
  * Nice levels are multiplicative, with a gentle 10% change for every
  * nice level changed. I.e. when a CPU-bound t

[PATCH ghak90 v11 07/11] audit: add containerid filtering

2021-01-12 Thread Richard Guy Briggs
Implement audit container identifier filtering using the AUDIT_CONTID
field name to send an 8-character string representing a u64 since the
value field is only u32.

Sending it as two u32 was considered, but gathering and comparing two
fields was more complex.

The feature indicator is AUDIT_FEATURE_BITMAP_CONTAINERID.

Please see the github audit kernel issue for the contid filter feature:
  https://github.com/linux-audit/audit-kernel/issues/91
Please see the github audit userspace issue for filter additions:
  https://github.com/linux-audit/audit-userspace/issues/40
Please see the github audit testsuiite issue for the test case:
  https://github.com/linux-audit/audit-testsuite/issues/64
Please see the github audit wiki for the feature overview:
  https://github.com/linux-audit/audit-kernel/wiki/RFE-Audit-Container-ID
Signed-off-by: Richard Guy Briggs 
Acked-by: Serge Hallyn 
Acked-by: Neil Horman 
Reviewed-by: Ondrej Mosnacek 
---
 include/linux/audit.h  |  1 +
 include/uapi/linux/audit.h |  5 -
 kernel/audit.c |  5 +
 kernel/audit.h |  3 +++
 kernel/auditfilter.c   | 46 ++
 kernel/auditsc.c   |  3 +++
 6 files changed, 62 insertions(+), 1 deletion(-)

diff --git a/include/linux/audit.h b/include/linux/audit.h
index 9f0238f7960f..056a7c9a12a2 100644
--- a/include/linux/audit.h
+++ b/include/linux/audit.h
@@ -69,6 +69,7 @@ struct audit_field {
u32 type;
union {
u32 val;
+   u64 val64;
kuid_t  uid;
kgid_t  gid;
struct {
diff --git a/include/uapi/linux/audit.h b/include/uapi/linux/audit.h
index 94dcf3085658..66350e572e41 100644
--- a/include/uapi/linux/audit.h
+++ b/include/uapi/linux/audit.h
@@ -271,6 +271,7 @@
 #define AUDIT_LOGINUID_SET 24
 #define AUDIT_SESSIONID25  /* Session ID */
 #define AUDIT_FSTYPE   26  /* FileSystem Type */
+#define AUDIT_CONTID   27  /* Container ID */
 
/* These are ONLY useful when checking
 * at syscall exit time (AUDIT_AT_EXIT). */
@@ -353,6 +354,7 @@ enum {
 #define AUDIT_FEATURE_BITMAP_SESSIONID_FILTER  0x0010
 #define AUDIT_FEATURE_BITMAP_LOST_RESET0x0020
 #define AUDIT_FEATURE_BITMAP_FILTER_FS 0x0040
+#define AUDIT_FEATURE_BITMAP_CONTAINERID   0x0080
 
 #define AUDIT_FEATURE_BITMAP_ALL (AUDIT_FEATURE_BITMAP_BACKLOG_LIMIT | \
  AUDIT_FEATURE_BITMAP_BACKLOG_WAIT_TIME | \
@@ -360,7 +362,8 @@ enum {
  AUDIT_FEATURE_BITMAP_EXCLUDE_EXTEND | \
  AUDIT_FEATURE_BITMAP_SESSIONID_FILTER | \
  AUDIT_FEATURE_BITMAP_LOST_RESET | \
- AUDIT_FEATURE_BITMAP_FILTER_FS)
+ AUDIT_FEATURE_BITMAP_FILTER_FS | \
+ AUDIT_FEATURE_BITMAP_CONTAINERID)
 
 /* deprecated: AUDIT_VERSION_* */
 #define AUDIT_VERSION_LATEST   AUDIT_FEATURE_BITMAP_ALL
diff --git a/kernel/audit.c b/kernel/audit.c
index 946fe5862dc7..533254167abf 100644
--- a/kernel/audit.c
+++ b/kernel/audit.c
@@ -2489,6 +2489,11 @@ int audit_log_container_id_ctx(struct audit_context 
*context)
return record;
 }
 
+int audit_contid_comparator(struct task_struct *tsk, u32 op, u64 right)
+{
+   return audit_comparator64(audit_get_contid(tsk), op, right);
+}
+
 void audit_log_key(struct audit_buffer *ab, char *key)
 {
audit_log_format(ab, " key=");
diff --git a/kernel/audit.h b/kernel/audit.h
index 40e609787a0c..48c429c2d544 100644
--- a/kernel/audit.h
+++ b/kernel/audit.h
@@ -218,12 +218,15 @@ extern void *audit_contobj_get_bytask(struct task_struct 
*tsk);
 extern void audit_contobj_put(void **cont, int count);
 extern int audit_log_container_id(struct audit_context *context, void *cont);
 extern int audit_log_container_id_ctx(struct audit_context *context);
+extern int audit_contid_comparator(struct task_struct *tsk, const u32 op,
+  const u64 right);
 
 /* Indicates that audit should log the full pathname. */
 #define AUDIT_NAME_FULL -1
 
 extern int audit_match_class(int class, unsigned syscall);
 extern int audit_comparator(const u32 left, const u32 op, const u32 right);
+extern int audit_comparator64(const u64 left, const u32 op, const u64 right);
 extern int audit_uid_comparator(kuid_t left, u32 op, kuid_t right);
 extern int audit_gid_comparator(kgid_t left, u32 op, kgid_t right);
 extern int parent_len(const char *path);
diff --git a/kernel/auditfilter.c b/kernel/auditfilter.c
index 333b3bcfc545..9362ee9cc414 100644
--- a/kernel/auditfilter.c
+++ b/kernel/auditfilter.c
@@ -399,6 +399,7 @@ static int audit_field_valid(struct audit_entry *entr

[PATCH ghak90 v11 05/11] audit: add support for non-syscall auxiliary records

2021-01-12 Thread Richard Guy Briggs
Standalone audit records have the timestamp and serial number generated
on the fly and as such are unique, making them standalone.  This new
function audit_alloc_local() generates a local audit context that will
be used only for a standalone record and its auxiliary record(s).  The
context is discarded immediately after the local associated records are
produced.

A new flag, "local" was used rather than "in_syscall" since it would be
overloading the original purpose and meaning.  Events using this
function may not be triggered by a syscall but still need records
linked by timestamp and serial.

Signed-off-by: Richard Guy Briggs 
Acked-by: Serge Hallyn 
Acked-by: Neil Horman 
Reviewed-by: Ondrej Mosnacek 
---
 include/linux/audit.h |  8 
 kernel/audit.h|  1 +
 kernel/auditsc.c  | 31 ++-
 3 files changed, 35 insertions(+), 5 deletions(-)

diff --git a/include/linux/audit.h b/include/linux/audit.h
index 7c1928e75cfe..9f0238f7960f 100644
--- a/include/linux/audit.h
+++ b/include/linux/audit.h
@@ -304,6 +304,8 @@ static inline int audit_signal_info(int sig, struct 
task_struct *t)
 
 /* These are defined in auditsc.c */
/* Public API */
+extern struct audit_context *audit_alloc_local(gfp_t gfpflags);
+extern void audit_free_context(struct audit_context *context);
 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);
@@ -555,6 +557,12 @@ static inline void audit_log_nfcfg(const char *name, u8 af,
 extern int audit_n_rules;
 extern int audit_signals;
 #else /* CONFIG_AUDITSYSCALL */
+static inline struct audit_context *audit_alloc_local(gfp_t gfpflags)
+{
+   return NULL;
+}
+static inline void audit_free_context(struct audit_context *context)
+{ }
 static inline void audit_syscall_entry(int major, unsigned long a0,
   unsigned long a1, unsigned long a2,
   unsigned long a3)
diff --git a/kernel/audit.h b/kernel/audit.h
index de79f59d623f..40e609787a0c 100644
--- a/kernel/audit.h
+++ b/kernel/audit.h
@@ -98,6 +98,7 @@ struct audit_proctitle {
 struct audit_context {
int dummy;  /* must be the first element */
int in_syscall; /* 1 if task is in a syscall */
+   boollocal;  /* local context needed */
enum audit_statestate, current_state;
unsigned intserial; /* serial number for record */
int major;  /* syscall number */
diff --git a/kernel/auditsc.c b/kernel/auditsc.c
index 2d9762f2f432..fc781ab5af2c 100644
--- a/kernel/auditsc.c
+++ b/kernel/auditsc.c
@@ -920,11 +920,12 @@ static inline void audit_free_aux(struct audit_context 
*context)
}
 }
 
-static inline struct audit_context *audit_alloc_context(enum audit_state state)
+static inline struct audit_context *audit_alloc_context(enum audit_state state,
+   gfp_t gfpflags)
 {
struct audit_context *context;
 
-   context = kzalloc(sizeof(*context), GFP_KERNEL);
+   context = kzalloc(sizeof(*context), gfpflags);
if (!context)
return NULL;
context->state = state;
@@ -962,7 +963,8 @@ int audit_alloc_syscall(struct task_struct *tsk)
return 0;
}
 
-   if (!(context = audit_alloc_context(state))) {
+   context = audit_alloc_context(state, GFP_KERNEL);
+   if (!context) {
kfree(key);
audit_log_lost("out of memory in audit_alloc_syscall");
return -ENOMEM;
@@ -974,8 +976,26 @@ int audit_alloc_syscall(struct task_struct *tsk)
return 0;
 }
 
-static inline void audit_free_context(struct audit_context *context)
+struct audit_context *audit_alloc_local(gfp_t gfpflags)
 {
+   struct audit_context *context;
+
+   context = audit_alloc_context(AUDIT_RECORD_CONTEXT, gfpflags);
+   if (!context) {
+   audit_log_lost("out of memory in audit_alloc_local");
+   return NULL;
+   }
+   context->serial = audit_serial();
+   ktime_get_coarse_real_ts64(>ctime);
+   context->local = true;
+   return context;
+}
+EXPORT_SYMBOL(audit_alloc_local);
+
+void audit_free_context(struct audit_context *context)
+{
+   if (!context)
+   return;
audit_free_module(context);
audit_free_names(context);
unroll_tree_refs(context, NULL, 0);
@@ -986,6 +1006,7 @@ static inline void audit_free_context(struct audit_context 
*context)
audit_proctitle_free(context);
kfree(context);
 }
+EXPORT_SYMBOL(audit_free_context);
 
 static int audit_log_pid_context(struct audit_context *context, pid_t pid,

[PATCH ghak90 v11 06/11] audit: add containerid support for user records

2021-01-12 Thread Richard Guy Briggs
Add audit container identifier auxiliary record to user event standalone
records.

Signed-off-by: Richard Guy Briggs 
Acked-by: Neil Horman 
Reviewed-by: Ondrej Mosnacek 
---
 kernel/audit.c | 12 +---
 1 file changed, 5 insertions(+), 7 deletions(-)

diff --git a/kernel/audit.c b/kernel/audit.c
index 314af418bf67..946fe5862dc7 100644
--- a/kernel/audit.c
+++ b/kernel/audit.c
@@ -1339,12 +1339,6 @@ static void audit_log_common_recv_msg(struct 
audit_context *context,
audit_log_task_context(*ab);
 }
 
-static inline void audit_log_user_recv_msg(struct audit_buffer **ab,
-  u16 msg_type)
-{
-   audit_log_common_recv_msg(NULL, ab, msg_type);
-}
-
 int is_audit_feature_set(int i)
 {
return af.features & AUDIT_FEATURE_TO_MASK(i);
@@ -1620,6 +1614,7 @@ static int audit_receive_msg(struct sk_buff *skb, struct 
nlmsghdr *nlh)
err = audit_filter(msg_type, AUDIT_FILTER_USER);
if (err == 1) { /* match or error */
char *str = data;
+   struct audit_context *context;
 
err = 0;
if (msg_type == AUDIT_USER_TTY) {
@@ -1627,7 +1622,8 @@ static int audit_receive_msg(struct sk_buff *skb, struct 
nlmsghdr *nlh)
if (err)
break;
}
-   audit_log_user_recv_msg(, msg_type);
+   context = audit_alloc_local(GFP_KERNEL);
+   audit_log_common_recv_msg(context, , msg_type);
if (msg_type != AUDIT_USER_TTY) {
/* ensure NULL termination */
str[data_len - 1] = '\0';
@@ -1641,6 +1637,8 @@ static int audit_receive_msg(struct sk_buff *skb, struct 
nlmsghdr *nlh)
audit_log_n_untrustedstring(ab, str, data_len);
}
audit_log_end(ab);
+   audit_log_container_id_ctx(context);
+   audit_free_context(context);
}
break;
case AUDIT_ADD_RULE:
-- 
2.18.4



[PATCH ghak90 v11 03/11] audit: log container info of syscalls

2021-01-12 Thread Richard Guy Briggs
Create a new audit record AUDIT_CONTAINER_ID to document the audit
container identifier of a process if it is present.

Called from audit_log_exit(), syscalls are covered.

Include target_cid references from ptrace and signal.

A sample raw event:
  time->Thu Nov 26 10:24:40 2020
  type=PROCTITLE msg=audit(1606404280.226:174542): 
proctitle=2F7573722F62696E2F7065726C002D7700636F6E7461696E657269642F74657374
  type=PATH msg=audit(1606404280.226:174542): item=1 
name="/tmp/audit-testsuite-dir-8riQ/testsuite-1606404267-WNldVJCr" inode=428 
dev=00:1f mode=0100644 ouid=0 ogid=0 rdev=00:00 
obj=unconfined_u:object_r:user_tmp_t:s0 nametype=CREATE cap_fp=0 cap_fi=0 
cap_fe=0 cap_fver=0 cap_frootid=0
  type=PATH msg=audit(1606404280.226:174542): item=0 
name="/tmp/audit-testsuite-dir-8riQ/" inode=427 dev=00:1f mode=040700 ouid=0 
ogid=0 rdev=00:00 obj=unconfined_u:object_r:user_tmp_t:s0 nametype=PARENT 
cap_fp=0 cap_fi=0 cap_fe=0 cap_fver=0 cap_frootid=0
  type=CWD msg=audit(1606404280.226:174542): 
cwd="/root/rgb/git/audit-testsuite/tests"
  type=SYSCALL msg=audit(1606404280.226:174542): arch=c03e syscall=257 
success=yes exit=6 a0=ff9c a1=557446bd5f10 a2=80241 a3=1b6 items=2 
ppid=8724 pid=8758 auid=0 uid=0 gid=0 euid=0 suid=0 fsuid=0 egid=0 sgid=0 
fsgid=0 tty=ttyS0 ses=1 comm="perl" exe="/usr/bin/perl" 
subj=unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c1023 
key="testsuite-1606404267-WNldVJCr" record=1
  type=CONTAINER_ID msg=audit(1606404280.226:174542): record=1 
contid=527940429489930240

Please see the github audit kernel issue for the main feature:
  https://github.com/linux-audit/audit-kernel/issues/90
Please see the github audit userspace issue for supporting additions:
  https://github.com/linux-audit/audit-userspace/issues/51
Please see the github audit testsuiite issue for the test case:
  https://github.com/linux-audit/audit-testsuite/issues/64
Please see the github audit wiki for the feature overview:
  https://github.com/linux-audit/audit-kernel/wiki/RFE-Audit-Container-ID
Signed-off-by: Richard Guy Briggs 
---
Acks removed due to added "record=" field, track container of signalled process
Acked-by: Serge Hallyn 
Acked-by: Steve Grubb 
Acked-by: Neil Horman 
Reviewed-by: Ondrej Mosnacek 
---
 include/uapi/linux/audit.h |  1 +
 kernel/audit.c | 74 ++
 kernel/audit.h |  6 
 kernel/auditsc.c   | 49 -
 4 files changed, 122 insertions(+), 8 deletions(-)

diff --git a/include/uapi/linux/audit.h b/include/uapi/linux/audit.h
index 26d65d0882e2..c56335e828dc 100644
--- a/include/uapi/linux/audit.h
+++ b/include/uapi/linux/audit.h
@@ -119,6 +119,7 @@
 #define AUDIT_TIME_ADJNTPVAL   1333/* NTP value adjustment */
 #define AUDIT_BPF  1334/* BPF subsystem */
 #define AUDIT_EVENT_LISTENER   1335/* Task joined multicast read socket */
+#define AUDIT_CONTAINER_ID 1336/* Container ID */
 
 #define AUDIT_AVC  1400/* SE Linux avc denial or grant */
 #define AUDIT_SELINUX_ERR  1401/* Internal SE Linux Errors */
diff --git a/kernel/audit.c b/kernel/audit.c
index fe94b295a362..5495b69bc505 100644
--- a/kernel/audit.c
+++ b/kernel/audit.c
@@ -319,6 +319,11 @@ static struct audit_contobj 
*_audit_contobj_get_bytask(struct task_struct *tsk)
return _audit_contobj_get(info->cont);
 }
 
+void *audit_contobj_get_bytask(struct task_struct *tsk)
+{
+   return (void *)_audit_contobj_get_bytask(tsk);
+}
+
 /* _audit_contobj_list_lock must be held by caller */
 static void _audit_contobj_put(struct audit_contobj *cont)
 {
@@ -331,6 +336,17 @@ static void _audit_contobj_put(struct audit_contobj *cont)
}
 }
 
+void audit_contobj_put(void **cont, int count)
+{
+   int i;
+   struct audit_contobj **contobj = (struct audit_contobj **)cont;
+
+   spin_lock(&_audit_contobj_list_lock);
+   for (i = 0; i < count; i++)
+   _audit_contobj_put(contobj[i]);
+   spin_unlock(&_audit_contobj_list_lock);
+}
+
 static inline int audit_hash_contid(u64 contid)
 {
return (contid & (AUDIT_CONTID_BUCKETS-1));
@@ -2327,6 +2343,59 @@ void audit_log_session_info(struct audit_buffer *ab)
audit_log_format(ab, "auid=%u ses=%u", auid, sessionid);
 }
 
+/*
+ * _audit_log_container_id - report container info
+ * @context: task or local context for record
+ * @cont: container object to report
+ *
+ * Returns 0 on record absence, positive integer on valid record id.
+ */
+static int _audit_log_container_id(struct audit_context *context,
+   struct audit_contobj *contobj)
+{
+   struct audit_buffer *ab;
+   int record;
+
+   if (!contobj)
+   return 0;
+   /* Generate AUDIT_CONTAINER_ID record with container ID */
+   ab = audit_log_start(context, GFP_KERNEL, AUDIT_CONTAINE

[PATCH ghak90 v11 02/11] audit: add container id

2021-01-12 Thread Richard Guy Briggs
Implement the proc fs write to set the audit container identifier of a
process, emitting an AUDIT_CONTAINER_OP record to document the event.

This is a write from the container orchestrator task to a proc entry of
the form /proc/PID/audit_containerid where PID is the process ID of the
newly created task that is to become the first task in a container, or
an additional task added to a container.

The write expects up to a u64 value (unset: 18446744073709551615).

The writer must have capability CAP_AUDIT_CONTROL.

This will produce an event such as this with the new CONTAINER_OP record:
  time->Thu Nov 26 10:24:27 2020
  type=PROCTITLE msg=audit(1606404267.551:174524): 
proctitle=2F7573722F62696E2F7065726C002D7700636F6E7461696E657269642F74657374
  type=SYSCALL msg=audit(1606404267.551:174524): arch=c03e syscall=1 
success=yes exit=20 a0=6 a1=557446aa9180 a2=14 a3=100 items=0 ppid=6827 
pid=8724 auid=0 uid=0 gid=0 euid=0 suid=0 fsuid=0 egid=0 sgid=0 fsgid=0 
tty=ttyS0 ses=1 comm="perl" exe="/usr/bin/perl" 
subj=unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c1023 key=(null)
  type=CONTAINER_OP msg=audit(1606404267.551:174524): op=set opid=8730 
contid=4515122123205246976 old-contid=-1

The "op" field indicates an initial set.  The "opid" field is the
object's PID, the process being "contained".  New and old audit
container identifier values are given in the "contid" fields.

It is not permitted to unset the audit container identifier.
A child inherits its parent's audit container identifier.

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.

Since the life of each audit container indentifier is being tracked, we match
the creation event with the destruction event.  Log the drop of the audit
container identifier when the last process in that container exits.

Add support for reading the audit container identifier from the proc
filesystem.  This is a read from the proc entry of the form
/proc/PID/audit_containerid where PID is the process ID of the task
whose audit container identifier is sought.  The read expects up to a u64 value
(unset: (u64)-1).  This read requires CAP_AUDIT_CONTROL.

Add an entry to Documentation/ABI for /proc/$pid/audit_containerid.

Please see the github audit kernel issue for the main feature:
  https://github.com/linux-audit/audit-kernel/issues/90
Please see the github audit userspace issue for supporting additions:
  https://github.com/linux-audit/audit-userspace/issues/51
Please see the github audit testsuiite issue for the test case:
  https://github.com/linux-audit/audit-testsuite/issues/64
Please see the github audit wiki for the feature overview:
  https://github.com/linux-audit/audit-kernel/wiki/RFE-Audit-Container-ID

Signed-off-by: Richard Guy Briggs 
---
Acks dropped due to log drop added 7.3, redo rcu/spin locking, u64/contobj
Acked-by: Serge Hallyn 
Acked-by: Steve Grubb 
Acked-by: Neil Horman 
Reviewed-by: Ondrej Mosnacek 
---
 .../ABI/testing/procfs-audit_containerid  |  13 ++
 fs/proc/base.c|  56 -
 include/linux/audit.h |   5 +
 include/uapi/linux/audit.h|   2 +
 kernel/audit.c| 210 ++
 kernel/audit.h|   2 +
 kernel/auditsc.c  |   2 +
 7 files changed, 289 insertions(+), 1 deletion(-)
 create mode 100644 Documentation/ABI/testing/procfs-audit_containerid

diff --git a/Documentation/ABI/testing/procfs-audit_containerid 
b/Documentation/ABI/testing/procfs-audit_containerid
new file mode 100644
index ..30ea64790473
--- /dev/null
+++ b/Documentation/ABI/testing/procfs-audit_containerid
@@ -0,0 +1,13 @@
+What:  Audit Container Identifier
+Date:  2020-??
+KernelVersion: 5.10?
+Contact:   linux-au...@redhat.com
+Format:u64
+Users: auditd, libaudit, audit-testsuite, podman(?), container 
orchestrators
+Description:
+   The /proc/$pid/audit_containerid pseudofile it written
+   to set and read to get the audit container identifier of
+   process $pid.  The accessor must have CAP_AUDIT_CONTROL
+   or have its own /proc/$pid/capcontainerid set to write
+   or read.
+
diff --git a/fs/proc/base.c b/fs/proc/base.c
index b3422cda2a91..bf447e7932d2 100644
--- a/fs/proc/base.c
+++ b/fs/proc/base.c
@@ -1244,7 +1244,7 @@ static const struct file_operations 
proc_oom_score_adj_operation

[PATCH ghak90 v11 01/11] audit: collect audit task parameters

2021-01-12 Thread Richard Guy Briggs
The audit-related parameters in struct task_struct should ideally be
collected together and accessed through a standard audit API and the audit
structures made opaque to other kernel subsystems.

Collect the existing loginuid, sessionid and audit_context together in a
new opaque 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.

Please see the upstream github issues
https://github.com/linux-audit/audit-kernel/issues/81
https://github.com/linux-audit/audit-kernel/issues/90

Signed-off-by: Richard Guy Briggs 
---
Acks removed due to significant code changes hiding audit task struct:
Acked-by: Neil Horman 
Reviewed-by: Ondrej Mosnacek 
---
 fs/io-wq.c|   8 +--
 fs/io_uring.c |  16 ++---
 include/linux/audit.h |  49 +-
 include/linux/sched.h |   7 +-
 init/init_task.c  |   3 +-
 init/main.c   |   2 +
 kernel/audit.c| 154 +-
 kernel/audit.h|   7 ++
 kernel/auditsc.c  |  24 ---
 kernel/fork.c |   1 -
 10 files changed, 205 insertions(+), 66 deletions(-)

diff --git a/fs/io-wq.c b/fs/io-wq.c
index a564f36e260c..0c57a20f4feb 100644
--- a/fs/io-wq.c
+++ b/fs/io-wq.c
@@ -499,8 +499,8 @@ static void io_impersonate_work(struct io_worker *worker,
current->signal->rlim[RLIMIT_FSIZE].rlim_cur = RLIM_INFINITY;
io_wq_switch_blkcg(worker, work);
 #ifdef CONFIG_AUDIT
-   current->loginuid = work->identity->loginuid;
-   current->sessionid = work->identity->sessionid;
+   audit_set_loginuid_iouring(work->identity->loginuid);
+   audit_set_sessionid_iouring(work->identity->sessionid);
 #endif
 }
 
@@ -515,8 +515,8 @@ static void io_assign_current_work(struct io_worker *worker,
}
 
 #ifdef CONFIG_AUDIT
-   current->loginuid = KUIDT_INIT(AUDIT_UID_UNSET);
-   current->sessionid = AUDIT_SID_UNSET;
+   audit_set_loginuid_iouring(KUIDT_INIT(AUDIT_UID_UNSET));
+   audit_set_sessionid_iouring(AUDIT_SID_UNSET);
 #endif
 
spin_lock_irq(>lock);
diff --git a/fs/io_uring.c b/fs/io_uring.c
index ca46f314640b..7aaff14d2859 100644
--- a/fs/io_uring.c
+++ b/fs/io_uring.c
@@ -1216,8 +1216,8 @@ static void io_init_identity(struct io_identity *id)
id->fs = current->fs;
id->fsize = rlimit(RLIMIT_FSIZE);
 #ifdef CONFIG_AUDIT
-   id->loginuid = current->loginuid;
-   id->sessionid = current->sessionid;
+   id->loginuid = audit_get_loginuid(current);
+   id->sessionid = audit_get_sessionid(current);
 #endif
refcount_set(>count, 1);
 }
@@ -1473,8 +1473,8 @@ static bool io_grab_identity(struct io_kiocb *req)
req->work.flags |= IO_WQ_WORK_CREDS;
}
 #ifdef CONFIG_AUDIT
-   if (!uid_eq(current->loginuid, id->loginuid) ||
-   current->sessionid != id->sessionid)
+   if (!uid_eq(audit_get_loginuid(current), id->loginuid) ||
+   audit_get_sessionid(current) != id->sessionid)
return false;
 #endif
if (!(req->work.flags & IO_WQ_WORK_FS) &&
@@ -7016,8 +7016,8 @@ static int io_sq_thread(void *data)
}
io_sq_thread_associate_blkcg(ctx, _css);
 #ifdef CONFIG_AUDIT
-   current->loginuid = ctx->loginuid;
-   current->sessionid = ctx->sessionid;
+   audit_set_loginuid_iouring(ctx->loginuid);
+   audit_set_sessionid_iouring(ctx->sessionid);
 #endif
 
ret = __io_sq_thread(ctx, cap_entries);
@@ -9528,8 +9528,8 @@ static int io_uring_create(unsigned entries, struct 
io_uring_params *p,
ctx->user = user;
ctx->creds = get_current_cred();
 #ifdef CONFIG_AUDIT
-   ctx->loginuid = current->loginuid;
-   ctx->sessionid = current->sessionid;
+   ctx->loginuid = audit_get_loginuid(current);
+   ctx->sessionid = audit_get_sessionid(current);
 #endif
ctx->sqo_task = get_task_struct(current);
 
diff --git a/include/linux/audit.h b/include/linux/audit.h
index 82b7c1116a85..515cc89a7e0c 100644
--- a/include/linux/audit.h
+++ b/include/linux/audit.h
@@ -154,6 +154,9 @@ struct filename;
 #ifdef CONFIG_AUDIT
 /* These are defined in audit.c */
/* Public API */
+extern int  audit_alloc(struct task_struct *task);
+extern void audit_free(struct task_struct *task);
+extern void __init audit_task_init(void);
 extern __printf(4, 5)
 void audit_log(struct audit_context *ctx, gfp_t gfp_mask, int type,
   const char *fmt, ...);
@@ -194,22 +197,26 @@ extern int audit_rule_change(int type, int seq, void 
*data, size_t datasz);
 extern int audit_list_rules_send(struct sk_buff *request_

[PATCH ghak90 v11 00/11] audit: implement container identifier

2021-01-12 Thread Richard Guy Briggs
dit_log_contid() handed contid rather than tsk
- switch from AUDIT_CONTAINER to AUDIT_CONTAINER_ID for aux record
- move audit_log_contid(tsk/contid) & 
audit_contid_set(tsk)/audit_contid_valid(contid)
- switch from tsk to current
- audit_alloc_local() calls audit_log_lost() on failure to allocate a context
- add AUDIT_USER* non-syscall contid record
- cosmetic cleanup double parens, goto out on err
- ditch audit_get_ns_contid_list_lock(), fix aunet lock race
- switch from all-cpu read spinlock to rcu, keep spinlock for write
- update audit_alloc_local() to use ktime_get_coarse_real_ts64()
- add nft_log support
- add call from do_exit() in audit_free() to remove contid from netns
- relegate AUDIT_CONTAINER ref= field (was op=) to debug patch

v4
- preface set with ghak81:"collect audit task parameters"
- add shallyn and sgrubb acks
- rename feature bitmap macro
- rename cid_valid() to audit_contid_valid()
- rename AUDIT_CONTAINER_ID to AUDIT_CONTAINER_OP
- delete audit_get_contid_list() from headers
- move work into inner if, delete "found"
- change netns contid list function names
- move exports for audit_log_contid audit_alloc_local audit_free_context to 
non-syscall patch
- list contids CSV
- pass in gfp flags to audit_alloc_local() (fix audit_alloc_context callers)
- use "local" in lieu of abusing in_syscall for auditsc_get_stamp()
- read_lock(_lock) around children and thread check
- task_lock(tsk) should be taken before first check of tsk->audit
- add spin lock to contid list in aunet
- restrict /proc read to CAP_AUDIT_CONTROL
- remove set again prohibition and inherited flag
- delete contidion spelling fix from patchset, send to netdev/linux-wireless

v3
- switched from containerid in task_struct to audit_task_info (depends on 
ghak81)
- drop INVALID_CID in favour of only AUDIT_CID_UNSET
- check for !audit_task_info, throw -ENOPROTOOPT on set
- changed -EPERM to -EEXIST for parent check
- return AUDIT_CID_UNSET if !audit_enabled
- squash child/thread check patch into AUDIT_CONTAINER_ID patch
- changed -EPERM to -EBUSY for child check
- separate child and thread checks, use -EALREADY for latter
- move addition of op= from ptrace/signal patch to AUDIT_CONTAINER patch
- fix && to || bashism in ptrace/signal patch
- uninline and export function for audit_free_context()
- drop CONFIG_CHANGE, FEATURE_CHANGE, ANOM_ABEND, ANOM_SECCOMP patches
- move audit_enabled check (xt_AUDIT)
- switched from containerid list in struct net to net_generic's struct audit_net
- move containerid list iteration into audit (xt_AUDIT)
- create function to move namespace switch into audit
- switched /proc/PID/ entry from containerid to audit_containerid
- call kzalloc with GFP_ATOMIC on in_atomic() in audit_alloc_context()
- call kzalloc with GFP_ATOMIC on in_atomic() in audit_log_container_info()
- use xt_net(par) instead of sock_net(skb->sk) to get net
- switched record and field names: initial CONTAINER_ID, aux CONTAINER, field 
CONTID
- allow to set own contid
- open code audit_set_containerid
- add contid inherited flag
- ccontainerid and pcontainerid eliminated due to inherited flag
- change name of container list funcitons
- rename containerid to contid
- convert initial container record to syscall aux
- fix spelling mistake of contidion in net/rfkill/core.c to avoid contid name 
collision

v2
- add check for children and threads
- add network namespace container identifier list
- add NETFILTER_PKT audit container identifier logging
- patch description and documentation clean-up and example
- reap unused ppid

Richard Guy Briggs (11):
  audit: collect audit task parameters
  audit: add container id
  audit: log container info of syscalls
  audit: add contid support for signalling the audit daemon
  audit: add support for non-syscall auxiliary records
  audit: add containerid support for user records
  audit: add containerid filtering
  audit: add support for containerid to network namespaces
  audit: contid check descendancy and nesting
  audit: track container nesting
  audit: add capcontid to set contid outside init_user_ns

 .../ABI/testing/procfs-audit_containerid  |  29 +
 fs/io-wq.c|   8 +-
 fs/io_uring.c |  16 +-
 fs/proc/base.c| 110 ++-
 include/linux/audit.h |  83 +-
 include/linux/sched.h |  10 +-
 include/uapi/linux/audit.h|  10 +-
 init/init_task.c  |   3 +-
 init/main.c   |   2 +
 kernel/audit.c| 878 +-
 kernel/audit.h|  19 +
 kernel/auditfilter.c  |  46 +
 kernel/auditsc.c  | 109 ++-
 kernel/fork.c |   1 -
 kernel/nsproxy.c  |   4 +
 kernel/

Re: [PATCH ghak90 v10 01/11] audit: collect audit task parameters

2020-12-21 Thread Richard Guy Briggs
On 2020-12-21 12:14, Paul Moore wrote:
> On Mon, Dec 21, 2020 at 11:57 AM Richard Guy Briggs  wrote:
> >
> > The audit-related parameters in struct task_struct should ideally be
> > collected together and accessed through a standard audit API and the audit
> > structures made opaque to other kernel subsystems.
> >
> > Collect the existing loginuid, sessionid and audit_context together in a
> > new opaque 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.
> >
> > Please see the upstream github issues
> > https://github.com/linux-audit/audit-kernel/issues/81
> > https://github.com/linux-audit/audit-kernel/issues/90
> >
> > Signed-off-by: Richard Guy Briggs 
> > Acked-by: Neil Horman 
> > Reviewed-by: Ondrej Mosnacek 
> 
> Did Neil and Ondrej really ACK/Review the changes that you made here
> in v10 or are you just carrying over the ACK/Review?  I'm hopeful it
> is the former, because I'm going to be a little upset if it is the
> latter.

It is the latter, sorry.  So, this needs to be reposted without their
ACK/Review lines.

> > ---
> >  fs/io-wq.c|   8 +--
> >  fs/io_uring.c |  16 ++---
> >  include/linux/audit.h |  49 +-
> >  include/linux/sched.h |   7 +-
> >  init/init_task.c  |   3 +-
> >  init/main.c   |   2 +
> >  kernel/audit.c| 154 +-
> >  kernel/audit.h|   7 ++
> >  kernel/auditsc.c  |  24 ---
> >  kernel/fork.c |   1 -
> >  10 files changed, 205 insertions(+), 66 deletions(-)
> 
> -- 
> paul moore
> www.paul-moore.com
> 

- RGB

--
Richard Guy Briggs 
Sr. S/W Engineer, Kernel Security, Base Operating Systems
Remote, Ottawa, Red Hat Canada
IRC: rgb, SunRaycer
Voice: +1.647.777.2635, Internal: (81) 32635



[PATCH ghau51/ghau40 v10 01/11] AUDIT_CONTAINER_OP message type basic support

2020-12-21 Thread Richard Guy Briggs
This defines the message number for the audit container identifier
registration record should the kernel headers not be up to date, gives
the record number a name for printing and allows the record to be
interpreted since it is in the 1000 range like AUDIT_LOGIN.

See: https://github.com/linux-audit/audit-userspace/issues/51
See: https://github.com/linux-audit/audit-kernel/issues/90
See: https://github.com/linux-audit/audit-testsuite/issues/64
See: https://github.com/linux-audit/audit-kernel/wiki/RFE-Audit-Container-ID
Signed-off-by: Richard Guy Briggs 
---
 lib/libaudit.h | 4 
 lib/msg_typetab.h  | 1 +
 lib/netlink.c  | 1 +
 src/ausearch-lol.c | 2 ++
 4 files changed, 8 insertions(+)

diff --git a/lib/libaudit.h b/lib/libaudit.h
index 3a8e8c854fed..7fe56f4c8b22 100644
--- a/lib/libaudit.h
+++ b/lib/libaudit.h
@@ -247,6 +247,10 @@ extern "C" {
 #define AUDIT_GET_FEATURE   1019/* Get which features are enabled */
 #endif
 
+#ifndef AUDIT_CONTAINER_OP
+#define AUDIT_CONTAINER_OP 1020/* Container creation notice */
+#endif
+
 #ifndef AUDIT_MMAP
 #define AUDIT_MMAP 1323 /* Descriptor and flags in mmap */
 #endif
diff --git a/lib/msg_typetab.h b/lib/msg_typetab.h
index 4dff2e9c4d40..376e121e1278 100644
--- a/lib/msg_typetab.h
+++ b/lib/msg_typetab.h
@@ -44,6 +44,7 @@ _S(AUDIT_LOGIN,  "LOGIN"  
   )
 //_S(AUDIT_TTY_SET,"TTY_SET"   )
 //_S(AUDIT_SET_FEATURE,"SET_FEATURE"   )
 //_S(AUDIT_GET_FEATURE,"GET_FEATURE"   )
+_S(AUDIT_CONTAINER_OP,   "CONTAINER_OP"  )
 _S(AUDIT_USER_AUTH,  "USER_AUTH" )
 _S(AUDIT_USER_ACCT,  "USER_ACCT" )
 _S(AUDIT_USER_MGMT,  "USER_MGMT" )
diff --git a/lib/netlink.c b/lib/netlink.c
index 9525b8d833c0..d660b8f37c79 100644
--- a/lib/netlink.c
+++ b/lib/netlink.c
@@ -182,6 +182,7 @@ static int adjust_reply(struct audit_reply *rep, int len)
break;
case AUDIT_USER:
case AUDIT_LOGIN:
+   case AUDIT_CONTAINER_OP:
case AUDIT_KERNEL:
case AUDIT_FIRST_USER_MSG...AUDIT_LAST_USER_MSG:
case AUDIT_FIRST_USER_MSG2...AUDIT_LAST_USER_MSG2:
diff --git a/src/ausearch-lol.c b/src/ausearch-lol.c
index f0f36e04dd93..05fe80fe3ad6 100644
--- a/src/ausearch-lol.c
+++ b/src/ausearch-lol.c
@@ -248,6 +248,8 @@ static void check_events(lol *lo, time_t sec)
ready++;
} else if ( cur->l->e.type <  AUDIT_LOGIN||
   (cur->l->e.type >  AUDIT_LOGIN   &&
+   cur->l->e.type <  AUDIT_CONTAINER_OP   ) ||
+  (cur->l->e.type >  AUDIT_CONTAINER_OP&&
cur->l->e.type <  AUDIT_FIRST_EVENT) ||
cur->l->e.type == AUDIT_PROCTITLE||
   (cur->l->e.type >= AUDIT_MAC_UNLBL_ALLOW &&
-- 
2.18.4



[PATCH ghau51/ghau40 v10 11/11] libaudit: add support to get and set capcontid on a task

2020-12-21 Thread Richard Guy Briggs
Add support to be able to set a capability to allow a task to set the
audit container identifier of descendants.

See: https://github.com/linux-audit/audit-userspace/issues/51
See: https://github.com/linux-audit/audit-kernel/issues/90
See: https://github.com/linux-audit/audit-testsuite/issues/64
See: https://github.com/linux-audit/audit-kernel/wiki/RFE-Audit-Container-ID

Add the audit_get_capcontid() and audit_set_capcontid() calls analogous
to CAP_AUDIT_CONTROL for descendant user namespaces.

Signed-off-by: Richard Guy Briggs 
---
 auparse/normalize.c|  1 +
 auparse/normalize_record_map.h |  1 +
 docs/Makefile.am   |  1 +
 docs/audit_get_capcontid.3 | 25 +
 docs/audit_set_capcontid.3 | 24 
 lib/libaudit.c | 68 ++
 lib/libaudit.h |  4 ++
 lib/msg_typetab.h  |  1 +
 lib/netlink.c  |  1 +
 src/ausearch-lol.c |  2 +
 src/ausearch-parse.c   |  1 +
 11 files changed, 129 insertions(+)
 create mode 100644 docs/audit_get_capcontid.3
 create mode 100644 docs/audit_set_capcontid.3

diff --git a/auparse/normalize.c b/auparse/normalize.c
index 2d7878ce9ba9..8bcfce280d1a 100644
--- a/auparse/normalize.c
+++ b/auparse/normalize.c
@@ -911,6 +911,7 @@ static const char *normalize_determine_evkind(int type)
case AUDIT_FEATURE_CHANGE ... AUDIT_REPLACE:
case AUDIT_USER_DEVICE:
case AUDIT_SOFTWARE_UPDATE:
+   case AUDIT_SET_CAPCONTID:
kind = NORM_EVTYPE_CONFIG;
break;
case AUDIT_SECCOMP:
diff --git a/auparse/normalize_record_map.h b/auparse/normalize_record_map.h
index 1bb4c9ac6a95..cb8fc55c0e5e 100644
--- a/auparse/normalize_record_map.h
+++ b/auparse/normalize_record_map.h
@@ -26,6 +26,7 @@
 _S(AUDIT_USER, "sent-message")
 _S(AUDIT_LOGIN, "changed-login-id-to")
 _S(AUDIT_CONTAINER_OP, "changed-container-id-to")
+_S(AUDIT_SET_CAPCONTID, "set-capcontid-to")
 _S(AUDIT_USER_AUTH, "authenticated")
 _S(AUDIT_USER_ACCT, "was-authorized")
 _S(AUDIT_USER_MGMT, "modified-user-account")
diff --git a/docs/Makefile.am b/docs/Makefile.am
index 209789bb2051..6b981b296d0c 100644
--- a/docs/Makefile.am
+++ b/docs/Makefile.am
@@ -29,6 +29,7 @@ auditd.conf.5 auditd-plugins.5 \
 audit_delete_rule_data.3 audit_detect_machine.3 \
 audit_encode_nv_string.3 audit_getloginuid.3 \
 audit_get_reply.3 audit_get_session.3 audit_get_containerid.3 \
+audit_get_capcontid.3 audit_set_capcontid.3 \
 audit_log_acct_message.3 audit_log_user_avc_message.3 \
 audit_log_user_command.3 audit_log_user_comm_message.3 \
 audit_log_user_message.3 audit_log_semanage_message.3 \
diff --git a/docs/audit_get_capcontid.3 b/docs/audit_get_capcontid.3
new file mode 100644
index ..652a4960a020
--- /dev/null
+++ b/docs/audit_get_capcontid.3
@@ -0,0 +1,25 @@
+.TH "AUDIT_GET_CAPCONTID" "26" "Aug 2019" "Red Hat" "Linux Audit API"
+.SH NAME
+audit_get_capcontid \- Get a program's capability container id value
+.SH SYNOPSIS
+.B #include 
+.sp
+int audit_get_capcontid(pid_t pid);
+
+.SH DESCRIPTION
+This function returns the pid task's audit capability container identifier 
attribute.
+
+.SH "RETURN VALUE"
+
+This function returns the audit capability container identifier value if it is 
implemented. It will return a \-1 if the audit capability container identifier 
is unavailable.
+
+.SH "ERRORS"
+
+This function returns \-2 on failure. Additionally, in the event of a real 
error, errno would be set. The function can set errno based on failures of 
open, read, or strtoull.
+
+.SH "SEE ALSO"
+
+.BR audit_set_capcontid (3).
+
+.SH AUTHOR
+Richard Guy Briggs
diff --git a/docs/audit_set_capcontid.3 b/docs/audit_set_capcontid.3
new file mode 100644
index ..70ac8c7a4e95
--- /dev/null
+++ b/docs/audit_set_capcontid.3
@@ -0,0 +1,24 @@
+.TH "AUDIT_SET_CAPCONTID" "26" "Aug 2019" "Red Hat" "Linux Audit API"
+.SH NAME
+audit_set_capcontid \- Set a program's capability container id value
+.SH SYNOPSIS
+.B #include 
+.sp
+int audit_set_capcontid(pid_t pid, uint32_t capcontid);
+
+.SH "DESCRIPTION"
+
+This function sets the pid task's attribute capability container id with the 
value of capcontid. The capcontid value may only be set by programs with the 
CAP_AUDIT_CONTROL capability in the initial user namespace or with capcontid. 
This normally means the root account or root in a container.
+.sp
+The capcontid value is part of the task structure and is inheritted by child 
processes within a user namespace. It is used to enable the capability to set 
container identifier of a child task in a descendent user namespace.  Container 
orchestrator/engines should set this va

[PATCH ghau51/ghau40 v10 09/11] contid: interpret correctly CONTAINER_ID contid field csv

2020-12-21 Thread Richard Guy Briggs
The CONTAINER_ID record contid field can contain comma-separated values
when accompanying a NETFILTER_PKT record.  Records appeared interpreted
as such:

Wrong:
CONTAINER_ID msg=audit(2019-04-10 13:20:18.746:1690) : contid=777 
666,333
Right:
CONTAINER_ID msg=audit(2019-04-10 13:20:18.746:1690) : 
contid=777,666,333

Signed-off-by: Richard Guy Briggs 
---
 src/ausearch-report.c | 6 --
 1 file changed, 4 insertions(+), 2 deletions(-)

diff --git a/src/ausearch-report.c b/src/ausearch-report.c
index 416c2b13fa6a..754b28af2cb6 100644
--- a/src/ausearch-report.c
+++ b/src/ausearch-report.c
@@ -279,7 +279,7 @@ no_print:
if (str && val && (str < val)) {
// Value side  has commas and another field exists
// Known: LABEL_LEVEL_CHANGE banners=none,none
-   // Known: ROLL_ASSIGN new-role=r,r
+   // Known: ROLE_ASSIGN new-role=r,r
// Known: any MAC LABEL can potentially have commas
int ftype = auparse_interp_adjust_type(n->type,
name, val);
@@ -293,9 +293,11 @@ no_print:
} else if (str && (val == NULL)) {
// Goes all the way to the end. Done parsing
// Known: MCS context in PATH rec obj=u:r:t:s0:c2,c7
+   // Known: CONTAINER_ID/OP old-/contid can be a 
comma-separated list
int ftype = auparse_interp_adjust_type(n->type,
name, ptr);
-   if (ftype == AUPARSE_TYPE_MAC_LABEL)
+   if (ftype == AUPARSE_TYPE_MAC_LABEL
+   || ftype == AUPARSE_TYPE_CONTID)
str = NULL;
else {
*str++ = 0;
-- 
2.18.4



[PATCH ghau51/ghau40 v10 10/11] ausearch: convert contid to comma-sep/carrat-mod cnode/clist

2020-12-21 Thread Richard Guy Briggs
Now that the kernel is able to track container nesting ("audit: track
container nesting"), convert the ausearch internals to parse and track
the compound list of contids stored in their native u64 format for
faster and more efficient processing.

Signed-off-by: Richard Guy Briggs 
---
 src/Makefile.am|   6 +-
 src/aureport-options.c |   3 +-
 src/ausearch-contid.c  | 172 +
 src/ausearch-contid.h  |  60 ++
 src/ausearch-llist.c   |   8 +-
 src/ausearch-llist.h   |   3 +-
 src/ausearch-match.c   |  36 -
 src/ausearch-options.c |  36 -
 src/ausearch-options.h |   3 +-
 src/ausearch-parse.c   | 110 --
 10 files changed, 402 insertions(+), 35 deletions(-)
 create mode 100644 src/ausearch-contid.c
 create mode 100644 src/ausearch-contid.h

diff --git a/src/Makefile.am b/src/Makefile.am
index fda612b1ccb0..91c29cfbe52e 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -25,7 +25,7 @@ SUBDIRS = test
 AM_CPPFLAGS = -I${top_srcdir} -I${top_srcdir}/lib -I${top_srcdir}/src/libev 
-I${top_srcdir}/auparse -I${top_srcdir}/audisp -I${top_srcdir}/common
 sbin_PROGRAMS = auditd auditctl aureport ausearch autrace
 AM_CFLAGS = -D_GNU_SOURCE -Wno-pointer-sign
-noinst_HEADERS = auditd-config.h auditd-event.h auditd-listen.h 
ausearch-llist.h ausearch-options.h auditctl-llist.h aureport-options.h 
ausearch-parse.h aureport-scan.h ausearch-lookup.h ausearch-int.h 
auditd-dispatch.h ausearch-string.h ausearch-nvpair.h ausearch-common.h 
ausearch-avc.h ausearch-time.h ausearch-lol.h auditctl-listing.h 
ausearch-checkpt.h
+noinst_HEADERS = auditd-config.h auditd-event.h auditd-listen.h 
ausearch-llist.h ausearch-options.h auditctl-llist.h aureport-options.h 
ausearch-parse.h aureport-scan.h ausearch-lookup.h ausearch-int.h 
auditd-dispatch.h ausearch-string.h ausearch-nvpair.h ausearch-common.h 
ausearch-avc.h ausearch-time.h ausearch-lol.h auditctl-listing.h 
ausearch-checkpt.h ausearch-contid.h
 
 auditd_SOURCES = auditd.c auditd-event.c auditd-config.c auditd-reconfig.c 
auditd-sendmail.c auditd-dispatch.c
 if ENABLE_LISTENER
@@ -41,10 +41,10 @@ auditctl_CFLAGS = -fPIE -DPIE -g -D_GNU_SOURCE
 auditctl_LDFLAGS = -pie -Wl,-z,relro -Wl,-z,now
 auditctl_LDADD = -L${top_builddir}/lib -laudit -L${top_builddir}/auparse 
-lauparse -L${top_builddir}/common -laucommon
 
-aureport_SOURCES = aureport.c auditd-config.c ausearch-llist.c 
aureport-options.c ausearch-string.c ausearch-parse.c aureport-scan.c 
aureport-output.c ausearch-lookup.c ausearch-int.c ausearch-time.c 
ausearch-nvpair.c ausearch-avc.c ausearch-lol.c
+aureport_SOURCES = aureport.c auditd-config.c ausearch-llist.c 
aureport-options.c ausearch-string.c ausearch-parse.c aureport-scan.c 
aureport-output.c ausearch-lookup.c ausearch-int.c ausearch-time.c 
ausearch-nvpair.c ausearch-avc.c ausearch-lol.c ausearch-contid.c
 aureport_LDADD = -L${top_builddir}/lib -laudit -L${top_builddir}/auparse 
-lauparse -L${top_builddir}/common -laucommon
 
-ausearch_SOURCES = ausearch.c auditd-config.c ausearch-llist.c 
ausearch-options.c ausearch-report.c ausearch-match.c ausearch-string.c 
ausearch-parse.c ausearch-int.c ausearch-time.c ausearch-nvpair.c 
ausearch-lookup.c ausearch-avc.c ausearch-lol.c ausearch-checkpt.c
+ausearch_SOURCES = ausearch.c auditd-config.c ausearch-llist.c 
ausearch-options.c ausearch-report.c ausearch-match.c ausearch-string.c 
ausearch-parse.c ausearch-int.c ausearch-time.c ausearch-nvpair.c 
ausearch-lookup.c ausearch-avc.c ausearch-lol.c ausearch-checkpt.c 
ausearch-contid.c
 ausearch_LDADD = -L${top_builddir}/lib -laudit -L${top_builddir}/auparse 
-lauparse -L${top_builddir}/common -laucommon
 
 autrace_SOURCES = autrace.c delete_all.c auditctl-llist.c
diff --git a/src/aureport-options.c b/src/aureport-options.c
index 29d267f2d1cb..0aa742c9a1fe 100644
--- a/src/aureport-options.c
+++ b/src/aureport-options.c
@@ -36,6 +36,7 @@
 #include "ausearch-time.h"
 #include "libaudit.h"
 #include "auparse-defs.h"
+#include "ausearch-contid.h"
 
 
 /* Global vars that will be accessed by the main program */
@@ -62,7 +63,7 @@ const char *event_vmname = NULL;
 long long event_exit = 0;
 int event_exit_is_set = 0;
 int event_ppid = -1, event_session_id = -2;
-unsigned long long event_contid = -1;
+clist *event_contid = NULL;
 int event_debug = 0, event_machine = -1;
 
 /* These are used by aureport */
diff --git a/src/ausearch-contid.c b/src/ausearch-contid.c
new file mode 100644
index ..87a94497ced1
--- /dev/null
+++ b/src/ausearch-contid.c
@@ -0,0 +1,172 @@
+/*
+ * ausearch-contid.c - Minimal linked list library for contid
+ * adapted from ausearch-string.c
+ * Copyright (c) 2005,2008,2014,2019 Red Hat Inc., Durham, North Carolina.
+ * All Rights Reserved.
+ *
+ * This software may be freely redistributed and/or modified under the
+ * terms of the GNU General Public License as published by the Free
+ * 

[PATCH ghau51/ghau40 v10 04/11] add ausearch containerid support

2020-12-21 Thread Richard Guy Briggs
Add support to ausearch for searching on the containerid field in
records.

Signed-off-by: Richard Guy Briggs 
---
 src/aureport-options.c |  1 +
 src/ausearch-llist.c   |  2 ++
 src/ausearch-llist.h   |  1 +
 src/ausearch-match.c   |  3 +++
 src/ausearch-options.c | 48 ++-
 src/ausearch-options.h |  1 +
 src/ausearch-parse.c   | 57 ++
 7 files changed, 112 insertions(+), 1 deletion(-)

diff --git a/src/aureport-options.c b/src/aureport-options.c
index bd847d7d57f0..29d267f2d1cb 100644
--- a/src/aureport-options.c
+++ b/src/aureport-options.c
@@ -62,6 +62,7 @@ const char *event_vmname = NULL;
 long long event_exit = 0;
 int event_exit_is_set = 0;
 int event_ppid = -1, event_session_id = -2;
+unsigned long long event_contid = -1;
 int event_debug = 0, event_machine = -1;
 
 /* These are used by aureport */
diff --git a/src/ausearch-llist.c b/src/ausearch-llist.c
index ef5503c34fd9..ade727a9e102 100644
--- a/src/ausearch-llist.c
+++ b/src/ausearch-llist.c
@@ -60,6 +60,7 @@ void list_create(llist *l)
l->s.arch = 0;
l->s.syscall = 0;
l->s.session_id = -2;
+   l->s.contid = -1;
l->s.uuid = NULL;
l->s.vmname = NULL;
l->s.tuid = NULL;
@@ -211,6 +212,7 @@ void list_clear(llist* l)
l->s.arch = 0;
l->s.syscall = 0;
l->s.session_id = -2;
+   l->s.contid = -1;
free(l->s.uuid);
l->s.uuid = NULL;
free(l->s.vmname);
diff --git a/src/ausearch-llist.h b/src/ausearch-llist.h
index 64e4ee1f3694..2d1f52237ce6 100644
--- a/src/ausearch-llist.h
+++ b/src/ausearch-llist.h
@@ -56,6 +56,7 @@ typedef struct
   int arch; // arch
   int syscall;  // syscall
   uint32_t session_id;  // Login session id
+  __u64 contid; // Container id
   long long exit;   // Syscall exit code
   int exit_is_set;  // Syscall exit code is valid
   char *hostname;   // remote hostname
diff --git a/src/ausearch-match.c b/src/ausearch-match.c
index 61a11d30a09b..47c12581a963 100644
--- a/src/ausearch-match.c
+++ b/src/ausearch-match.c
@@ -113,6 +113,9 @@ int match(llist *l)
if ((event_session_id != -2) &&
(event_session_id != l->s.session_id))
return 0;
+   if ((event_contid != -1) &&
+   (event_contid != l->s.contid))
+   return 0;
if (event_exit_is_set) {
if (l->s.exit_is_set == 0)
return 0;
diff --git a/src/ausearch-options.c b/src/ausearch-options.c
index 5363fdace73c..b45793e88109 100644
--- a/src/ausearch-options.c
+++ b/src/ausearch-options.c
@@ -60,6 +60,7 @@ int event_syscall = -1, event_machine = -1;
 int event_ua = 0, event_ga = 0, event_se = 0;
 int just_one = 0;
 uint32_t event_session_id = -2;
+unsigned long long event_contid = -1;
 long long event_exit = 0;
 int event_exit_is_set = 0;
 int line_buffered = 0;
@@ -92,7 +93,7 @@ S_TIME_END, S_TIME_START, S_TERMINAL, S_ALL_UID, S_EFF_UID, 
S_UID, S_LOGINID,
 S_VERSION, S_EXACT_MATCH, S_EXECUTABLE, S_CONTEXT, S_SUBJECT, S_OBJECT,
 S_PPID, S_KEY, S_RAW, S_NODE, S_IN_LOGS, S_JUST_ONE, S_SESSION, S_EXIT,
 S_LINEBUFFERED, S_UUID, S_VMNAME, S_DEBUG, S_CHECKPOINT, S_ARCH, S_FORMAT,
-S_EXTRA_TIME, S_EXTRA_LABELS, S_EXTRA_KEYS, S_EXTRA_OBJ2, S_ESCAPE };
+S_EXTRA_TIME, S_EXTRA_LABELS, S_EXTRA_KEYS, S_EXTRA_OBJ2, S_ESCAPE, S_CONTID };
 
 static struct nv_pair optiontab[] = {
{ S_EVENT, "-a" },
@@ -100,6 +101,7 @@ static struct nv_pair optiontab[] = {
{ S_EVENT, "--event" },
{ S_COMM, "-c" },
{ S_COMM, "--comm" },
+   { S_CONTID, "--contid" },
{ S_CHECKPOINT, "--checkpoint" },
{ S_DEBUG, "--debug" },
{ S_EXIT, "-e" },
@@ -197,6 +199,7 @@ static void usage(void)
"\t-a,--event \tsearch based on audit event id\n"
"\t--arch \t\t\tsearch based on the CPU architecture\n"
"\t-c,--comm  \t\tsearch based on command line name\n"
+   "\t--contid \tsearch based on the task's audit 
container id\n"
"\t--checkpoint \tsearch from last complete event\n"
"\t--debug\t\t\tWrite malformed events that are skipped to stderr\n"
"\t-e,--exit  \tsearch based on syscall exit code\n"
@@ -1182,6 +1185,49 @@ int check_params(int count, char *vars[])
}
c++;
break;
+   case S_CONTID:
+   if (!optarg) {
+   if ((c+1 < count) && vars[c+

[PATCH ghau51/ghau40 v10 08/11] add support for audit_signal_info2

2020-12-21 Thread Richard Guy Briggs
Since a process in a container could potentially signal the audit daemon
(reconfig, terminate, roll log, resume), that audit container identifier
information should be made available to the audit daemon to report the
full provenance of the signal.  It is not possible to add it to the
existing audit_signal_info struct without causing a kABI change.
Introduce a new audit message type AUDIT_SIGNAL_INFO2 using a new
audit_sig_info2 struct to be able to transfer this information from
kernel to userspace.

struct audit_sig_info2 {
   uid_t   uid;
   pid_t   pid;
   uint64_tcid;
   charctx[];
};

Signed-off-by: Richard Guy Briggs 
---
 auparse/auditd-config.c  |  1 +
 docs/audit_request_signal_info.3 | 15 -
 lib/libaudit.c   | 56 +++-
 lib/libaudit.h   | 16 -
 lib/msg_typetab.h|  1 +
 lib/netlink.c|  4 +++
 src/auditd-config.c  |  1 +
 src/auditd-config.h  |  1 +
 src/auditd-event.c   | 10 +-
 src/auditd-reconfig.c| 25 ++
 src/auditd.c |  4 ++-
 11 files changed, 116 insertions(+), 18 deletions(-)

diff --git a/auparse/auditd-config.c b/auparse/auditd-config.c
index 59984b47bd5a..7a3ed33ffb4b 100644
--- a/auparse/auditd-config.c
+++ b/auparse/auditd-config.c
@@ -77,6 +77,7 @@ void clear_config(struct daemon_conf *config)
config->sender_uid = 0;
config->sender_pid = 0;
config->sender_ctx = NULL;
+   config->sender_cid = NULL;
config->write_logs = 1;
config->log_file = strdup("/var/log/audit/audit.log");
config->log_format = LF_RAW;
diff --git a/docs/audit_request_signal_info.3 b/docs/audit_request_signal_info.3
index b68d7bbefeed..90c5da5bcf7d 100644
--- a/docs/audit_request_signal_info.3
+++ b/docs/audit_request_signal_info.3
@@ -14,10 +14,23 @@ audit_request_signal_info requests that the kernel send 
information about the se
 struct audit_sig_info {
 uid_t   uid;
 pid_t   pid;
-charctx[0];
+charctx[];
 };
 .fi
 
+If the process has an audit container identifier, the signal info structure is 
as follows:
+
+.nf
+struct audit_sig_info2 {
+uid_t   uid;
+pid_t   pid;
+uint32_tcid_len;
+chardata[];
+};
+.fi
+
+The data field contains first the audit container identifier list of length 
cid_len, followed by the SElinux context to the end of the structure.
+
 This function is likely to be used only by audit daemons and shouldn't be 
called by any other kind of program.
 
 .SH "RETURN VALUE"
diff --git a/lib/libaudit.c b/lib/libaudit.c
index 43c166fabbd8..1d5375b256c3 100644
--- a/lib/libaudit.c
+++ b/lib/libaudit.c
@@ -25,6 +25,7 @@
 #include "config.h"
 #include 
 #include 
+#include 
 #include 
 #include 
 #include 
@@ -683,7 +684,12 @@ int audit_request_rules_list_data(int fd)
 
 int audit_request_signal_info(int fd)
 {
-   int rc = audit_send(fd, AUDIT_SIGNAL_INFO, NULL, 0);
+   int rc;
+
+   if (audit_get_containerid() == (uint64_t)-2)
+   rc = audit_send(fd, AUDIT_SIGNAL_INFO, NULL, 0);
+   else
+   rc = audit_send(fd, AUDIT_SIGNAL_INFO2, NULL, 0);
if (rc < 0)
audit_msg(LOG_WARNING,
"Error sending signal_info request (%s)",
@@ -691,16 +697,50 @@ int audit_request_signal_info(int fd)
return rc;
 }
 
+bool audit_signal_info_has_ctx(struct audit_reply *rep)
+{
+   if (rep->type == AUDIT_SIGNAL_INFO) {
+   if (rep->len == 24)
+   return false;
+   } else {
+   if (rep->len == 24 + sizeof(uint32_t) + 
rep->signal_info2->cid_len)
+   return false;
+   }
+   return true;
+}
+
+#ifndef MIN
+#define MIN(a, b) (((a) <= (b)) ? (a) : (b))
+#endif
 char *audit_format_signal_info(char *buf, int len, char *op,
   struct audit_reply *rep, char *res)
 {
-   if (rep->len == 24)
-   snprintf(buf, len, "op=%s auid=%u pid=%d res=%s", op,
-   rep->signal_info->uid, rep->signal_info->pid, res);
-   else
-   snprintf(buf, len, "op=%s auid=%u pid=%d subj=%s res=%s",
-   op, rep->signal_info->uid, rep->signal_info->pid,
-   rep->signal_info->ctx, res);
+   int c = 0;
+
+   if (rep->type == AUDIT_SIGNAL_INFO) {
+   c += snprintf(buf + c, len - c, "op=%s auid=%u pid=%d",
+ op,
+ rep->signal_info->uid,
+ rep->signal_info->pid);
+   if 

[PATCH ghau51/ghau40 v10 05/11] start normalization containerid support

2020-12-21 Thread Richard Guy Briggs
Signed-off-by: Richard Guy Briggs 
---
 auparse/auparse-defs.h   |  3 ++-
 auparse/interpret.c  | 10 ++
 auparse/normalize_record_map.h   |  2 ++
 auparse/typetab.h|  2 ++
 bindings/python/auparse_python.c |  1 +
 5 files changed, 17 insertions(+), 1 deletion(-)

diff --git a/auparse/auparse-defs.h b/auparse/auparse-defs.h
index 27bfa943612c..a9b144df3462 100644
--- a/auparse/auparse-defs.h
+++ b/auparse/auparse-defs.h
@@ -87,7 +87,8 @@ typedef enum {  AUPARSE_TYPE_UNCLASSIFIED,  AUPARSE_TYPE_UID, 
AUPARSE_TYPE_GID,
AUPARSE_TYPE_PROCTITLE, AUPARSE_TYPE_HOOK,
AUPARSE_TYPE_NETACTION, AUPARSE_TYPE_MACPROTO,
AUPARSE_TYPE_IOCTL_REQ, AUPARSE_TYPE_ESCAPED_KEY,
-   AUPARSE_TYPE_ESCAPED_FILE, AUPARSE_TYPE_FANOTIFY } auparse_type_t;
+   AUPARSE_TYPE_ESCAPED_FILE, AUPARSE_TYPE_FANOTIFY, AUPARSE_TYPE_CONTID
+} auparse_type_t;
 
 /* This type determines what escaping if any gets applied to interpreted 
fields */
 typedef enum { AUPARSE_ESC_RAW, AUPARSE_ESC_TTY, AUPARSE_ESC_SHELL,
diff --git a/auparse/interpret.c b/auparse/interpret.c
index e23c3533877b..14fcc72148c8 100644
--- a/auparse/interpret.c
+++ b/auparse/interpret.c
@@ -2843,6 +2843,13 @@ static const char *print_seccomp_code(const char *val)
return out;
 }
 
+static const char *print_contid(const char *val)
+{
+   if (strcmp(val, "18446744073709551615") == 0 || strcmp(val, "-1") == 0)
+   return strdup("unset");
+   return strdup(val);
+}
+
 int lookup_type(const char *name)
 {
int i;
@@ -3083,6 +3090,9 @@ unknown:
case AUPARSE_TYPE_FANOTIFY:
out = print_fanotify(id->val);
break;
+   case AUPARSE_TYPE_CONTID:
+   out = print_contid(id->val);
+   break;
case AUPARSE_TYPE_MAC_LABEL:
case AUPARSE_TYPE_UNCLASSIFIED:
default:
diff --git a/auparse/normalize_record_map.h b/auparse/normalize_record_map.h
index c2d76e406b0f..1bb4c9ac6a95 100644
--- a/auparse/normalize_record_map.h
+++ b/auparse/normalize_record_map.h
@@ -25,6 +25,7 @@
 
 _S(AUDIT_USER, "sent-message")
 _S(AUDIT_LOGIN, "changed-login-id-to")
+_S(AUDIT_CONTAINER_OP, "changed-container-id-to")
 _S(AUDIT_USER_AUTH, "authenticated")
 _S(AUDIT_USER_ACCT, "was-authorized")
 _S(AUDIT_USER_MGMT, "modified-user-account")
@@ -84,6 +85,7 @@ _S(AUDIT_FEATURE_CHANGE, "changed-audit-feature")
 //_S(AUDIT_REPLACE,"")
 _S(AUDIT_KERN_MODULE, "loaded-kernel-module")
 _S(AUDIT_FANOTIFY, "accessed-policy-controlled-file")
+_S(AUDIT_CONTAINER_ID, "has-container-id")
 _S(AUDIT_AVC, "accessed-mac-policy-controlled-object")
 _S(AUDIT_MAC_POLICY_LOAD, "loaded-selinux-policy")
 _S(AUDIT_MAC_STATUS, "changed-selinux-enforcement-to")
diff --git a/auparse/typetab.h b/auparse/typetab.h
index 0391e87f731c..0c160bb56c3b 100644
--- a/auparse/typetab.h
+++ b/auparse/typetab.h
@@ -142,3 +142,5 @@ _S(AUPARSE_TYPE_IOCTL_REQ,  "ioctlcmd"  )
 _S(AUPARSE_TYPE_FANOTIFY,  "resp"  )
 _S(AUPARSE_TYPE_ESCAPED,   "sw")
 _S(AUPARSE_TYPE_ESCAPED,   "root_dir"  )
+_S(AUPARSE_TYPE_CONTID,"contid")
+_S(AUPARSE_TYPE_CONTID,"old-contid")
diff --git a/bindings/python/auparse_python.c b/bindings/python/auparse_python.c
index 1ba59cf78527..947d018cf594 100644
--- a/bindings/python/auparse_python.c
+++ b/bindings/python/auparse_python.c
@@ -2376,6 +2376,7 @@ initauparse(void)
 PyModule_AddIntConstant(m, "AUPARSE_ESC_TTY", AUPARSE_ESC_TTY);
 PyModule_AddIntConstant(m, "AUPARSE_ESC_SHELL", AUPARSE_ESC_SHELL);
 PyModule_AddIntConstant(m, "AUPARSE_ESC_SHELL_QUOTE", 
AUPARSE_ESC_SHELL_QUOTE);
+PyModule_AddIntConstant(m, "AUPARSE_TYPE_CONTID", AUPARSE_TYPE_CONTID);
 
 #ifdef IS_PY3K
 return m;
-- 
2.18.4



[PATCH ghau51/ghau40 v10 06/11] libaudit: add support to get the task audit container identifier

2020-12-21 Thread Richard Guy Briggs
Add the audit_get_containerid() call analogous to audit_getloginuid()
and audit_get_session() calls to get our own audit container identifier.

This is intended as a debug patch, not to be upstreamed.

Signed-off-by: Richard Guy Briggs 
---
 docs/Makefile.am |  2 +-
 docs/audit_get_containerid.3 | 25 +
 lib/libaudit.c   | 29 +
 lib/libaudit.h   |  1 +
 4 files changed, 56 insertions(+), 1 deletion(-)
 create mode 100644 docs/audit_get_containerid.3

diff --git a/docs/Makefile.am b/docs/Makefile.am
index 8fb030c6e5e4..209789bb2051 100644
--- a/docs/Makefile.am
+++ b/docs/Makefile.am
@@ -28,7 +28,7 @@ man_MANS = audit_add_rule_data.3 audit_add_watch.3 auditctl.8 
auditd.8 \
 auditd.conf.5 auditd-plugins.5 \
 audit_delete_rule_data.3 audit_detect_machine.3 \
 audit_encode_nv_string.3 audit_getloginuid.3 \
-audit_get_reply.3 audit_get_session.3 \
+audit_get_reply.3 audit_get_session.3 audit_get_containerid.3 \
 audit_log_acct_message.3 audit_log_user_avc_message.3 \
 audit_log_user_command.3 audit_log_user_comm_message.3 \
 audit_log_user_message.3 audit_log_semanage_message.3 \
diff --git a/docs/audit_get_containerid.3 b/docs/audit_get_containerid.3
new file mode 100644
index ..ef62a25db970
--- /dev/null
+++ b/docs/audit_get_containerid.3
@@ -0,0 +1,25 @@
+.TH "AUDIT_GET_CONTAINERID" "3" "Feb 2018" "Red Hat" "Linux Audit API"
+.SH NAME
+audit_get_containerid \- Get a program's container id value
+.SH SYNOPSIS
+.B #include 
+.sp
+uin64_t audit_get_containerid(void);
+
+.SH DESCRIPTION
+This function returns the task's audit container identifier attribute.
+
+.SH "RETURN VALUE"
+
+This function returns the audit container identifier value if it was set. It 
will return a \-1 if the audit container identifier is unset. However, since 
uint64_t is an unsigned type, you will see the converted value instead of \-1.
+
+.SH "ERRORS"
+
+This function returns \-2 on failure. Additionally, in the event of a real 
error, errno would be set. The function can set errno based on failures of 
open, read, or strtoull.
+
+.SH "SEE ALSO"
+
+.BR audit_getloginuid (3).
+
+.SH AUTHOR
+Richard Guy Briggs
diff --git a/lib/libaudit.c b/lib/libaudit.c
index bcef9dc7a2cc..43c166fabbd8 100644
--- a/lib/libaudit.c
+++ b/lib/libaudit.c
@@ -967,6 +967,35 @@ uint32_t audit_get_session(void)
return ses;
 }
 
+/*
+ * This function will retrieve the audit container identifier or -2 if
+ * there is an error.
+ */
+uint64_t audit_get_containerid(void)
+{
+   uint64_t containerid;
+   int len, in;
+   char buf[32];
+
+   errno = 0;
+   in = open("/proc/self/audit_containerid", O_NOFOLLOW|O_RDONLY);
+   if (in < 0)
+   return -2;
+   do {
+   len = read(in, buf, sizeof(buf));
+   } while (len < 0 && errno == EINTR);
+   close(in);
+   if (len < 0 || len >= sizeof(buf))
+   return -2;
+   buf[len] = 0;
+   errno = 0;
+   containerid = strtoull(buf, 0, 10);
+   if (errno)
+   return -2;
+   else
+   return containerid;
+}
+
 int audit_rule_syscall_data(struct audit_rule_data *rule, int scall)
 {
int word = AUDIT_WORD(scall);
diff --git a/lib/libaudit.h b/lib/libaudit.h
index a252813d1f72..c6f45fdf7abc 100644
--- a/lib/libaudit.h
+++ b/lib/libaudit.h
@@ -602,6 +602,7 @@ extern int  audit_get_reply(int fd, struct audit_reply 
*rep, reply_t block,
 extern uid_t audit_getloginuid(void);
 extern int  audit_setloginuid(uid_t uid);
 extern uint32_t audit_get_session(void);
+extern uint64_t audit_get_containerid(void);
 extern int  audit_detect_machine(void);
 extern int audit_determine_machine(const char *arch);
 extern char *audit_format_signal_info(char *buf, int len, char *op, struct 
audit_reply *rep, char *res);
-- 
2.18.4



[PATCH ghau51/ghau40 v10 07/11] signal_info: only print context if it is available.

2020-12-21 Thread Richard Guy Briggs
Signed-off-by: Richard Guy Briggs 
---
 src/auditd-event.c| 20 +++-
 src/auditd-reconfig.c |  2 --
 2 files changed, 15 insertions(+), 7 deletions(-)

diff --git a/src/auditd-event.c b/src/auditd-event.c
index e6b2a961f02b..800f4d83bc83 100644
--- a/src/auditd-event.c
+++ b/src/auditd-event.c
@@ -1323,13 +1323,16 @@ static void reconfigure(struct auditd_event *e)
const char *ctx = nconf->sender_ctx;
struct timeval tv;
char txt[MAX_AUDIT_MESSAGE_LENGTH];
+   int txt_len;
char date[40];
unsigned int seq_num;
int need_size_check = 0, need_reopen = 0, need_space_check = 0;
 
-   snprintf(txt, sizeof(txt),
-   "config change requested by pid=%d auid=%u subj=%s",
-   pid, uid, ctx);
+   txt_len = snprintf(txt, sizeof(txt),
+   "config change requested by pid=%d auid=%u", pid, uid);
+   if (ctx)
+   snprintf(txt + txt_len, sizeof(txt) - txt_len,
+" subj=%s", ctx);
audit_msg(LOG_NOTICE, "%s", txt);
 
/* Do the reconfiguring. These are done in a specific
@@ -1578,8 +1581,15 @@ static void reconfigure(struct auditd_event *e)
 
e->reply.type = AUDIT_DAEMON_CONFIG;
e->reply.len = snprintf(e->reply.msg.data, MAX_AUDIT_MESSAGE_LENGTH-2, 
-   "%s: op=reconfigure state=changed auid=%u pid=%d subj=%s res=success",
-   date, uid, pid, ctx );
+   "%s: op=reconfigure state=changed auid=%u 
pid=%d",
+   date, uid, pid);
+   if (ctx)
+   e->reply.len += snprintf(e->reply.msg.data + e->reply.len,
+MAX_AUDIT_MESSAGE_LENGTH-2 - 
e->reply.len,
+" subj=%s", ctx);
+   e->reply.len += snprintf(e->reply.msg.data + e->reply.len,
+MAX_AUDIT_MESSAGE_LENGTH-2 - e->reply.len,
+" res=success");
e->reply.message = e->reply.msg.data;
free((char *)ctx);
 }
diff --git a/src/auditd-reconfig.c b/src/auditd-reconfig.c
index f5b00e6d1dc7..1af402526c4e 100644
--- a/src/auditd-reconfig.c
+++ b/src/auditd-reconfig.c
@@ -106,8 +106,6 @@ static void *config_thread_main(void *arg)
if (e->reply.len > 24)
new_config.sender_ctx = 
strdup(e->reply.signal_info->ctx);
-   else
-   new_config.sender_ctx = strdup("?"); 
memcpy(e->reply.msg.data, _config, sizeof(new_config));
e->reply.conf = (struct daemon_conf *)e->reply.msg.data;
e->reply.type = AUDIT_DAEMON_RECONFIG;
-- 
2.18.4



[PATCH ghau51/ghau40 v10 03/11] auditctl: add support for AUDIT_CONTID filter

2020-12-21 Thread Richard Guy Briggs
A u64 container identifier has been added to the kernel view of tasks.
This allows container orchestrators to label tasks with a unique
tamperproof identifier that gets inherited by its children to be able to
track the provenance of actions by a container.

Add support to libaudit and auditctl for the AUDIT_CONTID field to
filter based on audit container identifier.  This field is specified
with the "contid" field name on the command line.

Since it is a u64 and larger than any other numeric field, send it as a
string but do the appropriate conversions on each end in each direction.

See: https://github.com/linux-audit/audit-userspace/issues/40
See: https://github.com/linux-audit/audit-kernel/issues/91
See: https://github.com/linux-audit/audit-testsuite/issues/64
See: https://github.com/linux-audit/audit-kernel/wiki/RFE-Audit-Container-ID
Signed-off-by: Richard Guy Briggs 
---
 docs/auditctl.8|  3 +++
 lib/fieldtab.h |  1 +
 lib/libaudit.c | 35 +++
 lib/libaudit.h |  7 +++
 src/auditctl-listing.c | 21 +
 5 files changed, 67 insertions(+)

diff --git a/docs/auditctl.8 b/docs/auditctl.8
index 09ed2466c5d4..c6a1a62472fe 100644
--- a/docs/auditctl.8
+++ b/docs/auditctl.8
@@ -223,6 +223,9 @@ Address family number as found in 
/usr/include/bits/socket.h. For example, IPv4
 .B sessionid
 User's login session ID
 .TP
+.B contid
+Process' audit container ID
+.TP
 .B subj_user
 Program's SE Linux User
 .TP
diff --git a/lib/fieldtab.h b/lib/fieldtab.h
index b597cafb2df8..e0a49d0154bb 100644
--- a/lib/fieldtab.h
+++ b/lib/fieldtab.h
@@ -47,6 +47,7 @@ _S(AUDIT_OBJ_TYPE, "obj_type" )
 _S(AUDIT_OBJ_LEV_LOW,  "obj_lev_low"  )
 _S(AUDIT_OBJ_LEV_HIGH, "obj_lev_high" )
 _S(AUDIT_SESSIONID,"sessionid")
+_S(AUDIT_CONTID,   "contid"   )
 
 _S(AUDIT_DEVMAJOR, "devmajor" )
 _S(AUDIT_DEVMINOR, "devminor" )
diff --git a/lib/libaudit.c b/lib/libaudit.c
index 2c7b16ccf44e..bcef9dc7a2cc 100644
--- a/lib/libaudit.c
+++ b/lib/libaudit.c
@@ -1779,6 +1779,41 @@ int audit_rule_fieldpair_data(struct audit_rule_data 
**rulep, const char *pair,
if (rule->values[rule->field_count] >= AF_MAX)
return -EAU_FIELDVALTOOBIG;
break;
+   case AUDIT_CONTID: {
+   unsigned long long val;
+
+   if ((audit_get_features() &
+   AUDIT_FEATURE_BITMAP_CONTAINERID) == 0)
+   return -EAU_FIELDNOSUPPORT;
+   if (flags != AUDIT_FILTER_EXCLUDE &&
+   flags != AUDIT_FILTER_USER &&
+   flags != AUDIT_FILTER_EXIT)
+   return -EAU_FIELDNOFILTER;
+   if (isdigit((char)*(v)))
+   val = strtoull(v, NULL, 0);
+   else if (strlen(v) >= 2 && *(v) == '-' &&
+   (isdigit((char)*(v+1
+   val = strtoll(v, NULL, 0);
+   else if (strcmp(v, "unset") == 0)
+   val = ULLONG_MAX;
+   else
+   return -EAU_FIELDVALNUM;
+   if (errno)
+   return -EAU_FIELDVALNUM;
+   vlen = sizeof(unsigned long long);
+   rule->values[rule->field_count] = vlen;
+   offset = rule->buflen;
+   rule->buflen += vlen;
+   *rulep = realloc(rule, sizeof(*rule) + rule->buflen);
+   if (*rulep == NULL) {
+   free(rule);
+   audit_msg(LOG_ERR, "Cannot realloc memory!\n");
+   return -3;
+   }
+   rule = *rulep;
+   *(unsigned long long *)(>buf[offset]) = val;
+   break;
+   }
case AUDIT_DEVMAJOR...AUDIT_INODE:
case AUDIT_SUCCESS:
if (flags != AUDIT_FILTER_EXIT)
diff --git a/lib/libaudit.h b/lib/libaudit.h
index 3b0b1e8d0d22..a252813d1f72 100644
--- a/lib/libaudit.h
+++ b/lib/libaudit.h
@@ -363,6 +363,9 @@ extern "C" {
 #ifndef AUDIT_FEATURE_BITMAP_FILTER_FS
 #define AUDIT_FEATURE_BITMAP_FILTER_FS 0x0040
 #endif
+#ifndef AUDIT_FEATURE_BITMAP_CONTAINERID
+#define AUDIT_FEATURE_BITMAP_CONTAINERID   0x0080
+#endif
 
 /* Defines for interfield comparison update */
 #ifndef AUDIT_OBJ_UID
@@ -389,6 +392,10 @@ extern "C" {
 #define AUDIT_FSTYPE 26
 #endif
 
+#ifndef AUDIT_CONTID
+#d

[PATCH ghau51/ghau40 v10 02/11] AUDIT_CONTAINER_ID message type basic support

2020-12-21 Thread Richard Guy Briggs
This defines the message number for the audit container identifier
information record should the kernel headers not be up to date and gives
the record number a name for printing.

See: https://github.com/linux-audit/audit-userspace/issues/51
See: https://github.com/linux-audit/audit-kernel/issues/90
See: https://github.com/linux-audit/audit-testsuite/issues/64
See: https://github.com/linux-audit/audit-kernel/wiki/RFE-Audit-Container-ID
Signed-off-by: Richard Guy Briggs 
---
 lib/libaudit.h| 4 
 lib/msg_typetab.h | 1 +
 2 files changed, 5 insertions(+)

diff --git a/lib/libaudit.h b/lib/libaudit.h
index 7fe56f4c8b22..3b0b1e8d0d22 100644
--- a/lib/libaudit.h
+++ b/lib/libaudit.h
@@ -303,6 +303,10 @@ extern "C" {
 #define AUDIT_EVENT_LISTENER   1335 /* audit mcast sock join/part */
 #endif
 
+#ifndef AUDIT_CONTAINER_ID
+#define AUDIT_CONTAINER_ID 1336 /* Container ID */
+#endif
+
 #ifndef AUDIT_MAC_CALIPSO_ADD
 #define AUDIT_MAC_CALIPSO_ADD  1418 /* NetLabel: add CALIPSO DOI entry */
 #endif
diff --git a/lib/msg_typetab.h b/lib/msg_typetab.h
index 376e121e1278..9484bdce6776 100644
--- a/lib/msg_typetab.h
+++ b/lib/msg_typetab.h
@@ -128,6 +128,7 @@ _S(AUDIT_TIME_INJOFFSET, "TIME_INJOFFSET"   
 )
 _S(AUDIT_TIME_ADJNTPVAL, "TIME_ADJNTPVAL")
 _S(AUDIT_BPF,"BPF"   )
 _S(AUDIT_EVENT_LISTENER, "EVENT_LISTENER")
+_S(AUDIT_CONTAINER_ID,   "CONTAINER_ID"  )
 _S(AUDIT_AVC,"AVC"   )
 _S(AUDIT_SELINUX_ERR,"SELINUX_ERR"   )
 _S(AUDIT_AVC_PATH,   "AVC_PATH"  )
-- 
2.18.4



[PATCH ghau51/ghau40 v10 00/11] add support for audit container identifier

2020-12-21 Thread Richard Guy Briggs
Add support for audit kernel container identifiers to userspace tools.

The first and second add new record types.  The third adds filter
support.  The fourth and 5th start to add search support.

The 6th is to read the calling process' audit container identifier from
the /proc filesystem matching the kernel /proc read patch.

The 7th is to fix signal support and the 8th is to learn the audit
container identifier of the process that signals the audit daemon.

The 9th is a touch up to allow the contid field to be interpreted as a
CSV list.

The 10th adds audit contid list support to ausearch.

The last adds audit library support to allow a process to give
permission to a container orchestrator in a non-init user namespace via
audit netlink messages.

See: https://github.com/linux-audit/audit-userspace/issues/51
See: https://github.com/linux-audit/audit-userspace/issues/40
See: https://github.com/linux-audit/audit-kernel/issues/90
See: https://github.com/linux-audit/audit-kernel/issues/91
See: https://github.com/linux-audit/audit-testsuite/issues/64
  https://githu.com/linux-audit/audit-testsuite/pull/91
  https://github.com/rgbriggs/audit-testsuite/tree/ghat64-contid
See: https://github.com/linux-audit/audit-kernel/wiki/RFE-Audit-Container-ID

A repo of the code is here:
  g...@github.com:rgbriggs/audit-userspace.git ghau40-containerid-filter.v10
And test rpms built from it are here:
  people.redhat.com/~rbriggs/ghak90/git-a52e3dd-fc32

Changelog:
v10
- rebase on upstream

v9
- accept a contid list for sig_info2
- bump AUDIT_CONTAINER_ID to 1336 to accommodate AUDIT_EVENT_LISTENER
- fix logical result reversal in audit_signal_info_has_ctx()
- fix event_contid clist declaration, fix comment about CONTAINER_OP/ID 
old-/contid CSV
- add SET_CAPCONTID to lib/netlink.c adjust_reply() and check_events()
- rebase on ghak28 parser
- rebase on ghak25 parser
- rebase on ghau86 fix
- in auparse/interpret.c:print_contid() also detect "-1"
- remove patches to limit nesting depth and netns count
- whitespace fixes
- squash clist into slist
- simplify audit_[sg]et_capcontid()

v8
- renumber contid records and drop netlink contid set/get support
- remove subject attributes from parse_container_op()
- fix audit_request_signal_info.3 manpage
- add manpage for audit_set_capcontid()
- implement clist for contid list search
- rebase on audit_bpf patches (bump CONTAINER_ID to 1335)
- implement control for audit container identifier nesting depth limit with 
manpage
- implent control for audit container identifier netns count limit with manpage

v7
- rebase on ghau90 and touchup
- rebase on ghak10 support (change AUDIT_CONTAINER_ID to 1334)
- render type contid as a CSV
- switch from /proc to audit netlink to set/get contid, auid/sessionid
- add support for capcontid

v6
- auditd signaller tracking was moved to a new AUDIT_SIGNAL_INFO2
  request and record
- swap CONTAINER_OP contid/old-contid to ease parsing
- add to auparse

v5
- updated aux record from AUDIT_CONTAINER to AUDIT_CONTAINER_ID
- add AUDIT_CONTAINER_ID to normalization
- rebase on AUDIT_ANOM_LINK and AUDIT_MAC_CALIPSO_ADD

v4
- change from AUDIT_CONTAINER_ID to AUDIT_CONTAINER_OP
- change from AUDIT_FEATURE_BITMAP_CONTAINERID_FILTER to
  AUDIT_FEATURE_BITMAP_CONTAINERID
- change from event_container_id to event_contid internally
- change from container_id to contid and event_container_id to
  event_contid internally
- change command line option from --container-id to --contid

v3
- change from AUDIT_CONTAINER to AUDIT_CONTAINER_ID
- change from AUDIT_CONTAINER_INFO to AUDIT_CONTAINER
- change from AUDIT_CONTAINERID to AUDIT_CONTID
- update github issue refs
- add audit_get_containerid
- change event_container_id default value
- add --containerid to ausearch options help text
- update ausearch parser and error codes

v2
- rebase on UINT_MAX patch
- add patches for AUDIT_CONTAINER, AUDIT_CONTAINER_INFO, ausearch,
  normalization

Richard Guy Briggs (11):
  AUDIT_CONTAINER_OP message type basic support
  AUDIT_CONTAINER_ID message type basic support
  auditctl: add support for AUDIT_CONTID filter
  add ausearch containerid support
  start normalization containerid support
  libaudit: add support to get the task audit container identifier
  signal_info: only print context if it is available.
  add support for audit_signal_info2
  contid: interpret correctly CONTAINER_ID contid field csv
  ausearch: convert contid to comma-sep/carrat-mod cnode/clist
  libaudit: add support to get and set capcontid on a task

 auparse/auditd-config.c  |   1 +
 auparse/auparse-defs.h   |   3 +-
 auparse/interpret.c  |  10 ++
 auparse/normalize.c  |   1 +
 auparse/normalize_record_map.h   |   3 +
 auparse/typetab.h|   2 +
 bindings/python/auparse_python.c |   1 +
 docs/Makefile.am |   3 +-
 docs/audit_get_capcontid.3   |  25 
 docs/audit_get_containerid.3 |  25 
 docs/audit_request_signal_in

[PATCH ghak90 v10 11/11] audit: add capcontid to set contid outside init_user_ns

2020-12-21 Thread Richard Guy Briggs
Provide a mechanism similar to CAP_AUDIT_CONTROL to explicitly give a
process in a non-init user namespace the capability to set audit
container identifiers of individual children.

Provide the /proc/$PID/audit_capcontid interface to capcontid.
Valid values are: 1==enabled, 0==disabled

Writing a "1" to this special file for the target process $PID will
enable the target process to set audit container identifiers of its
descendants.

A process must already have CAP_AUDIT_CONTROL in the initial user
namespace or have had audit_capcontid enabled by a previous use of this
feature by its parent on this process in order to be able to enable it
for another process.  The target process must be a descendant of the
calling process.

Report this action in new message type AUDIT_SET_CAPCONTID 1022 with
fields opid= capcontid= old-capcontid=

Add an entry to Documentation/ABI.

Signed-off-by: Richard Guy Briggs 
---
 .../ABI/testing/procfs-audit_containerid  | 16 +
 fs/proc/base.c| 54 +++
 include/linux/audit.h |  4 +-
 include/uapi/linux/audit.h|  1 +
 kernel/audit.c| 65 ++-
 5 files changed, 137 insertions(+), 3 deletions(-)

diff --git a/Documentation/ABI/testing/procfs-audit_containerid 
b/Documentation/ABI/testing/procfs-audit_containerid
index 30ea64790473..c697d7da0ad1 100644
--- a/Documentation/ABI/testing/procfs-audit_containerid
+++ b/Documentation/ABI/testing/procfs-audit_containerid
@@ -11,3 +11,19 @@ Description:
or have its own /proc/$pid/capcontainerid set to write
or read.
 
+
+What:  Capability to set or get the Audit Container Identifier
+Date:  2020-??
+KernelVersion: 5.10?
+Contact:   linux-au...@redhat.com
+Format:u32
+Users: auditd, libaudit, audit-testsuite, podman(?), container 
orchestrators
+Description:
+   The /proc/$pid/audit_capcontainerid pseudofile is
+   written to set and is read to get the capability of
+   process $pid to write or to read the /proc/$pid/containerid
+   audit container identifier of any of its descendants.
+   "1" allows and "0" denies that capability.  This
+   property is an extension to CAP_AUDIT_CONTROL outside of
+   the initial user namespace.
+
diff --git a/fs/proc/base.c b/fs/proc/base.c
index 94895a5750ca..3fedb8711fcb 100644
--- a/fs/proc/base.c
+++ b/fs/proc/base.c
@@ -1381,6 +1381,58 @@ static const struct file_operations 
proc_contid_operations = {
.write  = proc_contid_write,
.llseek = generic_file_llseek,
 };
+
+static ssize_t proc_capcontid_read(struct file *file, char __user *buf,
+ size_t count, loff_t *ppos)
+{
+   struct inode *inode = file_inode(file);
+   struct task_struct *task = get_proc_task(inode);
+   ssize_t length;
+   char tmpbuf[TMPBUFLEN];
+
+   if (!task)
+   return -ESRCH;
+   length = audit_get_capcontid_proc(tmpbuf, TMPBUFLEN, task);
+   put_task_struct(task);
+   if (length < 0)
+   return length;
+   return simple_read_from_buffer(buf, count, ppos, tmpbuf, length);
+}
+
+static ssize_t proc_capcontid_write(struct file *file, const char __user *buf,
+  size_t count, loff_t *ppos)
+{
+   struct inode *inode = file_inode(file);
+   u32 capcontid;
+   int rv;
+   struct task_struct *task = get_proc_task(inode);
+
+   if (!task)
+   return -ESRCH;
+   if (*ppos != 0) {
+   /* No partial writes. */
+   put_task_struct(task);
+   return -EINVAL;
+   }
+
+   rv = kstrtou32_from_user(buf, count, 10, );
+   if (rv < 0) {
+   put_task_struct(task);
+   return rv;
+   }
+
+   rv = audit_set_capcontid(task, capcontid);
+   put_task_struct(task);
+   if (rv < 0)
+   return rv;
+   return count;
+}
+
+static const struct file_operations proc_capcontid_operations = {
+   .read   = proc_capcontid_read,
+   .write  = proc_capcontid_write,
+   .llseek = generic_file_llseek,
+};
 #endif
 
 #ifdef CONFIG_FAULT_INJECTION
@@ -3284,6 +3336,7 @@ static const struct pid_entry tgid_base_stuff[] = {
REG("loginuid",   S_IWUSR|S_IRUGO, proc_loginuid_operations),
REG("sessionid",  S_IRUGO, proc_sessionid_operations),
REG("audit_containerid", S_IWUSR|S_IRUSR, proc_contid_operations),
+   REG("audit_capcontainerid", S_IWUSR|S_IRUSR, proc_capcontid_operations),
 #endif
 #ifdef CONFIG_FAULT_INJECTION
REG("make-it-fail", S_IRUGO|S_IWUSR, proc_fault_inject_operations),
@@ -3624,6 +3677,7 @@ st

[PATCH ghak90 v10 10/11] audit: track container nesting

2020-12-21 Thread Richard Guy Briggs
Track the parent container of a container to be able to filter and
report nesting.

Now that we have a way to track and check the parent container of a
container, modify the contid field format to be able to report that
nesting using a carrat ("^") modifier to indicate nesting.  The
original field format was "contid=" for task-associated records
and "contid=[,[...]]" for network-namespace-associated
records.  The new field format is
"contid=[,^[...]][,[...]]".

For task event example, an orchestrator in contid 1 spawns tasks in contid
2 and contid 3, then the task in contid 2 spawns a task in contid 4.  An
event happens in the task in contid 4:
type=SYSCALL ...
type=CONTAINER_ID msg=audit(:): contid=4,^2,^1

For a network namespace event example, an orchestrator in contid 1 in
network namespace A spawns peer tasks 2 and 3 in network namespace B.  An
event happens in network namespace B:
type=NETFILTER_PKT ...
type=CONTAINER_ID msg=audit(:): contid=2,^1,3,^1

Signed-off-by: Richard Guy Briggs 
---
 kernel/audit.c | 75 +-
 1 file changed, 62 insertions(+), 13 deletions(-)

diff --git a/kernel/audit.c b/kernel/audit.c
index 6eed8ed0cc8e..46ddf49f731f 100644
--- a/kernel/audit.c
+++ b/kernel/audit.c
@@ -231,6 +231,7 @@ struct audit_contobj {
refcount_t  refcount;
refcount_t  sigflag;
struct rcu_head rcu;
+   struct audit_contobj*parent;
 };
 
 struct audit_task_info {
@@ -253,6 +254,7 @@ struct audit_contobj_netns {
 
 static void audit_netns_contid_add(struct net *net, struct audit_contobj 
*cont);
 static void audit_netns_contid_del(struct net *net, struct audit_contobj 
*cont);
+static void audit_log_contid(struct audit_buffer *ab, struct audit_contobj 
*cont);
 
 void __init audit_task_init(void)
 {
@@ -378,6 +380,7 @@ static void _audit_contobj_put_sig(struct audit_contobj 
*cont)
refcount_set(>sigflag, 0);
if (!refcount_read(>refcount)) {
put_task_struct(cont->owner);
+   _audit_contobj_put(cont->parent);
list_del_rcu(>list);
kfree_rcu(cont, rcu);
}
@@ -721,11 +724,11 @@ int audit_log_netns_contid_list(struct net *net, struct 
audit_context *context)
audit_log_lost("out of memory in 
audit_log_netns_contid_list");
goto out;
}
-   audit_log_format(ab, "record=1 contid=%llu",
-cont->obj->id);
+   audit_log_format(ab, "record=1 contid=");
} else {
-   audit_log_format(ab, ",%llu", cont->obj->id);
+   audit_log_format(ab, ",");
}
+   audit_log_contid(ab, cont->obj);
}
audit_log_end(ab);
 out:
@@ -1905,6 +1908,7 @@ static int audit_receive_msg(struct sk_buff *skb, struct 
nlmsghdr *nlh)
case AUDIT_SIGNAL_INFO2: {
char *contidstr = NULL;
unsigned int contidstrlen = 0;
+   struct audit_contobj *cont = audit_sig_cid;
 
len = 0;
if (audit_sig_sid) {
@@ -1914,13 +1918,27 @@ static int audit_receive_msg(struct sk_buff *skb, 
struct nlmsghdr *nlh)
return err;
}
if (audit_sig_cid) {
-   contidstr = kmalloc(21, GFP_KERNEL);
+   contidstr = kmalloc(AUDIT_MESSAGE_TEXT_MAX, GFP_KERNEL);
if (!contidstr) {
if (audit_sig_sid)
security_release_secctx(ctx, len);
return -ENOMEM;
}
-   contidstrlen = scnprintf(contidstr, 20, "%llu", 
audit_sig_cid->id);
+   rcu_read_lock();
+   while (cont) {
+   if (cont->parent)
+   contidstrlen += scnprintf(contidstr,
+ 
AUDIT_MESSAGE_TEXT_MAX -
+ contidstrlen,
+ "%llu,^", 
cont->id);
+   else
+   contidstrlen += scnprintf(contidstr,
+ 
AUDIT_MESSAGE_TEXT_MAX -
+ contidstrlen,
+ "%llu", 
cont->id);
+   cont = cont->parent;
+ 

[PATCH ghak90 v10 09/11] audit: contid check descendancy and nesting

2020-12-21 Thread Richard Guy Briggs
Require the target task to be a descendant of the container
orchestrator/engine.

You would only change the audit container ID from one set or inherited
value to another if you were nesting containers.

If changing the contid, the container orchestrator/engine must be a
descendant and not same orchestrator as the one that set it so it is not
possible to change the contid of another orchestrator's container.

Since the task_is_descendant() function is used in YAMA and in audit,
remove the duplication and pull the function into kernel/core/sched.c

Signed-off-by: Richard Guy Briggs 
---
 include/linux/sched.h|  3 +++
 kernel/audit.c   | 26 +++---
 kernel/sched/core.c  | 33 +
 security/yama/yama_lsm.c | 33 -
 4 files changed, 59 insertions(+), 36 deletions(-)

diff --git a/include/linux/sched.h b/include/linux/sched.h
index b28348868b27..9e658e724543 100644
--- a/include/linux/sched.h
+++ b/include/linux/sched.h
@@ -2055,4 +2055,7 @@ int sched_trace_rq_nr_running(struct rq *rq);
 
 const struct cpumask *sched_trace_rd_span(struct root_domain *rd);
 
+extern int task_is_descendant(struct task_struct *parent,
+ struct task_struct *child);
+
 #endif
diff --git a/kernel/audit.c b/kernel/audit.c
index 8d03f07e7128..6eed8ed0cc8e 100644
--- a/kernel/audit.c
+++ b/kernel/audit.c
@@ -475,11 +475,13 @@ void audit_free(struct task_struct *tsk)
rcu_read_lock();
cont = _audit_contobj_get_bytask(tsk);
rcu_read_unlock();
-   spin_lock_irqsave(&_audit_contobj_list_lock, flags);
if (ns) {
audit_netns_contid_del(ns->net_ns, cont);
+   spin_lock_irqsave(&_audit_contobj_list_lock, flags);
_audit_contobj_put(cont);
+   spin_unlock_irqrestore(&_audit_contobj_list_lock, flags);
}
+   spin_lock_irqsave(&_audit_contobj_list_lock, flags);
_audit_contobj_put(cont);
spin_unlock_irqrestore(&_audit_contobj_list_lock, flags);
audit_free_syscall(tsk);
@@ -2923,6 +2925,21 @@ int audit_signal_info(int sig, struct task_struct *t)
return audit_signal_info_syscall(t);
 }
 
+static bool audit_contid_isnesting(struct task_struct *tsk)
+{
+   bool isowner = false;
+   bool ownerisparent = false;
+   struct audit_task_info *info = tsk->audit;
+
+   rcu_read_lock();
+   if (info && info->cont) {
+   isowner = current == info->cont->owner;
+   ownerisparent = task_is_descendant(info->cont->owner, current);
+   }
+   rcu_read_unlock();
+   return !isowner && ownerisparent;
+}
+
 /*
  * audit_set_contid - set current task's audit contid
  * @tsk: target task
@@ -2963,8 +2980,11 @@ int audit_set_contid(struct task_struct *tsk, u64 contid)
   !(thread_group_leader(tsk) && thread_group_empty(tsk))) {
/* if task has children or is not single-threaded, deny */
rc = -EBUSY;
-   } else if (info->cont) {
-   /* if contid is already set, deny */
+   } else if (tsk == current || !task_is_descendant(current, tsk)) {
+   /* if task is not descendant, block */
+   rc = -EXDEV;
+   } else if (info->cont && !audit_contid_isnesting(tsk)) {
+   /* only allow contid setting again if nesting */
rc = -EEXIST;
}
rcu_read_lock();
diff --git a/kernel/sched/core.c b/kernel/sched/core.c
index d2003a7d5ab5..6af7e6ee2498 100644
--- a/kernel/sched/core.c
+++ b/kernel/sched/core.c
@@ -8436,6 +8436,39 @@ void dump_cpu_task(int cpu)
sched_show_task(cpu_curr(cpu));
 }
 
+/*
+ * task_is_descendant - walk up a process family tree looking for a match
+ * @parent: the process to compare against while walking up from child
+ * @child: the process to start from while looking upwards for parent
+ *
+ * Returns 1 if child is a descendant of parent, 0 if not.
+ */
+int task_is_descendant(struct task_struct *parent,
+ struct task_struct *child)
+{
+   int rc = 0;
+   struct task_struct *walker = child;
+
+   if (!parent || !child)
+   return 0;
+
+   rcu_read_lock();
+   if (!thread_group_leader(parent))
+   parent = rcu_dereference(parent->group_leader);
+   while (walker->pid > 0) {
+   if (!thread_group_leader(walker))
+   walker = rcu_dereference(walker->group_leader);
+   if (walker == parent) {
+   rc = 1;
+   break;
+   }
+   walker = rcu_dereference(walker->real_parent);
+   }
+   rcu_read_unlock();
+
+   return rc;
+}
+
 /*
  * Nice levels are multiplicative, with a gentle 10% change for every
  * nice level changed. I.e. when a CPU-bound t

[PATCH ghak90 v10 08/11] audit: add support for containerid to network namespaces

2020-12-21 Thread Richard Guy Briggs
This also adds support to qualify NETFILTER_PKT records.

Audit events could happen in a network namespace outside of a task
context due to packets received from the net that trigger an auditing
rule prior to being associated with a running task.  The network
namespace could be in use by multiple containers by association to the
tasks in that network namespace.  We still want a way to attribute
these events to any potential containers.  Keep a list per network
namespace to track these audit container identifiiers.

Add/increment the audit container identifier on:
- initial setting of the audit container identifier via /proc
- clone/fork call that inherits an audit container identifier
- unshare call that inherits an audit container identifier
- setns call that inherits an audit container identifier
Delete/decrement the audit container identifier on:
- an inherited audit container identifier dropped when child set
- process exit
- unshare call that drops a net namespace
- setns call that drops a net namespace

Add audit container identifier auxiliary record(s) to NETFILTER_PKT
event standalone records.  Iterate through all potential audit container
identifiers associated with a network namespace.

Sample event:
type=NETFILTER_PKT msg=audit(2020-11-26 10:24:47.984:174549) : mark=0x15766399 
saddr=127.0.0.1 daddr=127.0.0.1 proto=icmp record=1
type=CONTAINER_ID msg=audit(2020-11-26 10:24:47.984:174549) : record=1 
contid=4112973747854606336,1916436506412318720

Please see the github audit kernel issue for contid net support:
  https://github.com/linux-audit/audit-kernel/issues/92
Please see the github audit testsuiite issue for the test case:
  https://github.com/linux-audit/audit-testsuite/issues/64
Please see the github audit wiki for the feature overview:
  https://github.com/linux-audit/audit-kernel/wiki/RFE-Audit-Container-ID
Signed-off-by: Richard Guy Briggs 
Acked-by: Neil Horman 
Reviewed-by: Ondrej Mosnacek 
---
 include/linux/audit.h|  17 +++
 kernel/audit.c   | 229 ++-
 kernel/nsproxy.c |   4 +
 net/netfilter/nft_log.c  |  14 ++-
 net/netfilter/xt_AUDIT.c |  14 ++-
 5 files changed, 249 insertions(+), 29 deletions(-)

diff --git a/include/linux/audit.h b/include/linux/audit.h
index 056a7c9a12a2..014f73296fec 100644
--- a/include/linux/audit.h
+++ b/include/linux/audit.h
@@ -217,6 +217,12 @@ extern int audit_get_contid_proc(char *tmpbuf, int 
TMPBUFLEN,
 
 extern int audit_set_contid(struct task_struct *tsk, u64 contid);
 
+extern void audit_copy_namespaces(struct net *net, struct task_struct *tsk);
+extern void audit_switch_task_namespaces(struct nsproxy *ns,
+struct task_struct *p);
+extern int audit_log_netns_contid_list(struct net *net,
+   struct audit_context *context);
+
 extern u32 audit_enabled;
 
 extern int audit_signal_info(int sig, struct task_struct *t);
@@ -281,6 +287,17 @@ static inline unsigned int audit_get_sessionid(struct 
task_struct *tsk)
return AUDIT_SID_UNSET;
 }
 
+static inline void audit_copy_namespaces(struct net *net, struct task_struct 
*tsk)
+{ }
+static inline void audit_switch_task_namespaces(struct nsproxy *ns,
+   struct task_struct *p)
+{ }
+static inline int audit_log_netns_contid_list(struct net *net,
+  struct audit_context *context)
+{
+   return 0;
+}
+
 #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 300daf2bcb16..8d03f07e7128 100644
--- a/kernel/audit.c
+++ b/kernel/audit.c
@@ -59,6 +59,7 @@
 #include 
 #include 
 #include 
+#include 
 
 #include "audit.h"
 
@@ -86,9 +87,13 @@ static unsigned int audit_net_id;
 /**
  * struct audit_net - audit private network namespace data
  * @sk: communication socket
+ * @contobj_list: audit container identifier list
+ * @contobj_list_lock audit container identifier list lock
  */
 struct audit_net {
struct sock *sk;
+   struct list_head contobj_list;
+   spinlock_t contobj_list_lock;
 };
 
 /**
@@ -239,6 +244,16 @@ struct audit_task_info {
 
 static struct kmem_cache *audit_task_cache;
 
+struct audit_contobj_netns {
+   struct list_headlist;
+   struct audit_contobj*obj;
+   int count;
+   struct rcu_head rcu;
+};
+
+static void audit_netns_contid_add(struct net *net, struct audit_contobj 
*cont);
+static void audit_netns_contid_del(struct net *net, struct audit_contobj 
*cont);
+
 void __init audit_task_init(void)
 {
audit_task_cache = kmem_cache_create("audit_task",
@@ -372,11 +387,12 @@ void audit_contobj_put(void **cont, int count)
 {
int i;
struct audit_contobj **contobj = (struct audit_contobj **)cont;
+   unsigned long flags;
 
-   spin_lock(&

[PATCH ghak90 v10 07/11] audit: add containerid filtering

2020-12-21 Thread Richard Guy Briggs
Implement audit container identifier filtering using the AUDIT_CONTID
field name to send an 8-character string representing a u64 since the
value field is only u32.

Sending it as two u32 was considered, but gathering and comparing two
fields was more complex.

The feature indicator is AUDIT_FEATURE_BITMAP_CONTAINERID.

Please see the github audit kernel issue for the contid filter feature:
  https://github.com/linux-audit/audit-kernel/issues/91
Please see the github audit userspace issue for filter additions:
  https://github.com/linux-audit/audit-userspace/issues/40
Please see the github audit testsuiite issue for the test case:
  https://github.com/linux-audit/audit-testsuite/issues/64
Please see the github audit wiki for the feature overview:
  https://github.com/linux-audit/audit-kernel/wiki/RFE-Audit-Container-ID
Signed-off-by: Richard Guy Briggs 
Acked-by: Serge Hallyn 
Acked-by: Neil Horman 
Reviewed-by: Ondrej Mosnacek 
---
 include/linux/audit.h  |  1 +
 include/uapi/linux/audit.h |  5 -
 kernel/audit.c |  5 +
 kernel/audit.h |  3 +++
 kernel/auditfilter.c   | 46 ++
 kernel/auditsc.c   |  3 +++
 6 files changed, 62 insertions(+), 1 deletion(-)

diff --git a/include/linux/audit.h b/include/linux/audit.h
index 9f0238f7960f..056a7c9a12a2 100644
--- a/include/linux/audit.h
+++ b/include/linux/audit.h
@@ -69,6 +69,7 @@ struct audit_field {
u32 type;
union {
u32 val;
+   u64 val64;
kuid_t  uid;
kgid_t  gid;
struct {
diff --git a/include/uapi/linux/audit.h b/include/uapi/linux/audit.h
index 94dcf3085658..66350e572e41 100644
--- a/include/uapi/linux/audit.h
+++ b/include/uapi/linux/audit.h
@@ -271,6 +271,7 @@
 #define AUDIT_LOGINUID_SET 24
 #define AUDIT_SESSIONID25  /* Session ID */
 #define AUDIT_FSTYPE   26  /* FileSystem Type */
+#define AUDIT_CONTID   27  /* Container ID */
 
/* These are ONLY useful when checking
 * at syscall exit time (AUDIT_AT_EXIT). */
@@ -353,6 +354,7 @@ enum {
 #define AUDIT_FEATURE_BITMAP_SESSIONID_FILTER  0x0010
 #define AUDIT_FEATURE_BITMAP_LOST_RESET0x0020
 #define AUDIT_FEATURE_BITMAP_FILTER_FS 0x0040
+#define AUDIT_FEATURE_BITMAP_CONTAINERID   0x0080
 
 #define AUDIT_FEATURE_BITMAP_ALL (AUDIT_FEATURE_BITMAP_BACKLOG_LIMIT | \
  AUDIT_FEATURE_BITMAP_BACKLOG_WAIT_TIME | \
@@ -360,7 +362,8 @@ enum {
  AUDIT_FEATURE_BITMAP_EXCLUDE_EXTEND | \
  AUDIT_FEATURE_BITMAP_SESSIONID_FILTER | \
  AUDIT_FEATURE_BITMAP_LOST_RESET | \
- AUDIT_FEATURE_BITMAP_FILTER_FS)
+ AUDIT_FEATURE_BITMAP_FILTER_FS | \
+ AUDIT_FEATURE_BITMAP_CONTAINERID)
 
 /* deprecated: AUDIT_VERSION_* */
 #define AUDIT_VERSION_LATEST   AUDIT_FEATURE_BITMAP_ALL
diff --git a/kernel/audit.c b/kernel/audit.c
index b23f004f4000..300daf2bcb16 100644
--- a/kernel/audit.c
+++ b/kernel/audit.c
@@ -2488,6 +2488,11 @@ int audit_log_container_id_ctx(struct audit_context 
*context)
return record;
 }
 
+int audit_contid_comparator(struct task_struct *tsk, u32 op, u64 right)
+{
+   return audit_comparator64(audit_get_contid(tsk), op, right);
+}
+
 void audit_log_key(struct audit_buffer *ab, char *key)
 {
audit_log_format(ab, " key=");
diff --git a/kernel/audit.h b/kernel/audit.h
index 40e609787a0c..48c429c2d544 100644
--- a/kernel/audit.h
+++ b/kernel/audit.h
@@ -218,12 +218,15 @@ extern void *audit_contobj_get_bytask(struct task_struct 
*tsk);
 extern void audit_contobj_put(void **cont, int count);
 extern int audit_log_container_id(struct audit_context *context, void *cont);
 extern int audit_log_container_id_ctx(struct audit_context *context);
+extern int audit_contid_comparator(struct task_struct *tsk, const u32 op,
+  const u64 right);
 
 /* Indicates that audit should log the full pathname. */
 #define AUDIT_NAME_FULL -1
 
 extern int audit_match_class(int class, unsigned syscall);
 extern int audit_comparator(const u32 left, const u32 op, const u32 right);
+extern int audit_comparator64(const u64 left, const u32 op, const u64 right);
 extern int audit_uid_comparator(kuid_t left, u32 op, kuid_t right);
 extern int audit_gid_comparator(kgid_t left, u32 op, kgid_t right);
 extern int parent_len(const char *path);
diff --git a/kernel/auditfilter.c b/kernel/auditfilter.c
index 333b3bcfc545..9362ee9cc414 100644
--- a/kernel/auditfilter.c
+++ b/kernel/auditfilter.c
@@ -399,6 +399,7 @@ static int audit_field_valid(struct audit_entry *entr

[PATCH ghak90 v10 06/11] audit: add containerid support for user records

2020-12-21 Thread Richard Guy Briggs
Add audit container identifier auxiliary record to user event standalone
records.

Signed-off-by: Richard Guy Briggs 
Acked-by: Neil Horman 
Reviewed-by: Ondrej Mosnacek 
---
 kernel/audit.c | 12 +---
 1 file changed, 5 insertions(+), 7 deletions(-)

diff --git a/kernel/audit.c b/kernel/audit.c
index 1c2045c48baf..b23f004f4000 100644
--- a/kernel/audit.c
+++ b/kernel/audit.c
@@ -1338,12 +1338,6 @@ static void audit_log_common_recv_msg(struct 
audit_context *context,
audit_log_task_context(*ab);
 }
 
-static inline void audit_log_user_recv_msg(struct audit_buffer **ab,
-  u16 msg_type)
-{
-   audit_log_common_recv_msg(NULL, ab, msg_type);
-}
-
 int is_audit_feature_set(int i)
 {
return af.features & AUDIT_FEATURE_TO_MASK(i);
@@ -1619,6 +1613,7 @@ static int audit_receive_msg(struct sk_buff *skb, struct 
nlmsghdr *nlh)
err = audit_filter(msg_type, AUDIT_FILTER_USER);
if (err == 1) { /* match or error */
char *str = data;
+   struct audit_context *context;
 
err = 0;
if (msg_type == AUDIT_USER_TTY) {
@@ -1626,7 +1621,8 @@ static int audit_receive_msg(struct sk_buff *skb, struct 
nlmsghdr *nlh)
if (err)
break;
}
-   audit_log_user_recv_msg(, msg_type);
+   context = audit_alloc_local(GFP_KERNEL);
+   audit_log_common_recv_msg(context, , msg_type);
if (msg_type != AUDIT_USER_TTY) {
/* ensure NULL termination */
str[data_len - 1] = '\0';
@@ -1640,6 +1636,8 @@ static int audit_receive_msg(struct sk_buff *skb, struct 
nlmsghdr *nlh)
audit_log_n_untrustedstring(ab, str, data_len);
}
audit_log_end(ab);
+   audit_log_container_id_ctx(context);
+   audit_free_context(context);
}
break;
case AUDIT_ADD_RULE:
-- 
2.18.4



[PATCH ghak90 v10 05/11] audit: add support for non-syscall auxiliary records

2020-12-21 Thread Richard Guy Briggs
Standalone audit records have the timestamp and serial number generated
on the fly and as such are unique, making them standalone.  This new
function audit_alloc_local() generates a local audit context that will
be used only for a standalone record and its auxiliary record(s).  The
context is discarded immediately after the local associated records are
produced.

A new flag, "local" was used rather than "in_syscall" since it would be
overloading the original purpose and meaning.  Events using this
function may not be triggered by a syscall but still need records
linked by timestamp and serial.

Signed-off-by: Richard Guy Briggs 
Acked-by: Serge Hallyn 
Acked-by: Neil Horman 
Reviewed-by: Ondrej Mosnacek 
---
 include/linux/audit.h |  8 
 kernel/audit.h|  1 +
 kernel/auditsc.c  | 31 ++-
 3 files changed, 35 insertions(+), 5 deletions(-)

diff --git a/include/linux/audit.h b/include/linux/audit.h
index 7c1928e75cfe..9f0238f7960f 100644
--- a/include/linux/audit.h
+++ b/include/linux/audit.h
@@ -304,6 +304,8 @@ static inline int audit_signal_info(int sig, struct 
task_struct *t)
 
 /* These are defined in auditsc.c */
/* Public API */
+extern struct audit_context *audit_alloc_local(gfp_t gfpflags);
+extern void audit_free_context(struct audit_context *context);
 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);
@@ -555,6 +557,12 @@ static inline void audit_log_nfcfg(const char *name, u8 af,
 extern int audit_n_rules;
 extern int audit_signals;
 #else /* CONFIG_AUDITSYSCALL */
+static inline struct audit_context *audit_alloc_local(gfp_t gfpflags)
+{
+   return NULL;
+}
+static inline void audit_free_context(struct audit_context *context)
+{ }
 static inline void audit_syscall_entry(int major, unsigned long a0,
   unsigned long a1, unsigned long a2,
   unsigned long a3)
diff --git a/kernel/audit.h b/kernel/audit.h
index de79f59d623f..40e609787a0c 100644
--- a/kernel/audit.h
+++ b/kernel/audit.h
@@ -98,6 +98,7 @@ struct audit_proctitle {
 struct audit_context {
int dummy;  /* must be the first element */
int in_syscall; /* 1 if task is in a syscall */
+   boollocal;  /* local context needed */
enum audit_statestate, current_state;
unsigned intserial; /* serial number for record */
int major;  /* syscall number */
diff --git a/kernel/auditsc.c b/kernel/auditsc.c
index eecc7b2e29a7..df26d0aa5e6d 100644
--- a/kernel/auditsc.c
+++ b/kernel/auditsc.c
@@ -920,11 +920,12 @@ static inline void audit_free_aux(struct audit_context 
*context)
}
 }
 
-static inline struct audit_context *audit_alloc_context(enum audit_state state)
+static inline struct audit_context *audit_alloc_context(enum audit_state state,
+   gfp_t gfpflags)
 {
struct audit_context *context;
 
-   context = kzalloc(sizeof(*context), GFP_KERNEL);
+   context = kzalloc(sizeof(*context), gfpflags);
if (!context)
return NULL;
context->state = state;
@@ -962,7 +963,8 @@ int audit_alloc_syscall(struct task_struct *tsk)
return 0;
}
 
-   if (!(context = audit_alloc_context(state))) {
+   context = audit_alloc_context(state, GFP_KERNEL);
+   if (!context) {
kfree(key);
audit_log_lost("out of memory in audit_alloc_syscall");
return -ENOMEM;
@@ -974,8 +976,26 @@ int audit_alloc_syscall(struct task_struct *tsk)
return 0;
 }
 
-static inline void audit_free_context(struct audit_context *context)
+struct audit_context *audit_alloc_local(gfp_t gfpflags)
 {
+   struct audit_context *context;
+
+   context = audit_alloc_context(AUDIT_RECORD_CONTEXT, gfpflags);
+   if (!context) {
+   audit_log_lost("out of memory in audit_alloc_local");
+   return NULL;
+   }
+   context->serial = audit_serial();
+   ktime_get_coarse_real_ts64(>ctime);
+   context->local = true;
+   return context;
+}
+EXPORT_SYMBOL(audit_alloc_local);
+
+void audit_free_context(struct audit_context *context)
+{
+   if (!context)
+   return;
audit_free_module(context);
audit_free_names(context);
unroll_tree_refs(context, NULL, 0);
@@ -986,6 +1006,7 @@ static inline void audit_free_context(struct audit_context 
*context)
audit_proctitle_free(context);
kfree(context);
 }
+EXPORT_SYMBOL(audit_free_context);
 
 static int audit_log_pid_context(struct audit_context *context, pid_t pid,

[PATCH ghak90 v10 02/11] audit: add container id

2020-12-21 Thread Richard Guy Briggs
Implement the proc fs write to set the audit container identifier of a
process, emitting an AUDIT_CONTAINER_OP record to document the event.

This is a write from the container orchestrator task to a proc entry of
the form /proc/PID/audit_containerid where PID is the process ID of the
newly created task that is to become the first task in a container, or
an additional task added to a container.

The write expects up to a u64 value (unset: 18446744073709551615).

The writer must have capability CAP_AUDIT_CONTROL.

This will produce a record such as this:
time->Thu Nov 26 10:24:46 2020
type=PROCTITLE msg=audit(1606404286.956:174546): 
proctitle=2F7573722F62696E2F7065726C002D7700636F6E7461696E657269642F74657374
type=SYSCALL msg=audit(1606404286.956:174546): arch=c03e syscall=1 
success=yes exit=19 a0=6 a1=557446a6a650 a2=13 a3=8 items=0 ppid=6827 pid=8724 
auid=0 uid=0 gid=0 euid=0 suid=0 fsuid=0 egid=0 sgid=0 fsgid=0 tty=ttyS0 ses=1 
comm="perl" exe="/usr/bin/perl" 
subj=unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c1023 key=(null)
type=CONTAINER_OP msg=audit(1606404286.956:174546): op=set opid=8771 
contid=4112973747854606336 old-contid=-1

The "op" field indicates an initial set.  The "opid" field is the
object's PID, the process being "contained".  New and old audit
container identifier values are given in the "contid" fields.

It is not permitted to unset the audit container identifier.
A child inherits its parent's audit container identifier.

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.

audit: log drop of contid on exit of last task

Since the life of each audit container indentifier is being tracked, we can
match the creation event with the destruction event.  Log the destruction of
the audit container identifier when the last process in that container exits.

Add support for reading the audit container identifier from the proc
filesystem.  This is a read from the proc entry of the form
/proc/PID/audit_containerid where PID is the process ID of the task
whose audit container identifier is sought.  The read expects up to a u64 value
(unset: 18446744073709551615).  This read requires CAP_AUDIT_CONTROL.

Add an entry to Documentation/ABI for /proc/$pid/audit_containerid.

Please see the github audit kernel issue for the main feature:
  https://github.com/linux-audit/audit-kernel/issues/90
Please see the github audit userspace issue for supporting additions:
  https://github.com/linux-audit/audit-userspace/issues/51
Please see the github audit testsuiite issue for the test case:
  https://github.com/linux-audit/audit-testsuite/issues/64
Please see the github audit wiki for the feature overview:
  https://github.com/linux-audit/audit-kernel/wiki/RFE-Audit-Container-ID

Signed-off-by: Richard Guy Briggs 
Acked-by: Serge Hallyn 
Acked-by: Steve Grubb 
Acked-by: Neil Horman 
Reviewed-by: Ondrej Mosnacek 
---
 .../ABI/testing/procfs-audit_containerid  |  13 ++
 fs/proc/base.c|  56 -
 include/linux/audit.h |   5 +
 include/uapi/linux/audit.h|   2 +
 kernel/audit.c| 210 ++
 kernel/audit.h|   2 +
 kernel/auditsc.c  |   2 +
 7 files changed, 289 insertions(+), 1 deletion(-)
 create mode 100644 Documentation/ABI/testing/procfs-audit_containerid

diff --git a/Documentation/ABI/testing/procfs-audit_containerid 
b/Documentation/ABI/testing/procfs-audit_containerid
new file mode 100644
index ..30ea64790473
--- /dev/null
+++ b/Documentation/ABI/testing/procfs-audit_containerid
@@ -0,0 +1,13 @@
+What:  Audit Container Identifier
+Date:  2020-??
+KernelVersion: 5.10?
+Contact:   linux-au...@redhat.com
+Format:u64
+Users: auditd, libaudit, audit-testsuite, podman(?), container 
orchestrators
+Description:
+   The /proc/$pid/audit_containerid pseudofile it written
+   to set and read to get the audit container identifier of
+   process $pid.  The accessor must have CAP_AUDIT_CONTROL
+   or have its own /proc/$pid/capcontainerid set to write
+   or read.
+
diff --git a/fs/proc/base.c b/fs/proc/base.c
index 0f707003dda5..94895a5750ca 100644
--- a/fs/proc/base.c
+++ b/fs/proc/base.c
@@ -1242,7 +1242,7 @@ static const struct file_operations 
proc_oom_score_adj_operations = {
 };
 
 #ifdef CONFIG_AUDIT
-#define TMPBUF

[PATCH ghak90 v10 04/11] audit: add contid support for signalling the audit daemon

2020-12-21 Thread Richard Guy Briggs
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 
---
 include/linux/audit.h   |   7 +++
 include/uapi/linux/audit.h  |   1 +
 kernel/audit.c  | 116 ++--
 security/selinux/nlmsgtab.c |   1 +
 4 files changed, 120 insertions(+), 5 deletions(-)

diff --git a/include/linux/audit.h b/include/linux/audit.h
index 30c55e6b6a3c..7c1928e75cfe 100644
--- a/include/linux/audit.h
+++ b/include/linux/audit.h
@@ -23,6 +23,13 @@ struct audit_sig_info {
charctx[];
 };
 
+struct audit_sig_info2 {
+   uid_t   uid;
+   pid_t   pid;
+   u32 cid_len;
+   chardata[];
+};
+
 struct audit_buffer;
 struct audit_context;
 struct inode;
diff --git a/include/uapi/linux/audit.h b/include/uapi/linux/audit.h
index c56335e828dc..94dcf3085658 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 0f97fc24a76a..1c2045c48baf 100644
--- a/kernel/audit.c
+++ b/kernel/audit.c
@@ -123,9 +123,11 @@ static u32 audit_backlog_limit = 64;
 static u32 audit_backlog_wait_time = AUDIT_BACKLOG_WAIT_TIME;
 
 /* The identity of the user shutting down the audit system. */
-static kuid_t  audit_sig_uid = INVALID_UID;
-static pid_t   audit_sig_pid = -1;
-static u32 audit_sig_sid;
+static kuid_t  audit_sig_uid = INVALID_UID;
+static pid_t   audit_sig_pid = -1;
+static u32 audit_sig_sid;
+static struct audit_contobj*audit_sig_cid;
+static struct task_struct  *audit_sig_adtsk;
 
 /* Records can be lost in several ways:
0) [suppressed in audit_alloc]
@@ -222,6 +224,7 @@ struct audit_contobj {
u64 id;
struct task_struct  *owner;
refcount_t  refcount;
+   refcount_t  sigflag;
struct rcu_head rcu;
 };
 
@@ -330,6 +333,35 @@ static void _audit_contobj_put(struct audit_contobj *cont)
if (!cont)
return;
if (refcount_dec_and_test(>refcount)) {
+   if (!refcount_read(>sigflag)) {
+   put_task_struct(cont->owner);
+   list_del_rcu(>list);
+   kfree_rcu(cont, rcu);
+   }
+   }
+}
+
+/* rcu_read_lock must be held by caller unless new */
+static struct audit_contobj *_audit_contobj_get_sig_bytask(struct task_struct 
*tsk)
+{
+   struct audit_contobj *cont;
+   struct audit_task_info *info = tsk->audit;
+
+   if (!info)
+   return NULL;
+   cont = info->cont;
+   if (cont)
+   refcount_set(>sigflag, 1);
+   return cont;
+}
+
+/* rcu_read_lock must be held by caller */
+static void _audit_contobj_put_sig(struct audit_contobj *cont)
+{
+   if (!cont)
+   return;
+   refcount_set(>sigflag, 0);
+   if (!refcount_read(>refcount)) {
put_task_struct(cont->owner);
list_del_rcu(>list);
kfree_rcu(cont, rcu);
@@ -430,6 +462,15 @@ void audit_free(struct task_struct *tsk)
 */
tsk->audit = NULL;
kmem_cache_free(audit_task_cache, info);
+   rcu_read_lock();
+   if (audit_sig_adtsk == tsk) {
+   spin_lock(&_audit_contobj_list_lock);
+   _audit_contobj_put_sig(audit_sig_cid);
+   spin_unlock(&_audit_contobj_list_lock);
+   audit_sig_cid = NULL;
+   audit_sig_adtsk = NULL;
+   }
+   rcu_read_unlock();
 }
 
 /**
@@ -1252,6 +1293,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:
@@ -1414,6 +1456,7 @@ static int audit_receive_msg(struct sk_buff *skb, struct 
nlmsghdr *nlh)
struct audit_buffer *ab;
u16   

[PATCH ghak90 v10 03/11] audit: log container info of syscalls

2020-12-21 Thread Richard Guy Briggs
Create a new audit record AUDIT_CONTAINER_ID to document the audit
container identifier of a process if it is present.

Called from audit_log_exit(), syscalls are covered.

Include target_cid references from ptrace and signal.

A sample raw event:
time->Thu Nov 26 10:24:40 2020
type=PROCTITLE msg=audit(1606404280.226:174542): 
proctitle=2F7573722F62696E2F7065726C002D7700636F6E7461696E657269642F74657374
type=PATH msg=audit(1606404280.226:174542): item=1 
name="/tmp/audit-testsuite-dir-8riQ/testsuite-1606404267-WNldVJCr" inode=428 
dev=00:1f mode=0100644 ouid=0 ogid=0 rdev=00:00 
obj=unconfined_u:object_r:user_tmp_t:s0 nametype=CREATE cap_fp=0 cap_fi=0 
cap_fe=0 cap_fver=0 cap_frootid=0
type=PATH msg=audit(1606404280.226:174542): item=0 
name="/tmp/audit-testsuite-dir-8riQ/" inode=427 dev=00:1f mode=040700 ouid=0 
ogid=0 rdev=00:00 obj=unconfined_u:object_r:user_tmp_t:s0 nametype=PARENT 
cap_fp=0 cap_fi=0 cap_fe=0 cap_fver=0 cap_frootid=0
type=CWD msg=audit(1606404280.226:174542): 
cwd="/root/rgb/git/audit-testsuite/tests"
type=SYSCALL msg=audit(1606404280.226:174542): arch=c03e syscall=257 
success=yes exit=6 a0=ff9c a1=557446bd5f10 a2=80241 a3=1b6 items=2 
ppid=8724 pid=8758 auid=0 uid=0 gid=0 euid=0 suid=0 fsuid=0 egid=0 sgid=0 
fsgid=0 tty=ttyS0 ses=1 comm="perl" exe="/usr/bin/perl" 
subj=unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c1023 
key="testsuite-1606404267-WNldVJCr" record=1
type=CONTAINER_ID msg=audit(1606404280.226:174542): record=1 
contid=527940429489930240

Please see the github audit kernel issue for the main feature:
  https://github.com/linux-audit/audit-kernel/issues/90
Please see the github audit userspace issue for supporting additions:
  https://github.com/linux-audit/audit-userspace/issues/51
Please see the github audit testsuiite issue for the test case:
  https://github.com/linux-audit/audit-testsuite/issues/64
Please see the github audit wiki for the feature overview:
  https://github.com/linux-audit/audit-kernel/wiki/RFE-Audit-Container-ID
Signed-off-by: Richard Guy Briggs 
Acked-by: Serge Hallyn 
Acked-by: Steve Grubb 
Acked-by: Neil Horman 
Reviewed-by: Ondrej Mosnacek 
---
 include/uapi/linux/audit.h |  1 +
 kernel/audit.c | 69 ++
 kernel/audit.h |  6 
 kernel/auditsc.c   | 49 ++-
 4 files changed, 117 insertions(+), 8 deletions(-)

diff --git a/include/uapi/linux/audit.h b/include/uapi/linux/audit.h
index 26d65d0882e2..c56335e828dc 100644
--- a/include/uapi/linux/audit.h
+++ b/include/uapi/linux/audit.h
@@ -119,6 +119,7 @@
 #define AUDIT_TIME_ADJNTPVAL   1333/* NTP value adjustment */
 #define AUDIT_BPF  1334/* BPF subsystem */
 #define AUDIT_EVENT_LISTENER   1335/* Task joined multicast read socket */
+#define AUDIT_CONTAINER_ID 1336/* Container ID */
 
 #define AUDIT_AVC  1400/* SE Linux avc denial or grant */
 #define AUDIT_SELINUX_ERR  1401/* Internal SE Linux Errors */
diff --git a/kernel/audit.c b/kernel/audit.c
index a5f7d1d6945e..0f97fc24a76a 100644
--- a/kernel/audit.c
+++ b/kernel/audit.c
@@ -319,6 +319,11 @@ static struct audit_contobj 
*_audit_contobj_get_bytask(struct task_struct *tsk)
return _audit_contobj_get(info->cont);
 }
 
+void *audit_contobj_get_bytask(struct task_struct *tsk)
+{
+   return (void *)_audit_contobj_get_bytask(tsk);
+}
+
 /* _audit_contobj_list_lock must be held by caller */
 static void _audit_contobj_put(struct audit_contobj *cont)
 {
@@ -331,6 +336,17 @@ static void _audit_contobj_put(struct audit_contobj *cont)
}
 }
 
+void audit_contobj_put(void **cont, int count)
+{
+   int i;
+   struct audit_contobj **contobj = (struct audit_contobj **)cont;
+
+   spin_lock(&_audit_contobj_list_lock);
+   for (i = 0; i < count; i++)
+   _audit_contobj_put(contobj[i]);
+   spin_unlock(&_audit_contobj_list_lock);
+}
+
 static inline int audit_hash_contid(u64 contid)
 {
return (contid & (AUDIT_CONTID_BUCKETS-1));
@@ -2327,6 +2343,59 @@ void audit_log_session_info(struct audit_buffer *ab)
audit_log_format(ab, "auid=%u ses=%u", auid, sessionid);
 }
 
+/*
+ * _audit_log_container_id - report container info
+ * @context: task or local context for record
+ * @cont: container object to report
+ *
+ * Returns 0 on record absence, positive integer on valid record id.
+ */
+static int _audit_log_container_id(struct audit_context *context,
+   struct audit_contobj *contobj)
+{
+   struct audit_buffer *ab;
+   int record;
+
+   if (!contobj)
+   return 0;
+   /* Generate AUDIT_CONTAINER_ID record with container ID */
+   ab = audit_log_start(context, GFP_KERNEL, AUDIT_CONTAINER_ID);
+   if (!ab)
+   return 0;
+   audit_log_format(ab, "record=%d contid=%llu&qu

[PATCH ghak90 v10 01/11] audit: collect audit task parameters

2020-12-21 Thread Richard Guy Briggs
The audit-related parameters in struct task_struct should ideally be
collected together and accessed through a standard audit API and the audit
structures made opaque to other kernel subsystems.

Collect the existing loginuid, sessionid and audit_context together in a
new opaque 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.

Please see the upstream github issues
https://github.com/linux-audit/audit-kernel/issues/81
https://github.com/linux-audit/audit-kernel/issues/90

Signed-off-by: Richard Guy Briggs 
Acked-by: Neil Horman 
Reviewed-by: Ondrej Mosnacek 
---
 fs/io-wq.c|   8 +--
 fs/io_uring.c |  16 ++---
 include/linux/audit.h |  49 +-
 include/linux/sched.h |   7 +-
 init/init_task.c  |   3 +-
 init/main.c   |   2 +
 kernel/audit.c| 154 +-
 kernel/audit.h|   7 ++
 kernel/auditsc.c  |  24 ---
 kernel/fork.c |   1 -
 10 files changed, 205 insertions(+), 66 deletions(-)

diff --git a/fs/io-wq.c b/fs/io-wq.c
index 02894df7656d..1c39207f3ffc 100644
--- a/fs/io-wq.c
+++ b/fs/io-wq.c
@@ -496,8 +496,8 @@ static void io_impersonate_work(struct io_worker *worker,
current->signal->rlim[RLIMIT_FSIZE].rlim_cur = RLIM_INFINITY;
io_wq_switch_blkcg(worker, work);
 #ifdef CONFIG_AUDIT
-   current->loginuid = work->identity->loginuid;
-   current->sessionid = work->identity->sessionid;
+   audit_set_loginuid_iouring(work->identity->loginuid);
+   audit_set_sessionid_iouring(work->identity->sessionid);
 #endif
 }
 
@@ -512,8 +512,8 @@ static void io_assign_current_work(struct io_worker *worker,
}
 
 #ifdef CONFIG_AUDIT
-   current->loginuid = KUIDT_INIT(AUDIT_UID_UNSET);
-   current->sessionid = AUDIT_SID_UNSET;
+   audit_set_loginuid_iouring(KUIDT_INIT(AUDIT_UID_UNSET));
+   audit_set_sessionid_iouring(AUDIT_SID_UNSET);
 #endif
 
spin_lock_irq(>lock);
diff --git a/fs/io_uring.c b/fs/io_uring.c
index b42dfa0243bf..a1e178d8b040 100644
--- a/fs/io_uring.c
+++ b/fs/io_uring.c
@@ -1064,8 +1064,8 @@ static void io_init_identity(struct io_identity *id)
id->fs = current->fs;
id->fsize = rlimit(RLIMIT_FSIZE);
 #ifdef CONFIG_AUDIT
-   id->loginuid = current->loginuid;
-   id->sessionid = current->sessionid;
+   id->loginuid = audit_get_loginuid(current);
+   id->sessionid = audit_get_sessionid(current);
 #endif
refcount_set(>count, 1);
 }
@@ -1335,8 +1335,8 @@ static bool io_grab_identity(struct io_kiocb *req)
req->work.flags |= IO_WQ_WORK_CREDS;
}
 #ifdef CONFIG_AUDIT
-   if (!uid_eq(current->loginuid, id->loginuid) ||
-   current->sessionid != id->sessionid)
+   if (!uid_eq(audit_get_loginuid(current), id->loginuid) ||
+   audit_get_sessionid(current) != id->sessionid)
return false;
 #endif
if (!(req->work.flags & IO_WQ_WORK_FS) &&
@@ -6771,8 +6771,8 @@ static int io_sq_thread(void *data)
}
io_sq_thread_associate_blkcg(ctx, _css);
 #ifdef CONFIG_AUDIT
-   current->loginuid = ctx->loginuid;
-   current->sessionid = ctx->sessionid;
+   audit_set_loginuid_iouring(ctx->loginuid);
+   audit_set_sessionid_iouring(ctx->sessionid);
 #endif
 
ret |= __io_sq_thread(ctx, start_jiffies, cap_entries);
@@ -9205,8 +9205,8 @@ static int io_uring_create(unsigned entries, struct 
io_uring_params *p,
ctx->user = user;
ctx->creds = get_current_cred();
 #ifdef CONFIG_AUDIT
-   ctx->loginuid = current->loginuid;
-   ctx->sessionid = current->sessionid;
+   ctx->loginuid = audit_get_loginuid(current);
+   ctx->sessionid = audit_get_sessionid(current);
 #endif
ctx->sqo_task = get_task_struct(current);
 
diff --git a/include/linux/audit.h b/include/linux/audit.h
index 82b7c1116a85..515cc89a7e0c 100644
--- a/include/linux/audit.h
+++ b/include/linux/audit.h
@@ -154,6 +154,9 @@ struct filename;
 #ifdef CONFIG_AUDIT
 /* These are defined in audit.c */
/* Public API */
+extern int  audit_alloc(struct task_struct *task);
+extern void audit_free(struct task_struct *task);
+extern void __init audit_task_init(void);
 extern __printf(4, 5)
 void audit_log(struct audit_context *ctx, gfp_t gfp_mask, int type,
   const char *fmt, ...);
@@ -194,22 +197,26 @@ extern int audit_rule_change(int type, int seq, void 
*data, size_t datasz);
 extern int audit_list_rules_send(struct sk_buff *request_skb, int seq);
 
 extern int audit_set_loginuid(kuid_t lo

[PATCH ghak90 v10 00/11] audit: implement container identifier

2020-12-21 Thread Richard Guy Briggs
te audit_alloc_local() to use ktime_get_coarse_real_ts64()
- add nft_log support
- add call from do_exit() in audit_free() to remove contid from netns
- relegate AUDIT_CONTAINER ref= field (was op=) to debug patch

v4
- preface set with ghak81:"collect audit task parameters"
- add shallyn and sgrubb acks
- rename feature bitmap macro
- rename cid_valid() to audit_contid_valid()
- rename AUDIT_CONTAINER_ID to AUDIT_CONTAINER_OP
- delete audit_get_contid_list() from headers
- move work into inner if, delete "found"
- change netns contid list function names
- move exports for audit_log_contid audit_alloc_local audit_free_context to 
non-syscall patch
- list contids CSV
- pass in gfp flags to audit_alloc_local() (fix audit_alloc_context callers)
- use "local" in lieu of abusing in_syscall for auditsc_get_stamp()
- read_lock(_lock) around children and thread check
- task_lock(tsk) should be taken before first check of tsk->audit
- add spin lock to contid list in aunet
- restrict /proc read to CAP_AUDIT_CONTROL
- remove set again prohibition and inherited flag
- delete contidion spelling fix from patchset, send to netdev/linux-wireless

v3
- switched from containerid in task_struct to audit_task_info (depends on 
ghak81)
- drop INVALID_CID in favour of only AUDIT_CID_UNSET
- check for !audit_task_info, throw -ENOPROTOOPT on set
- changed -EPERM to -EEXIST for parent check
- return AUDIT_CID_UNSET if !audit_enabled
- squash child/thread check patch into AUDIT_CONTAINER_ID patch
- changed -EPERM to -EBUSY for child check
- separate child and thread checks, use -EALREADY for latter
- move addition of op= from ptrace/signal patch to AUDIT_CONTAINER patch
- fix && to || bashism in ptrace/signal patch
- uninline and export function for audit_free_context()
- drop CONFIG_CHANGE, FEATURE_CHANGE, ANOM_ABEND, ANOM_SECCOMP patches
- move audit_enabled check (xt_AUDIT)
- switched from containerid list in struct net to net_generic's struct audit_net
- move containerid list iteration into audit (xt_AUDIT)
- create function to move namespace switch into audit
- switched /proc/PID/ entry from containerid to audit_containerid
- call kzalloc with GFP_ATOMIC on in_atomic() in audit_alloc_context()
- call kzalloc with GFP_ATOMIC on in_atomic() in audit_log_container_info()
- use xt_net(par) instead of sock_net(skb->sk) to get net
- switched record and field names: initial CONTAINER_ID, aux CONTAINER, field 
CONTID
- allow to set own contid
- open code audit_set_containerid
- add contid inherited flag
- ccontainerid and pcontainerid eliminated due to inherited flag
- change name of container list funcitons
- rename containerid to contid
- convert initial container record to syscall aux
- fix spelling mistake of contidion in net/rfkill/core.c to avoid contid name 
collision

v2
- add check for children and threads
- add network namespace container identifier list
- add NETFILTER_PKT audit container identifier logging
- patch description and documentation clean-up and example
- reap unused ppid

Richard Guy Briggs (11):
  audit: collect audit task parameters
  audit: add container id
  audit: log container info of syscalls
  audit: add contid support for signalling the audit daemon
  audit: add support for non-syscall auxiliary records
  audit: add containerid support for user records
  audit: add containerid filtering
  audit: add support for containerid to network namespaces
  audit: contid check descendancy and nesting
  audit: track container nesting
  audit: add capcontid to set contid outside init_user_ns

 .../ABI/testing/procfs-audit_containerid  |  29 +
 fs/io-wq.c|   8 +-
 fs/io_uring.c |  16 +-
 fs/proc/base.c| 110 ++-
 include/linux/audit.h |  83 +-
 include/linux/sched.h |  10 +-
 include/uapi/linux/audit.h|  10 +-
 init/init_task.c  |   3 +-
 init/main.c   |   2 +
 kernel/audit.c| 877 +-
 kernel/audit.h|  19 +
 kernel/auditfilter.c  |  46 +
 kernel/auditsc.c  | 109 ++-
 kernel/fork.c |   1 -
 kernel/nsproxy.c  |   4 +
 kernel/sched/core.c   |  33 +
 net/netfilter/nft_log.c   |  14 +-
 net/netfilter/xt_AUDIT.c  |  14 +-
 security/selinux/nlmsgtab.c   |   1 +
 security/yama/yama_lsm.c  |  33 -
 20 files changed, 1294 insertions(+), 128 deletions(-)
 create mode 100644 Documentation/ABI/testing/procfs-audit_containerid

-- 
2.18.4



Re: [PATCH -next] kernel/audit: convert comma to semicolon

2020-12-11 Thread Richard Guy Briggs
On 2020-12-11 16:42, Zheng Yongjun wrote:
> Replace a comma between expression statements by a semicolon.
> 
> Signed-off-by: Zheng Yongjun 
> ---
>  kernel/audit.c | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
> 
> diff --git a/kernel/audit.c b/kernel/audit.c
> index 68cee3bc8cfe..c8497115be35 100644
> --- a/kernel/audit.c
> +++ b/kernel/audit.c
> @@ -2282,7 +2282,7 @@ static void audit_log_set_loginuid(kuid_t koldloginuid, 
> kuid_t kloginuid,
>  
>   uid = from_kuid(_user_ns, task_uid(current));
>   oldloginuid = from_kuid(_user_ns, koldloginuid);
> - loginuid = from_kuid(_user_ns, kloginuid),
> + loginuid = from_kuid(_user_ns, kloginuid);

Nice catch.  That went unnoticed through 3 patches, the last two mine...
Not quite sure why no compiler complained about it...

Reviewed-by: Richard Guy Briggs 

>   tty = audit_get_tty();
>  
>   audit_log_format(ab, "pid=%d uid=%u", task_tgid_nr(current), uid);

- RGB

--
Richard Guy Briggs 
Sr. S/W Engineer, Kernel Security, Base Operating Systems
Remote, Ottawa, Red Hat Canada
IRC: rgb, SunRaycer
Voice: +1.647.777.2635, Internal: (81) 32635



Re: [PATCH] audit: remove unused macros

2020-11-11 Thread Richard Guy Briggs
On 2020-11-11 14:19, Alex Shi wrote:
> Thanks for comments!
> So here is the v2 according to your suggestion!
> 
> From 033425b6072ff4cee05d6bbffc97cd6a4c13166c Mon Sep 17 00:00:00 2001
> From: Alex Shi 
> Date: Fri, 6 Nov 2020 16:31:22 +0800
> Subject: [PATCH v2] kernel/audit: fix macros warning
> 
> Some unused macros could cause gcc warning:
> kernel/audit.c:68:0: warning: macro "AUDIT_UNINITIALIZED" is not used
> [-Wunused-macros]
> kernel/auditsc.c:104:0: warning: macro "AUDIT_AUX_IPCPERM" is not used
> [-Wunused-macros]
> kernel/auditsc.c:82:0: warning: macro "AUDITSC_INVALID" is not used
> [-Wunused-macros]
> 
> AUDIT_UNINITIALIZED and AUDITSC_INVALID are still meaningful and could
> be used in code.

"and should be incorporated"

> Just remove AUDIT_AUX_IPCPERM.
> 
> Thanks comments from Richard Guy Briggs and Paul Moore.
> 
> Signed-off-by: Alex Shi 
> Cc: Paul Moore 
> Cc: Eric Paris 
> Cc: linux-au...@redhat.com
> Cc: linux-kernel@vger.kernel.org
> ---
>  kernel/audit.c   |  2 +-
>  kernel/auditsc.c | 10 --
>  2 files changed, 5 insertions(+), 7 deletions(-)
> 
> diff --git a/kernel/audit.c b/kernel/audit.c
> index ac0aeaa99937..e22f22bdc000 100644
> --- a/kernel/audit.c
> +++ b/kernel/audit.c
> @@ -67,7 +67,7 @@
>  #define AUDIT_DISABLED   -1
>  #define AUDIT_UNINITIALIZED  0
>  #define AUDIT_INITIALIZED1
> -static int   audit_initialized;
> +static int   audit_initialized = AUDIT_UNINITIALIZED;
>  
>  u32  audit_enabled = AUDIT_OFF;
>  bool audit_ever_enabled = !!AUDIT_OFF;
> diff --git a/kernel/auditsc.c b/kernel/auditsc.c
> index 183d79cc2e12..ea0ed81ddee0 100644
> --- a/kernel/auditsc.c
> +++ b/kernel/auditsc.c
> @@ -102,8 +102,6 @@ struct audit_aux_data {
>   int type;
>  };
>  
> -#define AUDIT_AUX_IPCPERM0
> -
>  /* Number of target pids per aux struct. */
>  #define AUDIT_AUX_PIDS   16
>  
> @@ -552,11 +550,11 @@ static int audit_filter_rules(struct task_struct *tsk,
>   break;
>  
>   case AUDIT_EXIT:
> - if (ctx && ctx->return_valid)
> + if (ctx && ctx->return_valid != AUDITSC_INVALID)
>   result = audit_comparator(ctx->return_code, 
> f->op, f->val);
>   break;
>   case AUDIT_SUCCESS:
> - if (ctx && ctx->return_valid) {
> + if (ctx && ctx->return_valid != AUDITSC_INVALID) {
>   if (f->val)
>   result = 
> audit_comparator(ctx->return_valid, f->op, AUDITSC_SUCCESS);
>   else
> @@ -1488,7 +1486,7 @@ static void audit_log_exit(void)
>context->arch, context->major);
>   if (context->personality != PER_LINUX)
>   audit_log_format(ab, " per=%lx", context->personality);
> - if (context->return_valid)
> + if (context->return_valid != AUDITSC_INVALID)
>   audit_log_format(ab, " success=%s exit=%ld",
>
> (context->return_valid==AUDITSC_SUCCESS)?"yes":"no",
>context->return_code);
> @@ -1625,7 +1623,7 @@ void __audit_free(struct task_struct *tsk)
>* need to log via audit_log_exit().
>*/
>   if (tsk == current && !context->dummy && context->in_syscall) {
> - context->return_valid = 0;
> + context->return_valid = AUDITSC_INVALID;
>   context->return_code = 0;
>  
>   audit_filter_syscall(tsk, context,

This all looks good, but I don't see the initialization of
context->return_valid in audit_alloc_context() that was mentioned for
completeness.

> -- 
> 1.8.3.1
> 

- RGB

--
Richard Guy Briggs 
Sr. S/W Engineer, Kernel Security, Base Operating Systems
Remote, Ottawa, Red Hat Canada
IRC: rgb, SunRaycer
Voice: +1.647.777.2635, Internal: (81) 32635



Re: [PATCH] audit: remove unused macros

2020-11-10 Thread Richard Guy Briggs
On 2020-11-10 21:47, Paul Moore wrote:
> On Tue, Nov 10, 2020 at 10:23 AM Richard Guy Briggs  wrote:
> > On 2020-11-06 16:31, Alex Shi wrote:
> > > Some unused macros could cause gcc warning:
> > > kernel/audit.c:68:0: warning: macro "AUDIT_UNINITIALIZED" is not used
> > > [-Wunused-macros]
> > > kernel/auditsc.c:104:0: warning: macro "AUDIT_AUX_IPCPERM" is not used
> > > [-Wunused-macros]
> > > kernel/auditsc.c:82:0: warning: macro "AUDITSC_INVALID" is not used
> > > [-Wunused-macros]
> > >
> > > remove them to tame gcc.
> > >
> > > Signed-off-by: Alex Shi 
> > > Cc: Paul Moore 
> > > Cc: Eric Paris 
> > > Cc: linux-au...@redhat.com
> > > Cc: linux-kernel@vger.kernel.org
> > > ---
> > >  kernel/audit.c   | 1 -
> > >  kernel/auditsc.c | 3 ---
> > >  2 files changed, 4 deletions(-)
> > >
> > > diff --git a/kernel/audit.c b/kernel/audit.c
> > > index ac0aeaa99937..dfac1e0ca887 100644
> > > --- a/kernel/audit.c
> > > +++ b/kernel/audit.c
> > > @@ -65,7 +65,6 @@
> > >  /* No auditing will take place until audit_initialized == 
> > > AUDIT_INITIALIZED.
> > >   * (Initialization happens after skb_init is called.) */
> > >  #define AUDIT_DISABLED   -1
> > > -#define AUDIT_UNINITIALIZED  0
> > >  #define AUDIT_INITIALIZED1
> > >  static int   audit_initialized;
> >
> > This one is part of a set, so it feels like it should stay, but the code
> > is structured in such a way that it is not necessary.
> 
> Yes, I'd like for us to find a way to keep this if possible.  Let's
> simply initialize "audit_initialized" to AUDIT_UNINITIALIZED in this
> file.  At some point someone will surely complain about not needing to
> initialize to zero, but we can deal with that later.

We could change them to an enum of 1,2,3.  ;-)

> > > diff --git a/kernel/auditsc.c b/kernel/auditsc.c
> > > index 183d79cc2e12..eeb4930d499f 100644
> > > --- a/kernel/auditsc.c
> > > +++ b/kernel/auditsc.c
> > > @@ -80,7 +80,6 @@
> > >  #include "audit.h"
> > >
> > >  /* flags stating the success for a syscall */
> > > -#define AUDITSC_INVALID 0
> > >  #define AUDITSC_SUCCESS 1
> > >  #define AUDITSC_FAILURE 2
> >
> > Same here, but this one should really be fixed by using
> > AUDITSC_INVALID as the value assigned to context->return_valid in
> > __audit_free() to avoid using magic numbers.
> 
> Agreed.
> 
> We could probably explicitly set it in audit_alloc_context() as well
> if we wanted to be complete.

Agreed.

> > Similarly, the compared
> > values in audit_filter_rules() under the AUDIT_EXIT and AUDIT_SUCCESS
> > cases should be "ctx->return_valid != AUDITSC_INVALID" rather than just
> > "ctx->return_valid".  Same in audit_log_exit().
> 
> Agreed.
> 
> > > @@ -102,8 +101,6 @@ struct audit_aux_data {
> > >   int type;
> > >  };
> > >
> > > -#define AUDIT_AUX_IPCPERM0
> > > -
> >
> > Hmmm, this one looks like it was orphaned 15 years ago a couple of
> > months after it was introduced due to this commit:
> > c04049939f88 Steve Grubb  2005-05-13
> > ("AUDIT: Add message types to audit records")
> >
> > Introduced here:
> > 8e633c3fb2a2 David Woodhouse  2005-03-01
> > ("Audit IPC object owner/permission changes.")
> >
> > I agree, remove it.
> 
> No arguments from me.
> 
> --
> paul moore

- RGB

--
Richard Guy Briggs 
Sr. S/W Engineer, Kernel Security, Base Operating Systems
Remote, Ottawa, Red Hat Canada
IRC: rgb, SunRaycer
Voice: +1.647.777.2635, Internal: (81) 32635



Re: [PATCH] audit: remove unused macros

2020-11-10 Thread Richard Guy Briggs
On 2020-11-06 16:31, Alex Shi wrote:
> Some unused macros could cause gcc warning:
> kernel/audit.c:68:0: warning: macro "AUDIT_UNINITIALIZED" is not used
> [-Wunused-macros]
> kernel/auditsc.c:104:0: warning: macro "AUDIT_AUX_IPCPERM" is not used
> [-Wunused-macros]
> kernel/auditsc.c:82:0: warning: macro "AUDITSC_INVALID" is not used
> [-Wunused-macros]
> 
> remove them to tame gcc.
> 
> Signed-off-by: Alex Shi 
> Cc: Paul Moore  
> Cc: Eric Paris  
> Cc: linux-au...@redhat.com 
> Cc: linux-kernel@vger.kernel.org 
> ---
>  kernel/audit.c   | 1 -
>  kernel/auditsc.c | 3 ---
>  2 files changed, 4 deletions(-)
> 
> diff --git a/kernel/audit.c b/kernel/audit.c
> index ac0aeaa99937..dfac1e0ca887 100644
> --- a/kernel/audit.c
> +++ b/kernel/audit.c
> @@ -65,7 +65,6 @@
>  /* No auditing will take place until audit_initialized == AUDIT_INITIALIZED.
>   * (Initialization happens after skb_init is called.) */
>  #define AUDIT_DISABLED   -1
> -#define AUDIT_UNINITIALIZED  0
>  #define AUDIT_INITIALIZED1
>  static int   audit_initialized;

This one is part of a set, so it feels like it should stay, but the code
is structured in such a way that it is not necessary.

> diff --git a/kernel/auditsc.c b/kernel/auditsc.c
> index 183d79cc2e12..eeb4930d499f 100644
> --- a/kernel/auditsc.c
> +++ b/kernel/auditsc.c
> @@ -80,7 +80,6 @@
>  #include "audit.h"
>  
>  /* flags stating the success for a syscall */
> -#define AUDITSC_INVALID 0
>  #define AUDITSC_SUCCESS 1
>  #define AUDITSC_FAILURE 2

Same here, but this one should really be fixed by using
AUDITSC_INVALID as the value assigned to context->return_valid in
__audit_free() to avoid using magic numbers.  Similarly, the compared
values in audit_filter_rules() under the AUDIT_EXIT and AUDIT_SUCCESS
cases should be "ctx->return_valid != AUDITSC_INVALID" rather than just
"ctx->return_valid".  Same in audit_log_exit().

> @@ -102,8 +101,6 @@ struct audit_aux_data {
>   int type;
>  };
>  
> -#define AUDIT_AUX_IPCPERM0
> -

Hmmm, this one looks like it was orphaned 15 years ago a couple of
months after it was introduced due to this commit:
c04049939f88 Steve Grubb  2005-05-13
("AUDIT: Add message types to audit records")

Introduced here:
8e633c3fb2a2 David Woodhouse  2005-03-01 
("Audit IPC object owner/permission changes.")

I agree, remove it.

>  /* Number of target pids per aux struct. */
>  #define AUDIT_AUX_PIDS   16
>  
> -- 
> 1.8.3.1
> 
> --
> Linux-audit mailing list
> linux-au...@redhat.com
> https://www.redhat.com/mailman/listinfo/linux-audit

- RGB

--
Richard Guy Briggs 
Sr. S/W Engineer, Kernel Security, Base Operating Systems
Remote, Ottawa, Red Hat Canada
IRC: rgb, SunRaycer
Voice: +1.647.777.2635, Internal: (81) 32635



Re: [PATCH ghak90 V9 05/13] audit: log container info of syscalls

2020-10-23 Thread Richard Guy Briggs
On 2020-10-22 21:21, Paul Moore wrote:
> On Wed, Oct 21, 2020 at 12:39 PM Richard Guy Briggs  wrote:
> > Here is an exmple I was able to generate after updating the testsuite
> > script to include a signalling example of a nested audit container
> > identifier:
> >
> > 
> > type=PROCTITLE msg=audit(2020-10-21 10:31:16.655:6731) : 
> > proctitle=/usr/bin/perl -w containerid/test
> > type=CONTAINER_ID msg=audit(2020-10-21 10:31:16.655:6731) : 
> > contid=7129731255799087104^941723245477888
> > type=OBJ_PID msg=audit(2020-10-21 10:31:16.655:6731) : opid=115583 
> > oauid=root ouid=root oses=1 
> > obj=unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c1023 ocomm=perl
> > type=CONTAINER_ID msg=audit(2020-10-21 10:31:16.655:6731) : 
> > contid=941723245477888
> > type=OBJ_PID msg=audit(2020-10-21 10:31:16.655:6731) : opid=115580 
> > oauid=root ouid=root oses=1 
> > obj=unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c1023 ocomm=perl
> > type=CONTAINER_ID msg=audit(2020-10-21 10:31:16.655:6731) : 
> > contid=8098399240850112512^941723245477888
> > type=OBJ_PID msg=audit(2020-10-21 10:31:16.655:6731) : opid=115582 
> > oauid=root ouid=root oses=1 
> > obj=unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c1023 ocomm=perl
> > type=SYSCALL msg=audit(2020-10-21 10:31:16.655:6731) : arch=x86_64 
> > syscall=kill success=yes exit=0 a0=0xfffe3c84 a1=SIGTERM a2=0x4d524554 
> > a3=0x0 items=0 ppid=115564 pid=115567 auid=root uid=root gid=root euid=root 
> > suid=root fsuid=root egid=root sgid=root fsgid=root tty=ttyS0 ses=1 
> > comm=perl exe=/usr/bin/perl 
> > subj=unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c1023 
> > key=testsuite-1603290671-AcLtUulY
> > 
> >
> > There are three CONTAINER_ID records which need some way of associating 
> > with OBJ_PID records.  An additional CONTAINER_ID record would be present 
> > if the killing process itself had an audit container identifier.  I think 
> > the most obvious way to connect them is with a pid= field in the 
> > CONTAINER_ID record.
> 
> Using a "pid=" field as a way to link CONTAINER_ID records to other
> records raises a few questions.  What happens if/when we need to
> represent those PIDs in the context of a namespace?  Are we ever going
> to need to link to records which don't have a "pid=" field?  I haven't
> done the homework to know if either of these are a concern right now,
> but I worry that this might become a problem in the future.

Good point about PID namespaces in the future but those accompanying
records will already have to be conditioned for the PID namespace
context that is requesting it, so I don't see this as a showstopper.

I've forgotten about an important one we already hit, which is a network
event that only has a NETFILTER_PKT record, but in that case, there is
no ambiguity since there are no other records associated with that
event.  So the second is already an issue now.  Using
task_tgid_nr(current), in the contid testsuite script network event it
attributed it to ping which caused the event, but we cannot use this
since it wasn't triggered by a syscall and doesn't accurately reflect
the kernel thread that received it.  It could just be set to zero for
network events.

> The idea of using something like "item=" is interesting.  As you
> mention, the "item=" field does present some overlap problems with the
> PATH record, but perhaps we can do something similar.  What if we
> added a "record=" (or similar, I'm not worried about names at this
> point) to each record, reset to 0/1 at the start of each event, and
> when we needed to link records somehow we could add a "related=1,..,N"
> field.  This would potentially be useful beyond just the audit
> container ID work.

Does it make any sense to use the same keyword in each type of record
such as record/records as in PATH/SYSCALL: item/items ?

(I prefer 0-indexed like item=...)

> paul moore

- RGB

--
Richard Guy Briggs 
Sr. S/W Engineer, Kernel Security, Base Operating Systems
Remote, Ottawa, Red Hat Canada
IRC: rgb, SunRaycer
Voice: +1.647.777.2635, Internal: (81) 32635



Re: [PATCH ghak90 V9 05/13] audit: log container info of syscalls

2020-10-21 Thread Richard Guy Briggs
On 2020-10-21 12:49, Steve Grubb wrote:
> On Wednesday, October 21, 2020 12:39:26 PM EDT Richard Guy Briggs wrote:
> > > I think I have a way to generate a signal to multiple targets in one
> > > syscall...  The added challenge is to also give those targets different
> > > audit container identifiers.
> > 
> > Here is an exmple I was able to generate after updating the testsuite
> > script to include a signalling example of a nested audit container
> > identifier:
> > 
> > 
> > type=PROCTITLE msg=audit(2020-10-21 10:31:16.655:6731) :
> > proctitle=/usr/bin/perl -w containerid/test type=CONTAINER_ID
> > msg=audit(2020-10-21 10:31:16.655:6731) :
> > contid=7129731255799087104^941723245477888 type=OBJ_PID
> > msg=audit(2020-10-21 10:31:16.655:6731) : opid=115583 oauid=root ouid=root
> > oses=1 obj=unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c1023
> > ocomm=perl type=CONTAINER_ID msg=audit(2020-10-21 10:31:16.655:6731) :
> > contid=941723245477888 type=OBJ_PID msg=audit(2020-10-21
> > 10:31:16.655:6731) : opid=115580 oauid=root ouid=root oses=1
> > obj=unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c1023 ocomm=perl
> > type=CONTAINER_ID msg=audit(2020-10-21 10:31:16.655:6731) :
> > contid=8098399240850112512^941723245477888 type=OBJ_PID
> > msg=audit(2020-10-21 10:31:16.655:6731) : opid=115582 oauid=root ouid=root
> > oses=1 obj=unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c1023
> > ocomm=perl type=SYSCALL msg=audit(2020-10-21 10:31:16.655:6731) :
> > arch=x86_64 syscall=kill success=yes exit=0 a0=0xfffe3c84 a1=SIGTERM
> > a2=0x4d524554 a3=0x0 items=0 ppid=115564 pid=115567 auid=root uid=root
> > gid=root euid=root suid=root fsuid=root egid=root sgid=root fsgid=root
> > tty=ttyS0 ses=1 comm=perl exe=/usr/bin/perl
> > subj=unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c1023
> > key=testsuite-1603290671-AcLtUulY 
> > 
> > There are three CONTAINER_ID records which need some way of associating
> > with OBJ_PID records.  An additional CONTAINER_ID record would be present
> > if the killing process itself had an audit container identifier.  I think
> > the most obvious way to connect them is with a pid= field in the
> > CONTAINER_ID record.
> 
> pid is the process sending the signal, opid is the process receiving the 
> signal. I think you mean opid?

If the process sending the signal (it has a pid= field) has an audit
container identifier, it will generate a CONTAINER_ID record.  Each
process being signalled (each has an opid= field) that has an audit
container identifier will also generate a CONTAINER_ID record.  The
former will be much more common.  Which do we use in the CONTAINER_ID
record?  Having swinging fields, pid vs opid does not seem like a
reasonable solution.  Do we go back to "ref=pid=..." vs "ref=opid=..."?

> -Steve

- RGB

--
Richard Guy Briggs 
Sr. S/W Engineer, Kernel Security, Base Operating Systems
Remote, Ottawa, Red Hat Canada
IRC: rgb, SunRaycer
Voice: +1.647.777.2635, Internal: (81) 32635



Re: [PATCH ghak90 V9 05/13] audit: log container info of syscalls

2020-10-21 Thread Richard Guy Briggs
On 2020-10-02 15:52, Richard Guy Briggs wrote:
> On 2020-08-21 15:15, Paul Moore wrote:
> > On Wed, Jul 29, 2020 at 3:41 PM Richard Guy Briggs  wrote:
> > > On 2020-07-05 11:10, Paul Moore wrote:
> > > > On Sat, Jun 27, 2020 at 9:22 AM Richard Guy Briggs  
> > > > wrote:
> > 
> > ...
> > 
> > > > > diff --git a/kernel/auditsc.c b/kernel/auditsc.c
> > > > > index f03d3eb0752c..9e79645e5c0e 100644
> > > > > --- a/kernel/auditsc.c
> > > > > +++ b/kernel/auditsc.c
> > > > > @@ -1458,6 +1466,7 @@ static void audit_log_exit(void)
> > > > > struct audit_buffer *ab;
> > > > > struct audit_aux_data *aux;
> > > > > struct audit_names *n;
> > > > > +   struct audit_contobj *cont;
> > > > >
> > > > > context->personality = current->personality;
> > > > >
> > > > > @@ -1541,7 +1550,7 @@ static void audit_log_exit(void)
> > > > > for (aux = context->aux_pids; aux; aux = aux->next) {
> > > > > struct audit_aux_data_pids *axs = (void *)aux;
> > > > >
> > > > > -   for (i = 0; i < axs->pid_count; i++)
> > > > > +   for (i = 0; i < axs->pid_count; i++) {
> > > > > if (audit_log_pid_context(context, 
> > > > > axs->target_pid[i],
> > > > >   axs->target_auid[i],
> > > > >   axs->target_uid[i],
> > > > > @@ -1549,14 +1558,20 @@ static void audit_log_exit(void)
> > > > >   axs->target_sid[i],
> > > > >   
> > > > > axs->target_comm[i]))
> > > > > call_panic = 1;
> > > > > +   audit_log_container_id(context, 
> > > > > axs->target_cid[i]);
> > > > > +   }
> > > >
> > > > It might be nice to see an audit event example including the
> > > > ptrace/signal information.  I'm concerned there may be some confusion
> > > > about associating the different audit container IDs with the correct
> > > > information in the event.
> > >
> > > This is the subject of ghat81, which is a test for ptrace and signal
> > > records.
> > >
> > > This was the reason I had advocated for an op= field since there is a
> > > possibility of multiple contid records per event.
> > 
> > I think an "op=" field is the wrong way to link audit container ID to
> > a particular record.  It may be convenient, but I fear that it would
> > be overloading the field too much.
> 
> Ok, after looking at the field dictionary how about item, rel, ref or rec?
> Item perhaps could be added to the OBJ_PID records, but that might be
> overloading a field that is already used in PATH records.  "rel" for
> relates-to, "ref" for reference to, "rec" for record...  Perhaps pid=
> would be enough to tie this record to the OBJ_PID record or the SYSCALL
> record, but in the case of network events, the pid may refer to a kernel
> thread.
> 
> > Like I said above, I think it would be good to see an audit event
> > example including the ptrace/signal information.  This way we can talk
> > about it on-list and hash out the various solutions if it proves to be
> > a problem.
> 
> See the list posting from 2020-09-29 "auditing signals" pointing to
> ghat81 test case about testing ptrace and signals from 18 months ago.
> 
> I think I have a way to generate a signal to multiple targets in one
> syscall...  The added challenge is to also give those targets different
> audit container identifiers.

Here is an exmple I was able to generate after updating the testsuite
script to include a signalling example of a nested audit container
identifier:


type=PROCTITLE msg=audit(2020-10-21 10:31:16.655:6731) : 
proctitle=/usr/bin/perl -w containerid/test
type=CONTAINER_ID msg=audit(2020-10-21 10:31:16.655:6731) : 
contid=7129731255799087104^941723245477888
type=OBJ_PID msg=audit(2020-10-21 10:31:16.655:6731) : opid=115583 oauid=root 
ouid=root oses=1 obj=unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c1023 
ocomm=perl
type=CONTAINER_ID msg=audit(2020-10-21 10:31:16.655:6731) : 
contid=941723245477888
type=OBJ_PID msg=audit(2020-10-21 1

Re: [PATCH ghak90 V9 11/13] audit: contid check descendancy and nesting

2020-10-06 Thread Richard Guy Briggs
On 2020-08-21 16:13, Paul Moore wrote:
> On Fri, Aug 7, 2020 at 1:10 PM Richard Guy Briggs  wrote:
> > On 2020-07-05 11:11, Paul Moore wrote:
> > > On Sat, Jun 27, 2020 at 9:23 AM Richard Guy Briggs  
> > > wrote:
> > > > Require the target task to be a descendant of the container
> > > > orchestrator/engine.
> 
> If you want to get formal about this, you need to define "target" in
> the sentence above.  Target of what?

The target is the task having its audit container identifier modified by
the orchestrator current task.

> FWIW, I read the above to basically mean that a task can only set the
> audit container ID of processes which are beneath it in the "process
> tree" where the "process tree" is defined as the relationship between
> a parent and children processes such that the children processes are
> branches below the parent process.

Yes.

> I have no problem with that, with the understanding that nesting
> complicates it somewhat.  For example, this isn't true when one of the
> children is a nested orchestrator, is it?

It should still be true if that child is a nested orchestrator that has
not yet spawned any children or threads (or they have all died off).

It does get more complicated when we consider the scenario outlined
below about perceived layer violations...

> > > > You would only change the audit container ID from one set or inherited
> > > > value to another if you were nesting containers.
> 
> I thought we decided we were going to allow an orchestrator to move a
> process between audit container IDs, yes?  no?

We did?  I don't remember anything about that.  Has this been requested?
This seems to violate the rule that we can't change the audit container
identifier once it has been set (other than nesting).  Can you suggest a
use case?

> > > > If changing the contid, the container orchestrator/engine must be a
> > > > descendant and not same orchestrator as the one that set it so it is not
> > > > possible to change the contid of another orchestrator's container.
> 
> Try rephrasing the above please, it isn't clear to me what you are
> trying to say.

This is harder than I expected to rephrase...  It also makes it clear
that there are some scenarios that have not been considered that may
need to be restricted.

Orchestrator A spawned task B which is itself an orchestrator without
chidren yet.  Orchestrator A sets the audit container identifier of B.
Neither A, nor B, nor any other child of A (or any of their
descendants), nor any orchestrator outside the tree of A (uncles, aunts
and cousins are outside), can change the audit container identifier of
B.

Orchestrator B spawns task C.  Here's where it gets tricky.  It seems
like a layer violation for B to spawn a child C and have A reach over B
to set the audit container identifier of C, especially if B is also an
orchestrator.  This all will be especially hard to police if we don't
limit the ability of an orchestrator task to set an audit container
identifier to that orchestrator's immediate children, only once.

> > Are we able to agree on the premises above?  Is anything asserted that
> > should not be and is there anything missing?
> 
> See above.
> 
> If you want to go back to the definitions/assumptions stage, it
> probably isn't worth worrying about the other comments until we get
> the above sorted.

I don't want to.  I'm trying to confirm that we are on the same page.

> paul moore

- RGB

--
Richard Guy Briggs 
Sr. S/W Engineer, Kernel Security, Base Operating Systems
Remote, Ottawa, Red Hat Canada
IRC: rgb, SunRaycer
Voice: +1.647.777.2635, Internal: (81) 32635



Re: [PATCH ghak90 V9 05/13] audit: log container info of syscalls

2020-10-02 Thread Richard Guy Briggs
On 2020-08-21 15:15, Paul Moore wrote:
> On Wed, Jul 29, 2020 at 3:41 PM Richard Guy Briggs  wrote:
> > On 2020-07-05 11:10, Paul Moore wrote:
> > > On Sat, Jun 27, 2020 at 9:22 AM Richard Guy Briggs  
> > > wrote:
> 
> ...
> 
> > > > diff --git a/kernel/auditsc.c b/kernel/auditsc.c
> > > > index f03d3eb0752c..9e79645e5c0e 100644
> > > > --- a/kernel/auditsc.c
> > > > +++ b/kernel/auditsc.c
> > > > @@ -1458,6 +1466,7 @@ static void audit_log_exit(void)
> > > > struct audit_buffer *ab;
> > > > struct audit_aux_data *aux;
> > > > struct audit_names *n;
> > > > +   struct audit_contobj *cont;
> > > >
> > > > context->personality = current->personality;
> > > >
> > > > @@ -1541,7 +1550,7 @@ static void audit_log_exit(void)
> > > > for (aux = context->aux_pids; aux; aux = aux->next) {
> > > > struct audit_aux_data_pids *axs = (void *)aux;
> > > >
> > > > -   for (i = 0; i < axs->pid_count; i++)
> > > > +   for (i = 0; i < axs->pid_count; i++) {
> > > > if (audit_log_pid_context(context, 
> > > > axs->target_pid[i],
> > > >   axs->target_auid[i],
> > > >   axs->target_uid[i],
> > > > @@ -1549,14 +1558,20 @@ static void audit_log_exit(void)
> > > >   axs->target_sid[i],
> > > >   axs->target_comm[i]))
> > > > call_panic = 1;
> > > > +   audit_log_container_id(context, 
> > > > axs->target_cid[i]);
> > > > +   }
> > >
> > > It might be nice to see an audit event example including the
> > > ptrace/signal information.  I'm concerned there may be some confusion
> > > about associating the different audit container IDs with the correct
> > > information in the event.
> >
> > This is the subject of ghat81, which is a test for ptrace and signal
> > records.
> >
> > This was the reason I had advocated for an op= field since there is a
> > possibility of multiple contid records per event.
> 
> I think an "op=" field is the wrong way to link audit container ID to
> a particular record.  It may be convenient, but I fear that it would
> be overloading the field too much.

Ok, after looking at the field dictionary how about item, rel, ref or rec?
Item perhaps could be added to the OBJ_PID records, but that might be
overloading a field that is already used in PATH records.  "rel" for
relates-to, "ref" for reference to, "rec" for record...  Perhaps pid=
would be enough to tie this record to the OBJ_PID record or the SYSCALL
record, but in the case of network events, the pid may refer to a kernel
thread.

> Like I said above, I think it would be good to see an audit event
> example including the ptrace/signal information.  This way we can talk
> about it on-list and hash out the various solutions if it proves to be
> a problem.

See the list posting from 2020-09-29 "auditing signals" pointing to
ghat81 test case about testing ptrace and signals from 18 months ago.

I think I have a way to generate a signal to multiple targets in one
syscall...  The added challenge is to also give those targets different
audit container identifiers.

> > > > @@ -1575,6 +1590,14 @@ static void audit_log_exit(void)
> > > >
> > > > audit_log_proctitle();
> > > >
> > > > +   rcu_read_lock();
> > > > +   cont = _audit_contobj_get(current);
> > > > +   rcu_read_unlock();
> > > > +   audit_log_container_id(context, cont);
> > > > +   rcu_read_lock();
> > > > +   _audit_contobj_put(cont);
> > > > +   rcu_read_unlock();
> > >
> > > Do we need to grab an additional reference for the audit container
> > > object here?  We don't create any additional references here that
> > > persist beyond the lifetime of this function, right?
> >
> > Why do we need another reference?  There's one for each pointer pointing
> > to it and so far we have just one from this task.  Or are you thinking
> > of the contid hash list, which is only added to when a task points to it
> > and gets removed from that l

Re: [PATCH ghak90 V9 06/13] audit: add contid support for signalling the audit daemon

2020-10-02 Thread Richard Guy Briggs
On 2020-08-21 14:48, Paul Moore wrote:
> On Wed, Jul 29, 2020 at 3:00 PM Richard Guy Briggs  wrote:
> > On 2020-07-05 11:10, Paul Moore wrote:
> > > On Sat, Jun 27, 2020 at 9:22 AM Richard Guy Briggs  
> > > 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 
> > > > ---
> > > >  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 {
> > > > charctx[];
> > > >  };
> > > >
> > > > +struct audit_sig_info2 {
> > > > +   uid_t   uid;
> > > > +   pid_t   pid;
> > > > +   u32 cid_len;
> > > > +   chardata[];
> > > > +};
> > > > +
> > > >  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?
> >
> > We have it, see -ESHUTDOWN below.
> 
> That check in audit_set_contid() is checking ->refcount and not
> ->sigflag; ->sigflag is more important in this context, yes?

That contobj isn't findable until it is in the list with a positive
refcount.  If that contobj still exists and the refcount is zero, refuse
to increment it since it is dead.  The only reason it still exists is
the sigflag must be non-zero due to the signal not having been collected
yet or rcu hasn't released it yet after auditd exitted.

> > > > 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;
> > > >  u32audit_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

Re: [PATCH ghak120 V5] audit: trigger accompanying records when no rules present

2020-09-23 Thread Richard Guy Briggs
On 2020-09-23 10:29, Paul Moore wrote:
> On Tue, Sep 22, 2020 at 8:45 AM Richard Guy Briggs  wrote:
> >
> > When there are no audit rules registered, mandatory records (config,
> > etc.) are missing their accompanying records (syscall, proctitle, etc.).
> >
> > This is due to audit context dummy set on syscall entry based on absence
> > of rules that signals that no other records are to be printed.  Clear the 
> > dummy
> > bit if any record is generated, open coding this in audit_log_start().
> >
> > The proctitle context and dummy checks are pointless since the
> > proctitle record will not be printed if no syscall records are printed.
> >
> > The fds array is reset to -1 after the first syscall to indicate it
> > isn't valid any more, but was never set to -1 when the context was
> > allocated to indicate it wasn't yet valid.
> >
> > Check ctx->pwd in audit_log_name().
> >
> > The audit_inode* functions can be called without going through
> > getname_flags() or getname_kernel() that sets audit_names and cwd, so
> > set the cwd in audit_alloc_name() if it has not already been done so due to
> > audit_names being valid and purge all other audit_getcwd() calls.
> >
> > Revert the LSM dump_common_audit_data() LSM_AUDIT_DATA_* cases from the
> > ghak96 patch since they are no longer necessary due to cwd coverage in
> > audit_alloc_name().
> >
> > Thanks to bauen1  for reporting LSM situations in
> > which context->cwd is not valid, inadvertantly fixed by the ghak96 patch.
> >
> > Please see upstream github issue
> > https://github.com/linux-audit/audit-kernel/issues/120
> > This is also related to upstream github issue
> > https://github.com/linux-audit/audit-kernel/issues/96
> >
> > Signed-off-by: Richard Guy Briggs 
> > ---
> > Chagelog:
> > v5:
> > - open code audit_clear_dummy() in audit_log_start()
> > - fix check for ctx->pwd in audit_log_name()
> > - open code _audit_getcwd() contents in audit_alloc_name()
> > - ditch all *audit_getcwd() calls
> >
> > v4:
> > - resubmit after revert
> >
> > v3:
> > - initialize fds[0] to -1
> > - init cwd for ghak96 LSM_AUDIT_DATA_NET:AF_UNIX case
> > - init cwd for audit_inode{,_child}
> >
> > v2:
> > - unconditionally clear dummy
> > - create audit_clear_dummy accessor function
> > - remove proctitle context and dummy checks
> >
> >  include/linux/audit.h |  8 
> >  kernel/audit.c|  3 +++
> >  kernel/auditsc.c  | 27 +++
> >  security/lsm_audit.c  |  5 -
> >  4 files changed, 10 insertions(+), 33 deletions(-)
> 
> I've gone over this revision a couple of times now and it looks okay,
> but past experience is whispering in my ear that perhaps this is
> better to wait on this for the next cycle so it gets a full set of
> -rcX releases.  Thoughts?

I thought I had lots of time since we were just at the end of the
previous cycle when this failed the previous time...  Ran out yet
again...  (there were two weeks of PTO and a devel system rebuild in
there somewhere...)  It isn't my call.

> paul moore

- RGB

--
Richard Guy Briggs 
Sr. S/W Engineer, Kernel Security, Base Operating Systems
Remote, Ottawa, Red Hat Canada
IRC: rgb, SunRaycer
Voice: +1.647.777.2635, Internal: (81) 32635



[PATCH ghak120 V5] audit: trigger accompanying records when no rules present

2020-09-22 Thread Richard Guy Briggs
When there are no audit rules registered, mandatory records (config,
etc.) are missing their accompanying records (syscall, proctitle, etc.).

This is due to audit context dummy set on syscall entry based on absence
of rules that signals that no other records are to be printed.  Clear the dummy
bit if any record is generated, open coding this in audit_log_start().

The proctitle context and dummy checks are pointless since the
proctitle record will not be printed if no syscall records are printed.

The fds array is reset to -1 after the first syscall to indicate it
isn't valid any more, but was never set to -1 when the context was
allocated to indicate it wasn't yet valid.

Check ctx->pwd in audit_log_name().

The audit_inode* functions can be called without going through
getname_flags() or getname_kernel() that sets audit_names and cwd, so
set the cwd in audit_alloc_name() if it has not already been done so due to
audit_names being valid and purge all other audit_getcwd() calls.

Revert the LSM dump_common_audit_data() LSM_AUDIT_DATA_* cases from the
ghak96 patch since they are no longer necessary due to cwd coverage in
audit_alloc_name().

Thanks to bauen1  for reporting LSM situations in
which context->cwd is not valid, inadvertantly fixed by the ghak96 patch.

Please see upstream github issue
https://github.com/linux-audit/audit-kernel/issues/120
This is also related to upstream github issue
https://github.com/linux-audit/audit-kernel/issues/96

Signed-off-by: Richard Guy Briggs 
---
Chagelog:
v5:
- open code audit_clear_dummy() in audit_log_start()
- fix check for ctx->pwd in audit_log_name()
- open code _audit_getcwd() contents in audit_alloc_name()
- ditch all *audit_getcwd() calls

v4:
- resubmit after revert

v3:
- initialize fds[0] to -1
- init cwd for ghak96 LSM_AUDIT_DATA_NET:AF_UNIX case
- init cwd for audit_inode{,_child}

v2:
- unconditionally clear dummy
- create audit_clear_dummy accessor function
- remove proctitle context and dummy checks

 include/linux/audit.h |  8 
 kernel/audit.c|  3 +++
 kernel/auditsc.c  | 27 +++
 security/lsm_audit.c  |  5 -
 4 files changed, 10 insertions(+), 33 deletions(-)

diff --git a/include/linux/audit.h b/include/linux/audit.h
index b3d859831a31..82b7c1116a85 100644
--- a/include/linux/audit.h
+++ b/include/linux/audit.h
@@ -292,7 +292,6 @@ extern void __audit_syscall_entry(int major, unsigned long 
a0, unsigned long a1,
 extern void __audit_syscall_exit(int ret_success, long ret_value);
 extern struct filename *__audit_reusename(const __user char *uptr);
 extern void __audit_getname(struct filename *name);
-extern void __audit_getcwd(void);
 extern void __audit_inode(struct filename *name, const struct dentry *dentry,
unsigned int flags);
 extern void __audit_file(const struct file *);
@@ -351,11 +350,6 @@ static inline void audit_getname(struct filename *name)
if (unlikely(!audit_dummy_context()))
__audit_getname(name);
 }
-static inline void audit_getcwd(void)
-{
-   if (unlikely(audit_context()))
-   __audit_getcwd();
-}
 static inline void audit_inode(struct filename *name,
const struct dentry *dentry,
unsigned int aflags) {
@@ -584,8 +578,6 @@ static inline struct filename *audit_reusename(const __user 
char *name)
 }
 static inline void audit_getname(struct filename *name)
 { }
-static inline void audit_getcwd(void)
-{ }
 static inline void audit_inode(struct filename *name,
const struct dentry *dentry,
unsigned int aflags)
diff --git a/kernel/audit.c b/kernel/audit.c
index 68cee3bc8cfe..dd9d22ba4fd2 100644
--- a/kernel/audit.c
+++ b/kernel/audit.c
@@ -1865,6 +1865,9 @@ struct audit_buffer *audit_log_start(struct audit_context 
*ctx, gfp_t gfp_mask,
}
 
audit_get_stamp(ab->ctx, , );
+   /* cancel dummy context to enable supporting records */
+   if (ctx)
+   ctx->dummy = 0;
audit_log_format(ab, "audit(%llu.%03lu:%u): ",
 (unsigned long long)t.tv_sec, t.tv_nsec/100, 
serial);
 
diff --git a/kernel/auditsc.c b/kernel/auditsc.c
index 8dba8f0983b5..183d79cc2e12 100644
--- a/kernel/auditsc.c
+++ b/kernel/auditsc.c
@@ -929,6 +929,7 @@ static inline struct audit_context 
*audit_alloc_context(enum audit_state state)
context->prio = state == AUDIT_RECORD_CONTEXT ? ~0ULL : 0;
INIT_LIST_HEAD(>killed_trees);
INIT_LIST_HEAD(>names_list);
+   context->fds[0] = -1;
return context;
 }
 
@@ -1367,7 +1368,10 @@ static void audit_log_name(struct audit_context 
*context, struct audit_names *n,
/* name was specified as a relative path and the
 * directory component is the cwd
 */
- 

Re: [[PATCH V4]] audit: trigger accompanying records when no rules present

2020-09-22 Thread Richard Guy Briggs
On 2020-09-21 19:31, Paul Moore wrote:
> On Mon, Sep 21, 2020 at 3:57 PM Richard Guy Briggs  wrote:
> > On 2020-09-15 12:18, Paul Moore wrote:
> > > On Thu, Sep 10, 2020 at 11:03 AM Richard Guy Briggs  
> > > wrote:
> > > >
> > > > When there are no audit rules registered, mandatory records (config,
> > > > etc.) are missing their accompanying records (syscall, proctitle, etc.).
> > > >
> > > > This is due to audit context dummy set on syscall entry based on absence
> > > > of rules that signals that no other records are to be printed.
> > > >
> > > > Clear the dummy bit if any record is generated.
> > > >
> > > > The proctitle context and dummy checks are pointless since the
> > > > proctitle record will not be printed if no syscall records are printed.
> > > >
> > > > The fds array is reset to -1 after the first syscall to indicate it
> > > > isn't valid any more, but was never set to -1 when the context was
> > > > allocated to indicate it wasn't yet valid.
> > > >
> > > > The audit_inode* functions can be called without going through
> > > > getname_flags() or getname_kernel() that sets audit_names and cwd, so
> > > > set the cwd if it has not already been done so due to audit_names being
> > > > valid.
> > > >
> > > > The LSM dump_common_audit_data() LSM_AUDIT_DATA_NET:AF_UNIX case was
> > > > missed with the ghak96 patch, so add that case here.
> > > >
> > > > Thanks to bauen1  for reporting LSM situations in
> > > > which context->cwd is not valid, inadvertantly fixed by the ghak96 
> > > > patch.
> > > >
> > > > Please see upstream github issue
> > > > https://github.com/linux-audit/audit-kernel/issues/120
> > > > This is also related to upstream github issue
> > > > https://github.com/linux-audit/audit-kernel/issues/96
> > > >
> > > > Signed-off-by: Richard Guy Briggs 
> > > > ---
> > > > Passes audit-testsuite.
> > > >
> > > > Chagelog:
> > > > v4:
> > > > - rebase on audit/next v5.9-rc1
> > > > - squash v2+v3fix
> > > > - add pwd NULL check in audit_log_name()
> > > > - resubmit after revert
> > > >
> > > > v3:
> > > > - initialize fds[0] to -1
> > > > - init cwd for ghak96 LSM_AUDIT_DATA_NET:AF_UNIX case
> > > > - init cwd for audit_inode{,_child}
> > > >
> > > > v2:
> > > > - unconditionally clear dummy
> > > > - create audit_clear_dummy accessor function
> > > > - remove proctitle context and dummy checks
> > > >
> > > >  kernel/audit.c   |  1 +
> > > >  kernel/audit.h   |  8 
> > > >  kernel/auditsc.c | 11 +++
> > > >  security/lsm_audit.c |  1 +
> > > >  4 files changed, 17 insertions(+), 4 deletions(-)
> > >
> > > Comments below, but can you elaborate on if any testing was done
> > > beyond the audit-testsuite?
> >
> > Yes, it was tested with audit-testsuite and bauen1's reproducer
> >
> > > > diff --git a/kernel/audit.h b/kernel/audit.h
> > > > index 3b9c0945225a..abcfef58435b 100644
> > > > --- a/kernel/audit.h
> > > > +++ b/kernel/audit.h
> > > > @@ -290,6 +290,13 @@ extern int audit_signal_info_syscall(struct 
> > > > task_struct *t);
> > > >  extern void audit_filter_inodes(struct task_struct *tsk,
> > > > struct audit_context *ctx);
> > > >  extern struct list_head *audit_killed_trees(void);
> > > > +
> > > > +static inline void audit_clear_dummy(struct audit_context *ctx)
> > > > +{
> > > > +   if (ctx)
> > > > +   ctx->dummy = 0;
> > > > +}
> > >
> > > With the only caller being audit_log_start(), should this be moved to
> > > kernel/audit.c?  I'm just not sure this is something we would ever
> > > need (or want) to call from elsewhere, thoughts?
> >
> > Yes, move it, or better yet just open code it.
> 
> Sure.  It might also help to put a one-liner comment in there about why.

No problem.

> > > > diff --git a/kernel/auditsc.c b/kernel/auditsc.c
> > > > index 8dba8f0983b5..9d2de93f40b3 100644
> > > > --- a/kernel/auditsc.c
> > > > +++ b/kernel/auditsc.c
&g

Re: [[PATCH V4]] audit: trigger accompanying records when no rules present

2020-09-21 Thread Richard Guy Briggs
On 2020-09-15 12:18, Paul Moore wrote:
> On Thu, Sep 10, 2020 at 11:03 AM Richard Guy Briggs  wrote:
> >
> > When there are no audit rules registered, mandatory records (config,
> > etc.) are missing their accompanying records (syscall, proctitle, etc.).
> >
> > This is due to audit context dummy set on syscall entry based on absence
> > of rules that signals that no other records are to be printed.
> >
> > Clear the dummy bit if any record is generated.
> >
> > The proctitle context and dummy checks are pointless since the
> > proctitle record will not be printed if no syscall records are printed.
> >
> > The fds array is reset to -1 after the first syscall to indicate it
> > isn't valid any more, but was never set to -1 when the context was
> > allocated to indicate it wasn't yet valid.
> >
> > The audit_inode* functions can be called without going through
> > getname_flags() or getname_kernel() that sets audit_names and cwd, so
> > set the cwd if it has not already been done so due to audit_names being
> > valid.
> >
> > The LSM dump_common_audit_data() LSM_AUDIT_DATA_NET:AF_UNIX case was
> > missed with the ghak96 patch, so add that case here.
> >
> > Thanks to bauen1  for reporting LSM situations in
> > which context->cwd is not valid, inadvertantly fixed by the ghak96 patch.
> >
> > Please see upstream github issue
> > https://github.com/linux-audit/audit-kernel/issues/120
> > This is also related to upstream github issue
> > https://github.com/linux-audit/audit-kernel/issues/96
> >
> > Signed-off-by: Richard Guy Briggs 
> > ---
> > Passes audit-testsuite.
> >
> > Chagelog:
> > v4:
> > - rebase on audit/next v5.9-rc1
> > - squash v2+v3fix
> > - add pwd NULL check in audit_log_name()
> > - resubmit after revert
> >
> > v3:
> > - initialize fds[0] to -1
> > - init cwd for ghak96 LSM_AUDIT_DATA_NET:AF_UNIX case
> > - init cwd for audit_inode{,_child}
> >
> > v2:
> > - unconditionally clear dummy
> > - create audit_clear_dummy accessor function
> > - remove proctitle context and dummy checks
> >
> >  kernel/audit.c   |  1 +
> >  kernel/audit.h   |  8 
> >  kernel/auditsc.c | 11 +++
> >  security/lsm_audit.c |  1 +
> >  4 files changed, 17 insertions(+), 4 deletions(-)
> 
> Comments below, but can you elaborate on if any testing was done
> beyond the audit-testsuite?

Yes, it was tested with audit-testsuite and bauen1's reproducer

> > diff --git a/kernel/audit.h b/kernel/audit.h
> > index 3b9c0945225a..abcfef58435b 100644
> > --- a/kernel/audit.h
> > +++ b/kernel/audit.h
> > @@ -290,6 +290,13 @@ extern int audit_signal_info_syscall(struct 
> > task_struct *t);
> >  extern void audit_filter_inodes(struct task_struct *tsk,
> > struct audit_context *ctx);
> >  extern struct list_head *audit_killed_trees(void);
> > +
> > +static inline void audit_clear_dummy(struct audit_context *ctx)
> > +{
> > +   if (ctx)
> > +   ctx->dummy = 0;
> > +}
> 
> With the only caller being audit_log_start(), should this be moved to
> kernel/audit.c?  I'm just not sure this is something we would ever
> need (or want) to call from elsewhere, thoughts?

Yes, move it, or better yet just open code it.

> > diff --git a/kernel/auditsc.c b/kernel/auditsc.c
> > index 8dba8f0983b5..9d2de93f40b3 100644
> > --- a/kernel/auditsc.c
> > +++ b/kernel/auditsc.c
> > @@ -1367,7 +1368,10 @@ static void audit_log_name(struct audit_context 
> > *context, struct audit_names *n,
> > /* name was specified as a relative path and the
> >  * directory component is the cwd
> >  */
> > -   audit_log_d_path(ab, " name=", >pwd);
> > +   if (>pwd)
> 
> Hmm, I don't think this is going to work the way you are intending; I
> believe this will always evaluate to true regardless of the state of
> context->pwd.  If you look elsewhere in kernel/auditsc.c you will see
> some examples of checking to see if context->pwd is valid (e.g.
> _audit_getcwd() and audit_log_exit()).

Sorry for the ctx->pwd.dentry/mnt brainfart, the compiler *did*
complain.

> > +   audit_log_d_path(ab, " name=", 
> > >pwd);
> > +   else
> > +   audit_log_format(ab, " name=(null)");
> > 

[[PATCH V4]] audit: trigger accompanying records when no rules present

2020-09-10 Thread Richard Guy Briggs
When there are no audit rules registered, mandatory records (config,
etc.) are missing their accompanying records (syscall, proctitle, etc.).

This is due to audit context dummy set on syscall entry based on absence
of rules that signals that no other records are to be printed.

Clear the dummy bit if any record is generated.

The proctitle context and dummy checks are pointless since the
proctitle record will not be printed if no syscall records are printed.

The fds array is reset to -1 after the first syscall to indicate it
isn't valid any more, but was never set to -1 when the context was
allocated to indicate it wasn't yet valid.

The audit_inode* functions can be called without going through
getname_flags() or getname_kernel() that sets audit_names and cwd, so
set the cwd if it has not already been done so due to audit_names being
valid.

The LSM dump_common_audit_data() LSM_AUDIT_DATA_NET:AF_UNIX case was
missed with the ghak96 patch, so add that case here.

Thanks to bauen1  for reporting LSM situations in
which context->cwd is not valid, inadvertantly fixed by the ghak96 patch.

Please see upstream github issue
https://github.com/linux-audit/audit-kernel/issues/120
This is also related to upstream github issue
https://github.com/linux-audit/audit-kernel/issues/96

Signed-off-by: Richard Guy Briggs 
---
Passes audit-testsuite.

Chagelog:
v4:
- rebase on audit/next v5.9-rc1
- squash v2+v3fix
- add pwd NULL check in audit_log_name()
- resubmit after revert

v3:
- initialize fds[0] to -1
- init cwd for ghak96 LSM_AUDIT_DATA_NET:AF_UNIX case
- init cwd for audit_inode{,_child}

v2:
- unconditionally clear dummy
- create audit_clear_dummy accessor function
- remove proctitle context and dummy checks

 kernel/audit.c   |  1 +
 kernel/audit.h   |  8 
 kernel/auditsc.c | 11 +++
 security/lsm_audit.c |  1 +
 4 files changed, 17 insertions(+), 4 deletions(-)

diff --git a/kernel/audit.c b/kernel/audit.c
index 68cee3bc8cfe..8604eccb348f 100644
--- a/kernel/audit.c
+++ b/kernel/audit.c
@@ -1865,6 +1865,7 @@ struct audit_buffer *audit_log_start(struct audit_context 
*ctx, gfp_t gfp_mask,
}
 
audit_get_stamp(ab->ctx, , );
+   audit_clear_dummy(ab->ctx);
audit_log_format(ab, "audit(%llu.%03lu:%u): ",
 (unsigned long long)t.tv_sec, t.tv_nsec/100, 
serial);
 
diff --git a/kernel/audit.h b/kernel/audit.h
index 3b9c0945225a..abcfef58435b 100644
--- a/kernel/audit.h
+++ b/kernel/audit.h
@@ -290,6 +290,13 @@ extern int audit_signal_info_syscall(struct task_struct 
*t);
 extern void audit_filter_inodes(struct task_struct *tsk,
struct audit_context *ctx);
 extern struct list_head *audit_killed_trees(void);
+
+static inline void audit_clear_dummy(struct audit_context *ctx)
+{
+   if (ctx)
+   ctx->dummy = 0;
+}
+
 #else /* CONFIG_AUDITSYSCALL */
 #define auditsc_get_stamp(c, t, s) 0
 #define audit_put_watch(w) {}
@@ -323,6 +330,7 @@ static inline int audit_signal_info_syscall(struct 
task_struct *t)
 }
 
 #define audit_filter_inodes(t, c) AUDIT_DISABLED
+#define audit_clear_dummy(c) {}
 #endif /* CONFIG_AUDITSYSCALL */
 
 extern char *audit_unpack_string(void **bufp, size_t *remain, size_t len);
diff --git a/kernel/auditsc.c b/kernel/auditsc.c
index 8dba8f0983b5..9d2de93f40b3 100644
--- a/kernel/auditsc.c
+++ b/kernel/auditsc.c
@@ -929,6 +929,7 @@ static inline struct audit_context 
*audit_alloc_context(enum audit_state state)
context->prio = state == AUDIT_RECORD_CONTEXT ? ~0ULL : 0;
INIT_LIST_HEAD(>killed_trees);
INIT_LIST_HEAD(>names_list);
+   context->fds[0] = -1;
return context;
 }
 
@@ -1367,7 +1368,10 @@ static void audit_log_name(struct audit_context 
*context, struct audit_names *n,
/* name was specified as a relative path and the
 * directory component is the cwd
 */
-   audit_log_d_path(ab, " name=", >pwd);
+   if (>pwd)
+   audit_log_d_path(ab, " name=", >pwd);
+   else
+   audit_log_format(ab, " name=(null)");
break;
default:
/* log the name's directory component */
@@ -1435,9 +1439,6 @@ static void audit_log_proctitle(void)
struct audit_context *context = audit_context();
struct audit_buffer *ab;
 
-   if (!context || context->dummy)
-   return;
-
ab = audit_log_start(context, GFP_KERNEL, AUDIT_PROCTITLE);
if (!ab)
return; /* audit_panic or being filtered */
@@ -2079,6 +2080,7 @@ void __audit_inode(struct filename *name, const struct 
dentry *dentry,
}
handle_path(dentry);
audit_copy_inode(n, dentry, inode, flags & AUDIT_INODE_NO

  1   2   3   4   5   6   7   8   9   10   >