diff mbox series

[v23,19/23] audit: add support for non-syscall auxiliary records

Message ID 20201120201507.11993-20-casey@schaufler-ca.com (mailing list archive)
State New
Delegated to: Paul Moore
Headers show
Series [v23,01/23] LSM: Infrastructure management of the sock security | expand

Commit Message

Casey Schaufler Nov. 20, 2020, 8:15 p.m. UTC
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 <rgb@redhat.com>
Signed-off-by: Casey Schaufler <casey@schaufler-ca.com>
Cc: linux-audit@redhat.com
To: Richard Guy Briggs <rgb@redhat.com>
---
 include/linux/audit.h |  8 ++++++++
 kernel/audit.h        |  1 +
 kernel/auditsc.c      | 33 ++++++++++++++++++++++++++++-----
 3 files changed, 37 insertions(+), 5 deletions(-)

Comments

kernel test robot Nov. 20, 2020, 11:06 p.m. UTC | #1
Hi Casey,

I love your patch! Yet something to improve:

[auto build test ERROR on nf/master]
[also build test ERROR on linus/master v5.10-rc4 next-20201120]
[cannot apply to nf-next/master security/next-testing]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch]

url:    https://github.com/0day-ci/linux/commits/Casey-Schaufler/LSM-Module-stacking-for-AppArmor/20201121-044616
base:   https://git.kernel.org/pub/scm/linux/kernel/git/pablo/nf.git master
config: i386-randconfig-s001-20201120 (attached as .config)
compiler: gcc-9 (Debian 9.3.0-15) 9.3.0
reproduce:
        # apt-get install sparse
        # sparse version: v0.6.3-134-gb59dbdaf-dirty
        # https://github.com/0day-ci/linux/commit/3b464b0251cffe5ac73c81b701fd8d146664a7a3
        git remote add linux-review https://github.com/0day-ci/linux
        git fetch --no-tags linux-review Casey-Schaufler/LSM-Module-stacking-for-AppArmor/20201121-044616
        git checkout 3b464b0251cffe5ac73c81b701fd8d146664a7a3
        # save the attached .config to linux build tree
        make W=1 C=1 CF='-fdiagnostic-prefix -D__CHECK_ENDIAN__' ARCH=i386 

If you fix the issue, kindly add following tag as appropriate
Reported-by: kernel test robot <lkp@intel.com>

All errors (new ones prefixed by >>):

   In file included from include/linux/fsnotify.h:16,
                    from fs/remap_range.c:8:
>> include/linux/audit.h:563:1: error: expected identifier or '(' before '+' token
     563 | +static inline struct audit_context *audit_alloc_local(gfp_t gfpflags)
         | ^
--
   In file included from fs/pipe.c:23:
>> include/linux/audit.h:563:1: error: expected identifier or '(' before '+' token
     563 | +static inline struct audit_context *audit_alloc_local(gfp_t gfpflags)
         | ^
   fs/pipe.c:741:15: warning: no previous prototype for 'account_pipe_buffers' [-Wmissing-prototypes]
     741 | unsigned long account_pipe_buffers(struct user_struct *user,
         |               ^~~~~~~~~~~~~~~~~~~~
   fs/pipe.c:747:6: warning: no previous prototype for 'too_many_pipe_buffers_soft' [-Wmissing-prototypes]
     747 | bool too_many_pipe_buffers_soft(unsigned long user_bufs)
         |      ^~~~~~~~~~~~~~~~~~~~~~~~~~
   fs/pipe.c:754:6: warning: no previous prototype for 'too_many_pipe_buffers_hard' [-Wmissing-prototypes]
     754 | bool too_many_pipe_buffers_hard(unsigned long user_bufs)
         |      ^~~~~~~~~~~~~~~~~~~~~~~~~~
   fs/pipe.c:761:6: warning: no previous prototype for 'pipe_is_unprivileged_user' [-Wmissing-prototypes]
     761 | bool pipe_is_unprivileged_user(void)
         |      ^~~~~~~~~~~~~~~~~~~~~~~~~
   fs/pipe.c:1230:5: warning: no previous prototype for 'pipe_resize_ring' [-Wmissing-prototypes]
    1230 | int pipe_resize_ring(struct pipe_inode_info *pipe, unsigned int nr_slots)
         |     ^~~~~~~~~~~~~~~~

vim +563 include/linux/audit.h

   559	
   560	extern int audit_n_rules;
   561	extern int audit_signals;
   562	#else /* CONFIG_AUDITSYSCALL */
 > 563	+static inline struct audit_context *audit_alloc_local(gfp_t gfpflags)
   564	{
   565		return NULL;
   566	}
   567	static inline void audit_free_context(struct audit_context *context)
   568	{ }
   569	static inline int audit_alloc(struct task_struct *task)
   570	{
   571		return 0;
   572	}
   573	static inline void audit_free(struct task_struct *task)
   574	{ }
   575	static inline void audit_syscall_entry(int major, unsigned long a0,
   576					       unsigned long a1, unsigned long a2,
   577					       unsigned long a3)
   578	{ }
   579	static inline void audit_syscall_exit(void *pt_regs)
   580	{ }
   581	static inline bool audit_dummy_context(void)
   582	{
   583		return true;
   584	}
   585	static inline void audit_set_context(struct task_struct *task, struct audit_context *ctx)
   586	{ }
   587	static inline struct audit_context *audit_context(void)
   588	{
   589		return NULL;
   590	}
   591	static inline struct filename *audit_reusename(const __user char *name)
   592	{
   593		return NULL;
   594	}
   595	static inline void audit_getname(struct filename *name)
   596	{ }
   597	static inline void audit_getcwd(void)
   598	{ }
   599	static inline void audit_inode(struct filename *name,
   600					const struct dentry *dentry,
   601					unsigned int aflags)
   602	{ }
   603	static inline void audit_file(struct file *file)
   604	{
   605	}
   606	static inline void audit_inode_parent_hidden(struct filename *name,
   607					const struct dentry *dentry)
   608	{ }
   609	static inline void audit_inode_child(struct inode *parent,
   610					     const struct dentry *dentry,
   611					     const unsigned char type)
   612	{ }
   613	static inline void audit_core_dumps(long signr)
   614	{ }
   615	static inline void audit_seccomp(unsigned long syscall, long signr, int code)
   616	{ }
   617	static inline void audit_seccomp_actions_logged(const char *names,
   618							const char *old_names, int res)
   619	{ }
   620	static inline void audit_ipc_obj(struct kern_ipc_perm *ipcp)
   621	{ }
   622	static inline void audit_ipc_set_perm(unsigned long qbytes, uid_t uid,
   623						gid_t gid, umode_t mode)
   624	{ }
   625	static inline void audit_bprm(struct linux_binprm *bprm)
   626	{ }
   627	static inline int audit_socketcall(int nargs, unsigned long *args)
   628	{
   629		return 0;
   630	}
   631	

---
0-DAY CI Kernel Test Service, Intel Corporation
https://lists.01.org/hyperkitty/list/kbuild-all@lists.01.org
kernel test robot Nov. 21, 2020, 7:36 a.m. UTC | #2
Hi Casey,

I love your patch! Yet something to improve:

[auto build test ERROR on nf/master]
[also build test ERROR on linus/master v5.10-rc4 next-20201120]
[cannot apply to nf-next/master security/next-testing]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch]

url:    https://github.com/0day-ci/linux/commits/Casey-Schaufler/LSM-Module-stacking-for-AppArmor/20201121-044616
base:   https://git.kernel.org/pub/scm/linux/kernel/git/pablo/nf.git master
config: x86_64-randconfig-a015-20201120 (attached as .config)
compiler: clang version 12.0.0 (https://github.com/llvm/llvm-project 3ded927cf80ac519f9f9c4664fef08787f7c537d)
reproduce (this is a W=1 build):
        wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
        chmod +x ~/bin/make.cross
        # install x86_64 cross compiling tool for clang build
        # apt-get install binutils-x86-64-linux-gnu
        # https://github.com/0day-ci/linux/commit/3b464b0251cffe5ac73c81b701fd8d146664a7a3
        git remote add linux-review https://github.com/0day-ci/linux
        git fetch --no-tags linux-review Casey-Schaufler/LSM-Module-stacking-for-AppArmor/20201121-044616
        git checkout 3b464b0251cffe5ac73c81b701fd8d146664a7a3
        # save the attached .config to linux build tree
        COMPILER_INSTALL_PATH=$HOME/0day COMPILER=clang make.cross ARCH=x86_64 

If you fix the issue, kindly add following tag as appropriate
Reported-by: kernel test robot <lkp@intel.com>

All errors (new ones prefixed by >>):

   In file included from drivers/net/gtp.c:30:
   In file included from include/net/xfrm.h:15:
>> include/linux/audit.h:563:1: error: expected external declaration
   +static inline struct audit_context *audit_alloc_local(gfp_t gfpflags)
   ^
   1 error generated.
--
   In file included from drivers/net/ethernet/intel/ixgbe/ixgbe_main.c:40:
   In file included from include/net/xfrm.h:15:
>> include/linux/audit.h:563:1: error: expected external declaration
   +static inline struct audit_context *audit_alloc_local(gfp_t gfpflags)
   ^
   drivers/net/ethernet/intel/ixgbe/ixgbe_main.c:8108:14: warning: division by zero is undefined [-Wdivision-by-zero]
           cmd_type |= IXGBE_SET_FLAG(tx_flags, IXGBE_TX_FLAGS_HW_VLAN,
                       ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   drivers/net/ethernet/intel/ixgbe/ixgbe_main.c:8098:26: note: expanded from macro 'IXGBE_SET_FLAG'
            ((u32)(_input & _flag) / (_flag / _result)))
                                   ^ ~~~~~~~~~~~~~~~~~
   drivers/net/ethernet/intel/ixgbe/ixgbe_main.c:8112:14: warning: division by zero is undefined [-Wdivision-by-zero]
           cmd_type |= IXGBE_SET_FLAG(tx_flags, IXGBE_TX_FLAGS_TSO,
                       ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   drivers/net/ethernet/intel/ixgbe/ixgbe_main.c:8098:26: note: expanded from macro 'IXGBE_SET_FLAG'
            ((u32)(_input & _flag) / (_flag / _result)))
                                   ^ ~~~~~~~~~~~~~~~~~
   drivers/net/ethernet/intel/ixgbe/ixgbe_main.c:8116:14: warning: division by zero is undefined [-Wdivision-by-zero]
           cmd_type |= IXGBE_SET_FLAG(tx_flags, IXGBE_TX_FLAGS_TSTAMP,
                       ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   drivers/net/ethernet/intel/ixgbe/ixgbe_main.c:8098:26: note: expanded from macro 'IXGBE_SET_FLAG'
            ((u32)(_input & _flag) / (_flag / _result)))
                                   ^ ~~~~~~~~~~~~~~~~~
   drivers/net/ethernet/intel/ixgbe/ixgbe_main.c:8120:14: warning: division by zero is undefined [-Wdivision-by-zero]
           cmd_type ^= IXGBE_SET_FLAG(skb->no_fcs, 1, IXGBE_ADVTXD_DCMD_IFCS);
                       ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   drivers/net/ethernet/intel/ixgbe/ixgbe_main.c:8098:26: note: expanded from macro 'IXGBE_SET_FLAG'
            ((u32)(_input & _flag) / (_flag / _result)))
                                   ^ ~~~~~~~~~~~~~~~~~
   drivers/net/ethernet/intel/ixgbe/ixgbe_main.c:8131:19: warning: division by zero is undefined [-Wdivision-by-zero]
           olinfo_status |= IXGBE_SET_FLAG(tx_flags,
                            ^~~~~~~~~~~~~~~~~~~~~~~~
   drivers/net/ethernet/intel/ixgbe/ixgbe_main.c:8098:26: note: expanded from macro 'IXGBE_SET_FLAG'
            ((u32)(_input & _flag) / (_flag / _result)))
                                   ^ ~~~~~~~~~~~~~~~~~
   drivers/net/ethernet/intel/ixgbe/ixgbe_main.c:8136:19: warning: division by zero is undefined [-Wdivision-by-zero]
           olinfo_status |= IXGBE_SET_FLAG(tx_flags,
                            ^~~~~~~~~~~~~~~~~~~~~~~~
   drivers/net/ethernet/intel/ixgbe/ixgbe_main.c:8098:26: note: expanded from macro 'IXGBE_SET_FLAG'
            ((u32)(_input & _flag) / (_flag / _result)))
                                   ^ ~~~~~~~~~~~~~~~~~
   drivers/net/ethernet/intel/ixgbe/ixgbe_main.c:8141:19: warning: division by zero is undefined [-Wdivision-by-zero]
           olinfo_status |= IXGBE_SET_FLAG(tx_flags,
                            ^~~~~~~~~~~~~~~~~~~~~~~~
   drivers/net/ethernet/intel/ixgbe/ixgbe_main.c:8098:26: note: expanded from macro 'IXGBE_SET_FLAG'
            ((u32)(_input & _flag) / (_flag / _result)))
                                   ^ ~~~~~~~~~~~~~~~~~
   drivers/net/ethernet/intel/ixgbe/ixgbe_main.c:8149:19: warning: division by zero is undefined [-Wdivision-by-zero]
           olinfo_status |= IXGBE_SET_FLAG(tx_flags,
                            ^~~~~~~~~~~~~~~~~~~~~~~~
   drivers/net/ethernet/intel/ixgbe/ixgbe_main.c:8098:26: note: expanded from macro 'IXGBE_SET_FLAG'
            ((u32)(_input & _flag) / (_flag / _result)))
                                   ^ ~~~~~~~~~~~~~~~~~
   drivers/net/ethernet/intel/ixgbe/ixgbe_main.c:10621:45: warning: shift count >= width of type [-Wshift-count-overflow]
           if (!dma_set_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(64))) {
                                                      ^~~~~~~~~~~~~~~~
   include/linux/dma-mapping.h:76:54: note: expanded from macro 'DMA_BIT_MASK'
   #define DMA_BIT_MASK(n) (((n) == 64) ? ~0ULL : ((1ULL<<(n))-1))
                                                        ^ ~~~
   9 warnings and 1 error generated.
--
   In file included from drivers/net/ethernet/intel/ixgbevf/ixgbevf_main.c:33:
   In file included from include/net/xfrm.h:15:
>> include/linux/audit.h:563:1: error: expected external declaration
   +static inline struct audit_context *audit_alloc_local(gfp_t gfpflags)
   ^
   drivers/net/ethernet/intel/ixgbevf/ixgbevf_main.c:4529:45: warning: shift count >= width of type [-Wshift-count-overflow]
           if (!dma_set_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(64))) {
                                                      ^~~~~~~~~~~~~~~~
   include/linux/dma-mapping.h:76:54: note: expanded from macro 'DMA_BIT_MASK'
   #define DMA_BIT_MASK(n) (((n) == 64) ? ~0ULL : ((1ULL<<(n))-1))
                                                        ^ ~~~
   1 warning and 1 error generated.

vim +563 include/linux/audit.h

   559	
   560	extern int audit_n_rules;
   561	extern int audit_signals;
   562	#else /* CONFIG_AUDITSYSCALL */
 > 563	+static inline struct audit_context *audit_alloc_local(gfp_t gfpflags)
   564	{
   565		return NULL;
   566	}
   567	static inline void audit_free_context(struct audit_context *context)
   568	{ }
   569	static inline int audit_alloc(struct task_struct *task)
   570	{
   571		return 0;
   572	}
   573	static inline void audit_free(struct task_struct *task)
   574	{ }
   575	static inline void audit_syscall_entry(int major, unsigned long a0,
   576					       unsigned long a1, unsigned long a2,
   577					       unsigned long a3)
   578	{ }
   579	static inline void audit_syscall_exit(void *pt_regs)
   580	{ }
   581	static inline bool audit_dummy_context(void)
   582	{
   583		return true;
   584	}
   585	static inline void audit_set_context(struct task_struct *task, struct audit_context *ctx)
   586	{ }
   587	static inline struct audit_context *audit_context(void)
   588	{
   589		return NULL;
   590	}
   591	static inline struct filename *audit_reusename(const __user char *name)
   592	{
   593		return NULL;
   594	}
   595	static inline void audit_getname(struct filename *name)
   596	{ }
   597	static inline void audit_getcwd(void)
   598	{ }
   599	static inline void audit_inode(struct filename *name,
   600					const struct dentry *dentry,
   601					unsigned int aflags)
   602	{ }
   603	static inline void audit_file(struct file *file)
   604	{
   605	}
   606	static inline void audit_inode_parent_hidden(struct filename *name,
   607					const struct dentry *dentry)
   608	{ }
   609	static inline void audit_inode_child(struct inode *parent,
   610					     const struct dentry *dentry,
   611					     const unsigned char type)
   612	{ }
   613	static inline void audit_core_dumps(long signr)
   614	{ }
   615	static inline void audit_seccomp(unsigned long syscall, long signr, int code)
   616	{ }
   617	static inline void audit_seccomp_actions_logged(const char *names,
   618							const char *old_names, int res)
   619	{ }
   620	static inline void audit_ipc_obj(struct kern_ipc_perm *ipcp)
   621	{ }
   622	static inline void audit_ipc_set_perm(unsigned long qbytes, uid_t uid,
   623						gid_t gid, umode_t mode)
   624	{ }
   625	static inline void audit_bprm(struct linux_binprm *bprm)
   626	{ }
   627	static inline int audit_socketcall(int nargs, unsigned long *args)
   628	{
   629		return 0;
   630	}
   631	

---
0-DAY CI Kernel Test Service, Intel Corporation
https://lists.01.org/hyperkitty/list/kbuild-all@lists.01.org
diff mbox series

Patch

diff --git a/include/linux/audit.h b/include/linux/audit.h
index ba1cd38d601b..786d065a64ef 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);
@@ -558,6 +560,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 */
+	bool		    local;	/* local context needed */
 	enum audit_state    state, current_state;
 	unsigned int	    serial;     /* serial number for record */
 	int		    major;      /* syscall number */
diff --git a/kernel/auditsc.c b/kernel/auditsc.c
index 4af5861bcb9a..5bfee5d0812d 100644
--- a/kernel/auditsc.c
+++ b/kernel/auditsc.c
@@ -929,11 +929,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(&context->ctime);
+	context->local = true;
+out:
+	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);
@@ -991,6 +1013,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,
 				 kuid_t auid, kuid_t uid,
@@ -2228,7 +2251,7 @@  EXPORT_SYMBOL_GPL(__audit_inode_child);
 int auditsc_get_stamp(struct audit_context *ctx,
 		       struct timespec64 *t, unsigned int *serial)
 {
-	if (!ctx->in_syscall)
+	if (!ctx->in_syscall && !ctx->local)
 		return 0;
 	if (!ctx->serial)
 		ctx->serial = audit_serial();