18c2ecf20Sopenharmony_ci/* auditsc.c -- System-call auditing support
28c2ecf20Sopenharmony_ci * Handles all system-call specific auditing features.
38c2ecf20Sopenharmony_ci *
48c2ecf20Sopenharmony_ci * Copyright 2003-2004 Red Hat Inc., Durham, North Carolina.
58c2ecf20Sopenharmony_ci * Copyright 2005 Hewlett-Packard Development Company, L.P.
68c2ecf20Sopenharmony_ci * Copyright (C) 2005, 2006 IBM Corporation
78c2ecf20Sopenharmony_ci * All Rights Reserved.
88c2ecf20Sopenharmony_ci *
98c2ecf20Sopenharmony_ci * This program is free software; you can redistribute it and/or modify
108c2ecf20Sopenharmony_ci * it under the terms of the GNU General Public License as published by
118c2ecf20Sopenharmony_ci * the Free Software Foundation; either version 2 of the License, or
128c2ecf20Sopenharmony_ci * (at your option) any later version.
138c2ecf20Sopenharmony_ci *
148c2ecf20Sopenharmony_ci * This program is distributed in the hope that it will be useful,
158c2ecf20Sopenharmony_ci * but WITHOUT ANY WARRANTY; without even the implied warranty of
168c2ecf20Sopenharmony_ci * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
178c2ecf20Sopenharmony_ci * GNU General Public License for more details.
188c2ecf20Sopenharmony_ci *
198c2ecf20Sopenharmony_ci * You should have received a copy of the GNU General Public License
208c2ecf20Sopenharmony_ci * along with this program; if not, write to the Free Software
218c2ecf20Sopenharmony_ci * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
228c2ecf20Sopenharmony_ci *
238c2ecf20Sopenharmony_ci * Written by Rickard E. (Rik) Faith <faith@redhat.com>
248c2ecf20Sopenharmony_ci *
258c2ecf20Sopenharmony_ci * Many of the ideas implemented here are from Stephen C. Tweedie,
268c2ecf20Sopenharmony_ci * especially the idea of avoiding a copy by using getname.
278c2ecf20Sopenharmony_ci *
288c2ecf20Sopenharmony_ci * The method for actual interception of syscall entry and exit (not in
298c2ecf20Sopenharmony_ci * this file -- see entry.S) is based on a GPL'd patch written by
308c2ecf20Sopenharmony_ci * okir@suse.de and Copyright 2003 SuSE Linux AG.
318c2ecf20Sopenharmony_ci *
328c2ecf20Sopenharmony_ci * POSIX message queue support added by George Wilson <ltcgcw@us.ibm.com>,
338c2ecf20Sopenharmony_ci * 2006.
348c2ecf20Sopenharmony_ci *
358c2ecf20Sopenharmony_ci * The support of additional filter rules compares (>, <, >=, <=) was
368c2ecf20Sopenharmony_ci * added by Dustin Kirkland <dustin.kirkland@us.ibm.com>, 2005.
378c2ecf20Sopenharmony_ci *
388c2ecf20Sopenharmony_ci * Modified by Amy Griffis <amy.griffis@hp.com> to collect additional
398c2ecf20Sopenharmony_ci * filesystem information.
408c2ecf20Sopenharmony_ci *
418c2ecf20Sopenharmony_ci * Subject and object context labeling support added by <danjones@us.ibm.com>
428c2ecf20Sopenharmony_ci * and <dustin.kirkland@us.ibm.com> for LSPP certification compliance.
438c2ecf20Sopenharmony_ci */
448c2ecf20Sopenharmony_ci
458c2ecf20Sopenharmony_ci#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
468c2ecf20Sopenharmony_ci
478c2ecf20Sopenharmony_ci#include <linux/init.h>
488c2ecf20Sopenharmony_ci#include <asm/types.h>
498c2ecf20Sopenharmony_ci#include <linux/atomic.h>
508c2ecf20Sopenharmony_ci#include <linux/fs.h>
518c2ecf20Sopenharmony_ci#include <linux/namei.h>
528c2ecf20Sopenharmony_ci#include <linux/mm.h>
538c2ecf20Sopenharmony_ci#include <linux/export.h>
548c2ecf20Sopenharmony_ci#include <linux/slab.h>
558c2ecf20Sopenharmony_ci#include <linux/mount.h>
568c2ecf20Sopenharmony_ci#include <linux/socket.h>
578c2ecf20Sopenharmony_ci#include <linux/mqueue.h>
588c2ecf20Sopenharmony_ci#include <linux/audit.h>
598c2ecf20Sopenharmony_ci#include <linux/personality.h>
608c2ecf20Sopenharmony_ci#include <linux/time.h>
618c2ecf20Sopenharmony_ci#include <linux/netlink.h>
628c2ecf20Sopenharmony_ci#include <linux/compiler.h>
638c2ecf20Sopenharmony_ci#include <asm/unistd.h>
648c2ecf20Sopenharmony_ci#include <linux/security.h>
658c2ecf20Sopenharmony_ci#include <linux/list.h>
668c2ecf20Sopenharmony_ci#include <linux/binfmts.h>
678c2ecf20Sopenharmony_ci#include <linux/highmem.h>
688c2ecf20Sopenharmony_ci#include <linux/syscalls.h>
698c2ecf20Sopenharmony_ci#include <asm/syscall.h>
708c2ecf20Sopenharmony_ci#include <linux/capability.h>
718c2ecf20Sopenharmony_ci#include <linux/fs_struct.h>
728c2ecf20Sopenharmony_ci#include <linux/compat.h>
738c2ecf20Sopenharmony_ci#include <linux/ctype.h>
748c2ecf20Sopenharmony_ci#include <linux/string.h>
758c2ecf20Sopenharmony_ci#include <linux/uaccess.h>
768c2ecf20Sopenharmony_ci#include <linux/fsnotify_backend.h>
778c2ecf20Sopenharmony_ci#include <uapi/linux/limits.h>
788c2ecf20Sopenharmony_ci#include <uapi/linux/netfilter/nf_tables.h>
798c2ecf20Sopenharmony_ci
808c2ecf20Sopenharmony_ci#include "audit.h"
818c2ecf20Sopenharmony_ci
828c2ecf20Sopenharmony_ci/* flags stating the success for a syscall */
838c2ecf20Sopenharmony_ci#define AUDITSC_INVALID 0
848c2ecf20Sopenharmony_ci#define AUDITSC_SUCCESS 1
858c2ecf20Sopenharmony_ci#define AUDITSC_FAILURE 2
868c2ecf20Sopenharmony_ci
878c2ecf20Sopenharmony_ci/* no execve audit message should be longer than this (userspace limits),
888c2ecf20Sopenharmony_ci * see the note near the top of audit_log_execve_info() about this value */
898c2ecf20Sopenharmony_ci#define MAX_EXECVE_AUDIT_LEN 7500
908c2ecf20Sopenharmony_ci
918c2ecf20Sopenharmony_ci/* max length to print of cmdline/proctitle value during audit */
928c2ecf20Sopenharmony_ci#define MAX_PROCTITLE_AUDIT_LEN 128
938c2ecf20Sopenharmony_ci
948c2ecf20Sopenharmony_ci/* number of audit rules */
958c2ecf20Sopenharmony_ciint audit_n_rules;
968c2ecf20Sopenharmony_ci
978c2ecf20Sopenharmony_ci/* determines whether we collect data for signals sent */
988c2ecf20Sopenharmony_ciint audit_signals;
998c2ecf20Sopenharmony_ci
1008c2ecf20Sopenharmony_cistruct audit_aux_data {
1018c2ecf20Sopenharmony_ci	struct audit_aux_data	*next;
1028c2ecf20Sopenharmony_ci	int			type;
1038c2ecf20Sopenharmony_ci};
1048c2ecf20Sopenharmony_ci
1058c2ecf20Sopenharmony_ci#define AUDIT_AUX_IPCPERM	0
1068c2ecf20Sopenharmony_ci
1078c2ecf20Sopenharmony_ci/* Number of target pids per aux struct. */
1088c2ecf20Sopenharmony_ci#define AUDIT_AUX_PIDS	16
1098c2ecf20Sopenharmony_ci
1108c2ecf20Sopenharmony_cistruct audit_aux_data_pids {
1118c2ecf20Sopenharmony_ci	struct audit_aux_data	d;
1128c2ecf20Sopenharmony_ci	pid_t			target_pid[AUDIT_AUX_PIDS];
1138c2ecf20Sopenharmony_ci	kuid_t			target_auid[AUDIT_AUX_PIDS];
1148c2ecf20Sopenharmony_ci	kuid_t			target_uid[AUDIT_AUX_PIDS];
1158c2ecf20Sopenharmony_ci	unsigned int		target_sessionid[AUDIT_AUX_PIDS];
1168c2ecf20Sopenharmony_ci	u32			target_sid[AUDIT_AUX_PIDS];
1178c2ecf20Sopenharmony_ci	char 			target_comm[AUDIT_AUX_PIDS][TASK_COMM_LEN];
1188c2ecf20Sopenharmony_ci	int			pid_count;
1198c2ecf20Sopenharmony_ci};
1208c2ecf20Sopenharmony_ci
1218c2ecf20Sopenharmony_cistruct audit_aux_data_bprm_fcaps {
1228c2ecf20Sopenharmony_ci	struct audit_aux_data	d;
1238c2ecf20Sopenharmony_ci	struct audit_cap_data	fcap;
1248c2ecf20Sopenharmony_ci	unsigned int		fcap_ver;
1258c2ecf20Sopenharmony_ci	struct audit_cap_data	old_pcap;
1268c2ecf20Sopenharmony_ci	struct audit_cap_data	new_pcap;
1278c2ecf20Sopenharmony_ci};
1288c2ecf20Sopenharmony_ci
1298c2ecf20Sopenharmony_cistruct audit_tree_refs {
1308c2ecf20Sopenharmony_ci	struct audit_tree_refs *next;
1318c2ecf20Sopenharmony_ci	struct audit_chunk *c[31];
1328c2ecf20Sopenharmony_ci};
1338c2ecf20Sopenharmony_ci
1348c2ecf20Sopenharmony_cistruct audit_nfcfgop_tab {
1358c2ecf20Sopenharmony_ci	enum audit_nfcfgop	op;
1368c2ecf20Sopenharmony_ci	const char		*s;
1378c2ecf20Sopenharmony_ci};
1388c2ecf20Sopenharmony_ci
1398c2ecf20Sopenharmony_cistatic const struct audit_nfcfgop_tab audit_nfcfgs[] = {
1408c2ecf20Sopenharmony_ci	{ AUDIT_XT_OP_REGISTER,			"xt_register"		   },
1418c2ecf20Sopenharmony_ci	{ AUDIT_XT_OP_REPLACE,			"xt_replace"		   },
1428c2ecf20Sopenharmony_ci	{ AUDIT_XT_OP_UNREGISTER,		"xt_unregister"		   },
1438c2ecf20Sopenharmony_ci	{ AUDIT_NFT_OP_TABLE_REGISTER,		"nft_register_table"	   },
1448c2ecf20Sopenharmony_ci	{ AUDIT_NFT_OP_TABLE_UNREGISTER,	"nft_unregister_table"	   },
1458c2ecf20Sopenharmony_ci	{ AUDIT_NFT_OP_CHAIN_REGISTER,		"nft_register_chain"	   },
1468c2ecf20Sopenharmony_ci	{ AUDIT_NFT_OP_CHAIN_UNREGISTER,	"nft_unregister_chain"	   },
1478c2ecf20Sopenharmony_ci	{ AUDIT_NFT_OP_RULE_REGISTER,		"nft_register_rule"	   },
1488c2ecf20Sopenharmony_ci	{ AUDIT_NFT_OP_RULE_UNREGISTER,		"nft_unregister_rule"	   },
1498c2ecf20Sopenharmony_ci	{ AUDIT_NFT_OP_SET_REGISTER,		"nft_register_set"	   },
1508c2ecf20Sopenharmony_ci	{ AUDIT_NFT_OP_SET_UNREGISTER,		"nft_unregister_set"	   },
1518c2ecf20Sopenharmony_ci	{ AUDIT_NFT_OP_SETELEM_REGISTER,	"nft_register_setelem"	   },
1528c2ecf20Sopenharmony_ci	{ AUDIT_NFT_OP_SETELEM_UNREGISTER,	"nft_unregister_setelem"   },
1538c2ecf20Sopenharmony_ci	{ AUDIT_NFT_OP_GEN_REGISTER,		"nft_register_gen"	   },
1548c2ecf20Sopenharmony_ci	{ AUDIT_NFT_OP_OBJ_REGISTER,		"nft_register_obj"	   },
1558c2ecf20Sopenharmony_ci	{ AUDIT_NFT_OP_OBJ_UNREGISTER,		"nft_unregister_obj"	   },
1568c2ecf20Sopenharmony_ci	{ AUDIT_NFT_OP_OBJ_RESET,		"nft_reset_obj"		   },
1578c2ecf20Sopenharmony_ci	{ AUDIT_NFT_OP_FLOWTABLE_REGISTER,	"nft_register_flowtable"   },
1588c2ecf20Sopenharmony_ci	{ AUDIT_NFT_OP_FLOWTABLE_UNREGISTER,	"nft_unregister_flowtable" },
1598c2ecf20Sopenharmony_ci	{ AUDIT_NFT_OP_INVALID,			"nft_invalid"		   },
1608c2ecf20Sopenharmony_ci};
1618c2ecf20Sopenharmony_ci
1628c2ecf20Sopenharmony_cistatic int audit_match_perm(struct audit_context *ctx, int mask)
1638c2ecf20Sopenharmony_ci{
1648c2ecf20Sopenharmony_ci	unsigned n;
1658c2ecf20Sopenharmony_ci	if (unlikely(!ctx))
1668c2ecf20Sopenharmony_ci		return 0;
1678c2ecf20Sopenharmony_ci	n = ctx->major;
1688c2ecf20Sopenharmony_ci
1698c2ecf20Sopenharmony_ci	switch (audit_classify_syscall(ctx->arch, n)) {
1708c2ecf20Sopenharmony_ci	case 0:	/* native */
1718c2ecf20Sopenharmony_ci		if ((mask & AUDIT_PERM_WRITE) &&
1728c2ecf20Sopenharmony_ci		     audit_match_class(AUDIT_CLASS_WRITE, n))
1738c2ecf20Sopenharmony_ci			return 1;
1748c2ecf20Sopenharmony_ci		if ((mask & AUDIT_PERM_READ) &&
1758c2ecf20Sopenharmony_ci		     audit_match_class(AUDIT_CLASS_READ, n))
1768c2ecf20Sopenharmony_ci			return 1;
1778c2ecf20Sopenharmony_ci		if ((mask & AUDIT_PERM_ATTR) &&
1788c2ecf20Sopenharmony_ci		     audit_match_class(AUDIT_CLASS_CHATTR, n))
1798c2ecf20Sopenharmony_ci			return 1;
1808c2ecf20Sopenharmony_ci		return 0;
1818c2ecf20Sopenharmony_ci	case 1: /* 32bit on biarch */
1828c2ecf20Sopenharmony_ci		if ((mask & AUDIT_PERM_WRITE) &&
1838c2ecf20Sopenharmony_ci		     audit_match_class(AUDIT_CLASS_WRITE_32, n))
1848c2ecf20Sopenharmony_ci			return 1;
1858c2ecf20Sopenharmony_ci		if ((mask & AUDIT_PERM_READ) &&
1868c2ecf20Sopenharmony_ci		     audit_match_class(AUDIT_CLASS_READ_32, n))
1878c2ecf20Sopenharmony_ci			return 1;
1888c2ecf20Sopenharmony_ci		if ((mask & AUDIT_PERM_ATTR) &&
1898c2ecf20Sopenharmony_ci		     audit_match_class(AUDIT_CLASS_CHATTR_32, n))
1908c2ecf20Sopenharmony_ci			return 1;
1918c2ecf20Sopenharmony_ci		return 0;
1928c2ecf20Sopenharmony_ci	case 2: /* open */
1938c2ecf20Sopenharmony_ci		return mask & ACC_MODE(ctx->argv[1]);
1948c2ecf20Sopenharmony_ci	case 3: /* openat */
1958c2ecf20Sopenharmony_ci		return mask & ACC_MODE(ctx->argv[2]);
1968c2ecf20Sopenharmony_ci	case 4: /* socketcall */
1978c2ecf20Sopenharmony_ci		return ((mask & AUDIT_PERM_WRITE) && ctx->argv[0] == SYS_BIND);
1988c2ecf20Sopenharmony_ci	case 5: /* execve */
1998c2ecf20Sopenharmony_ci		return mask & AUDIT_PERM_EXEC;
2008c2ecf20Sopenharmony_ci	default:
2018c2ecf20Sopenharmony_ci		return 0;
2028c2ecf20Sopenharmony_ci	}
2038c2ecf20Sopenharmony_ci}
2048c2ecf20Sopenharmony_ci
2058c2ecf20Sopenharmony_cistatic int audit_match_filetype(struct audit_context *ctx, int val)
2068c2ecf20Sopenharmony_ci{
2078c2ecf20Sopenharmony_ci	struct audit_names *n;
2088c2ecf20Sopenharmony_ci	umode_t mode = (umode_t)val;
2098c2ecf20Sopenharmony_ci
2108c2ecf20Sopenharmony_ci	if (unlikely(!ctx))
2118c2ecf20Sopenharmony_ci		return 0;
2128c2ecf20Sopenharmony_ci
2138c2ecf20Sopenharmony_ci	list_for_each_entry(n, &ctx->names_list, list) {
2148c2ecf20Sopenharmony_ci		if ((n->ino != AUDIT_INO_UNSET) &&
2158c2ecf20Sopenharmony_ci		    ((n->mode & S_IFMT) == mode))
2168c2ecf20Sopenharmony_ci			return 1;
2178c2ecf20Sopenharmony_ci	}
2188c2ecf20Sopenharmony_ci
2198c2ecf20Sopenharmony_ci	return 0;
2208c2ecf20Sopenharmony_ci}
2218c2ecf20Sopenharmony_ci
2228c2ecf20Sopenharmony_ci/*
2238c2ecf20Sopenharmony_ci * We keep a linked list of fixed-sized (31 pointer) arrays of audit_chunk *;
2248c2ecf20Sopenharmony_ci * ->first_trees points to its beginning, ->trees - to the current end of data.
2258c2ecf20Sopenharmony_ci * ->tree_count is the number of free entries in array pointed to by ->trees.
2268c2ecf20Sopenharmony_ci * Original condition is (NULL, NULL, 0); as soon as it grows we never revert to NULL,
2278c2ecf20Sopenharmony_ci * "empty" becomes (p, p, 31) afterwards.  We don't shrink the list (and seriously,
2288c2ecf20Sopenharmony_ci * it's going to remain 1-element for almost any setup) until we free context itself.
2298c2ecf20Sopenharmony_ci * References in it _are_ dropped - at the same time we free/drop aux stuff.
2308c2ecf20Sopenharmony_ci */
2318c2ecf20Sopenharmony_ci
2328c2ecf20Sopenharmony_cistatic void audit_set_auditable(struct audit_context *ctx)
2338c2ecf20Sopenharmony_ci{
2348c2ecf20Sopenharmony_ci	if (!ctx->prio) {
2358c2ecf20Sopenharmony_ci		ctx->prio = 1;
2368c2ecf20Sopenharmony_ci		ctx->current_state = AUDIT_RECORD_CONTEXT;
2378c2ecf20Sopenharmony_ci	}
2388c2ecf20Sopenharmony_ci}
2398c2ecf20Sopenharmony_ci
2408c2ecf20Sopenharmony_cistatic int put_tree_ref(struct audit_context *ctx, struct audit_chunk *chunk)
2418c2ecf20Sopenharmony_ci{
2428c2ecf20Sopenharmony_ci	struct audit_tree_refs *p = ctx->trees;
2438c2ecf20Sopenharmony_ci	int left = ctx->tree_count;
2448c2ecf20Sopenharmony_ci	if (likely(left)) {
2458c2ecf20Sopenharmony_ci		p->c[--left] = chunk;
2468c2ecf20Sopenharmony_ci		ctx->tree_count = left;
2478c2ecf20Sopenharmony_ci		return 1;
2488c2ecf20Sopenharmony_ci	}
2498c2ecf20Sopenharmony_ci	if (!p)
2508c2ecf20Sopenharmony_ci		return 0;
2518c2ecf20Sopenharmony_ci	p = p->next;
2528c2ecf20Sopenharmony_ci	if (p) {
2538c2ecf20Sopenharmony_ci		p->c[30] = chunk;
2548c2ecf20Sopenharmony_ci		ctx->trees = p;
2558c2ecf20Sopenharmony_ci		ctx->tree_count = 30;
2568c2ecf20Sopenharmony_ci		return 1;
2578c2ecf20Sopenharmony_ci	}
2588c2ecf20Sopenharmony_ci	return 0;
2598c2ecf20Sopenharmony_ci}
2608c2ecf20Sopenharmony_ci
2618c2ecf20Sopenharmony_cistatic int grow_tree_refs(struct audit_context *ctx)
2628c2ecf20Sopenharmony_ci{
2638c2ecf20Sopenharmony_ci	struct audit_tree_refs *p = ctx->trees;
2648c2ecf20Sopenharmony_ci	ctx->trees = kzalloc(sizeof(struct audit_tree_refs), GFP_KERNEL);
2658c2ecf20Sopenharmony_ci	if (!ctx->trees) {
2668c2ecf20Sopenharmony_ci		ctx->trees = p;
2678c2ecf20Sopenharmony_ci		return 0;
2688c2ecf20Sopenharmony_ci	}
2698c2ecf20Sopenharmony_ci	if (p)
2708c2ecf20Sopenharmony_ci		p->next = ctx->trees;
2718c2ecf20Sopenharmony_ci	else
2728c2ecf20Sopenharmony_ci		ctx->first_trees = ctx->trees;
2738c2ecf20Sopenharmony_ci	ctx->tree_count = 31;
2748c2ecf20Sopenharmony_ci	return 1;
2758c2ecf20Sopenharmony_ci}
2768c2ecf20Sopenharmony_ci
2778c2ecf20Sopenharmony_cistatic void unroll_tree_refs(struct audit_context *ctx,
2788c2ecf20Sopenharmony_ci		      struct audit_tree_refs *p, int count)
2798c2ecf20Sopenharmony_ci{
2808c2ecf20Sopenharmony_ci	struct audit_tree_refs *q;
2818c2ecf20Sopenharmony_ci	int n;
2828c2ecf20Sopenharmony_ci	if (!p) {
2838c2ecf20Sopenharmony_ci		/* we started with empty chain */
2848c2ecf20Sopenharmony_ci		p = ctx->first_trees;
2858c2ecf20Sopenharmony_ci		count = 31;
2868c2ecf20Sopenharmony_ci		/* if the very first allocation has failed, nothing to do */
2878c2ecf20Sopenharmony_ci		if (!p)
2888c2ecf20Sopenharmony_ci			return;
2898c2ecf20Sopenharmony_ci	}
2908c2ecf20Sopenharmony_ci	n = count;
2918c2ecf20Sopenharmony_ci	for (q = p; q != ctx->trees; q = q->next, n = 31) {
2928c2ecf20Sopenharmony_ci		while (n--) {
2938c2ecf20Sopenharmony_ci			audit_put_chunk(q->c[n]);
2948c2ecf20Sopenharmony_ci			q->c[n] = NULL;
2958c2ecf20Sopenharmony_ci		}
2968c2ecf20Sopenharmony_ci	}
2978c2ecf20Sopenharmony_ci	while (n-- > ctx->tree_count) {
2988c2ecf20Sopenharmony_ci		audit_put_chunk(q->c[n]);
2998c2ecf20Sopenharmony_ci		q->c[n] = NULL;
3008c2ecf20Sopenharmony_ci	}
3018c2ecf20Sopenharmony_ci	ctx->trees = p;
3028c2ecf20Sopenharmony_ci	ctx->tree_count = count;
3038c2ecf20Sopenharmony_ci}
3048c2ecf20Sopenharmony_ci
3058c2ecf20Sopenharmony_cistatic void free_tree_refs(struct audit_context *ctx)
3068c2ecf20Sopenharmony_ci{
3078c2ecf20Sopenharmony_ci	struct audit_tree_refs *p, *q;
3088c2ecf20Sopenharmony_ci	for (p = ctx->first_trees; p; p = q) {
3098c2ecf20Sopenharmony_ci		q = p->next;
3108c2ecf20Sopenharmony_ci		kfree(p);
3118c2ecf20Sopenharmony_ci	}
3128c2ecf20Sopenharmony_ci}
3138c2ecf20Sopenharmony_ci
3148c2ecf20Sopenharmony_cistatic int match_tree_refs(struct audit_context *ctx, struct audit_tree *tree)
3158c2ecf20Sopenharmony_ci{
3168c2ecf20Sopenharmony_ci	struct audit_tree_refs *p;
3178c2ecf20Sopenharmony_ci	int n;
3188c2ecf20Sopenharmony_ci	if (!tree)
3198c2ecf20Sopenharmony_ci		return 0;
3208c2ecf20Sopenharmony_ci	/* full ones */
3218c2ecf20Sopenharmony_ci	for (p = ctx->first_trees; p != ctx->trees; p = p->next) {
3228c2ecf20Sopenharmony_ci		for (n = 0; n < 31; n++)
3238c2ecf20Sopenharmony_ci			if (audit_tree_match(p->c[n], tree))
3248c2ecf20Sopenharmony_ci				return 1;
3258c2ecf20Sopenharmony_ci	}
3268c2ecf20Sopenharmony_ci	/* partial */
3278c2ecf20Sopenharmony_ci	if (p) {
3288c2ecf20Sopenharmony_ci		for (n = ctx->tree_count; n < 31; n++)
3298c2ecf20Sopenharmony_ci			if (audit_tree_match(p->c[n], tree))
3308c2ecf20Sopenharmony_ci				return 1;
3318c2ecf20Sopenharmony_ci	}
3328c2ecf20Sopenharmony_ci	return 0;
3338c2ecf20Sopenharmony_ci}
3348c2ecf20Sopenharmony_ci
3358c2ecf20Sopenharmony_cistatic int audit_compare_uid(kuid_t uid,
3368c2ecf20Sopenharmony_ci			     struct audit_names *name,
3378c2ecf20Sopenharmony_ci			     struct audit_field *f,
3388c2ecf20Sopenharmony_ci			     struct audit_context *ctx)
3398c2ecf20Sopenharmony_ci{
3408c2ecf20Sopenharmony_ci	struct audit_names *n;
3418c2ecf20Sopenharmony_ci	int rc;
3428c2ecf20Sopenharmony_ci
3438c2ecf20Sopenharmony_ci	if (name) {
3448c2ecf20Sopenharmony_ci		rc = audit_uid_comparator(uid, f->op, name->uid);
3458c2ecf20Sopenharmony_ci		if (rc)
3468c2ecf20Sopenharmony_ci			return rc;
3478c2ecf20Sopenharmony_ci	}
3488c2ecf20Sopenharmony_ci
3498c2ecf20Sopenharmony_ci	if (ctx) {
3508c2ecf20Sopenharmony_ci		list_for_each_entry(n, &ctx->names_list, list) {
3518c2ecf20Sopenharmony_ci			rc = audit_uid_comparator(uid, f->op, n->uid);
3528c2ecf20Sopenharmony_ci			if (rc)
3538c2ecf20Sopenharmony_ci				return rc;
3548c2ecf20Sopenharmony_ci		}
3558c2ecf20Sopenharmony_ci	}
3568c2ecf20Sopenharmony_ci	return 0;
3578c2ecf20Sopenharmony_ci}
3588c2ecf20Sopenharmony_ci
3598c2ecf20Sopenharmony_cistatic int audit_compare_gid(kgid_t gid,
3608c2ecf20Sopenharmony_ci			     struct audit_names *name,
3618c2ecf20Sopenharmony_ci			     struct audit_field *f,
3628c2ecf20Sopenharmony_ci			     struct audit_context *ctx)
3638c2ecf20Sopenharmony_ci{
3648c2ecf20Sopenharmony_ci	struct audit_names *n;
3658c2ecf20Sopenharmony_ci	int rc;
3668c2ecf20Sopenharmony_ci
3678c2ecf20Sopenharmony_ci	if (name) {
3688c2ecf20Sopenharmony_ci		rc = audit_gid_comparator(gid, f->op, name->gid);
3698c2ecf20Sopenharmony_ci		if (rc)
3708c2ecf20Sopenharmony_ci			return rc;
3718c2ecf20Sopenharmony_ci	}
3728c2ecf20Sopenharmony_ci
3738c2ecf20Sopenharmony_ci	if (ctx) {
3748c2ecf20Sopenharmony_ci		list_for_each_entry(n, &ctx->names_list, list) {
3758c2ecf20Sopenharmony_ci			rc = audit_gid_comparator(gid, f->op, n->gid);
3768c2ecf20Sopenharmony_ci			if (rc)
3778c2ecf20Sopenharmony_ci				return rc;
3788c2ecf20Sopenharmony_ci		}
3798c2ecf20Sopenharmony_ci	}
3808c2ecf20Sopenharmony_ci	return 0;
3818c2ecf20Sopenharmony_ci}
3828c2ecf20Sopenharmony_ci
3838c2ecf20Sopenharmony_cistatic int audit_field_compare(struct task_struct *tsk,
3848c2ecf20Sopenharmony_ci			       const struct cred *cred,
3858c2ecf20Sopenharmony_ci			       struct audit_field *f,
3868c2ecf20Sopenharmony_ci			       struct audit_context *ctx,
3878c2ecf20Sopenharmony_ci			       struct audit_names *name)
3888c2ecf20Sopenharmony_ci{
3898c2ecf20Sopenharmony_ci	switch (f->val) {
3908c2ecf20Sopenharmony_ci	/* process to file object comparisons */
3918c2ecf20Sopenharmony_ci	case AUDIT_COMPARE_UID_TO_OBJ_UID:
3928c2ecf20Sopenharmony_ci		return audit_compare_uid(cred->uid, name, f, ctx);
3938c2ecf20Sopenharmony_ci	case AUDIT_COMPARE_GID_TO_OBJ_GID:
3948c2ecf20Sopenharmony_ci		return audit_compare_gid(cred->gid, name, f, ctx);
3958c2ecf20Sopenharmony_ci	case AUDIT_COMPARE_EUID_TO_OBJ_UID:
3968c2ecf20Sopenharmony_ci		return audit_compare_uid(cred->euid, name, f, ctx);
3978c2ecf20Sopenharmony_ci	case AUDIT_COMPARE_EGID_TO_OBJ_GID:
3988c2ecf20Sopenharmony_ci		return audit_compare_gid(cred->egid, name, f, ctx);
3998c2ecf20Sopenharmony_ci	case AUDIT_COMPARE_AUID_TO_OBJ_UID:
4008c2ecf20Sopenharmony_ci		return audit_compare_uid(audit_get_loginuid(tsk), name, f, ctx);
4018c2ecf20Sopenharmony_ci	case AUDIT_COMPARE_SUID_TO_OBJ_UID:
4028c2ecf20Sopenharmony_ci		return audit_compare_uid(cred->suid, name, f, ctx);
4038c2ecf20Sopenharmony_ci	case AUDIT_COMPARE_SGID_TO_OBJ_GID:
4048c2ecf20Sopenharmony_ci		return audit_compare_gid(cred->sgid, name, f, ctx);
4058c2ecf20Sopenharmony_ci	case AUDIT_COMPARE_FSUID_TO_OBJ_UID:
4068c2ecf20Sopenharmony_ci		return audit_compare_uid(cred->fsuid, name, f, ctx);
4078c2ecf20Sopenharmony_ci	case AUDIT_COMPARE_FSGID_TO_OBJ_GID:
4088c2ecf20Sopenharmony_ci		return audit_compare_gid(cred->fsgid, name, f, ctx);
4098c2ecf20Sopenharmony_ci	/* uid comparisons */
4108c2ecf20Sopenharmony_ci	case AUDIT_COMPARE_UID_TO_AUID:
4118c2ecf20Sopenharmony_ci		return audit_uid_comparator(cred->uid, f->op,
4128c2ecf20Sopenharmony_ci					    audit_get_loginuid(tsk));
4138c2ecf20Sopenharmony_ci	case AUDIT_COMPARE_UID_TO_EUID:
4148c2ecf20Sopenharmony_ci		return audit_uid_comparator(cred->uid, f->op, cred->euid);
4158c2ecf20Sopenharmony_ci	case AUDIT_COMPARE_UID_TO_SUID:
4168c2ecf20Sopenharmony_ci		return audit_uid_comparator(cred->uid, f->op, cred->suid);
4178c2ecf20Sopenharmony_ci	case AUDIT_COMPARE_UID_TO_FSUID:
4188c2ecf20Sopenharmony_ci		return audit_uid_comparator(cred->uid, f->op, cred->fsuid);
4198c2ecf20Sopenharmony_ci	/* auid comparisons */
4208c2ecf20Sopenharmony_ci	case AUDIT_COMPARE_AUID_TO_EUID:
4218c2ecf20Sopenharmony_ci		return audit_uid_comparator(audit_get_loginuid(tsk), f->op,
4228c2ecf20Sopenharmony_ci					    cred->euid);
4238c2ecf20Sopenharmony_ci	case AUDIT_COMPARE_AUID_TO_SUID:
4248c2ecf20Sopenharmony_ci		return audit_uid_comparator(audit_get_loginuid(tsk), f->op,
4258c2ecf20Sopenharmony_ci					    cred->suid);
4268c2ecf20Sopenharmony_ci	case AUDIT_COMPARE_AUID_TO_FSUID:
4278c2ecf20Sopenharmony_ci		return audit_uid_comparator(audit_get_loginuid(tsk), f->op,
4288c2ecf20Sopenharmony_ci					    cred->fsuid);
4298c2ecf20Sopenharmony_ci	/* euid comparisons */
4308c2ecf20Sopenharmony_ci	case AUDIT_COMPARE_EUID_TO_SUID:
4318c2ecf20Sopenharmony_ci		return audit_uid_comparator(cred->euid, f->op, cred->suid);
4328c2ecf20Sopenharmony_ci	case AUDIT_COMPARE_EUID_TO_FSUID:
4338c2ecf20Sopenharmony_ci		return audit_uid_comparator(cred->euid, f->op, cred->fsuid);
4348c2ecf20Sopenharmony_ci	/* suid comparisons */
4358c2ecf20Sopenharmony_ci	case AUDIT_COMPARE_SUID_TO_FSUID:
4368c2ecf20Sopenharmony_ci		return audit_uid_comparator(cred->suid, f->op, cred->fsuid);
4378c2ecf20Sopenharmony_ci	/* gid comparisons */
4388c2ecf20Sopenharmony_ci	case AUDIT_COMPARE_GID_TO_EGID:
4398c2ecf20Sopenharmony_ci		return audit_gid_comparator(cred->gid, f->op, cred->egid);
4408c2ecf20Sopenharmony_ci	case AUDIT_COMPARE_GID_TO_SGID:
4418c2ecf20Sopenharmony_ci		return audit_gid_comparator(cred->gid, f->op, cred->sgid);
4428c2ecf20Sopenharmony_ci	case AUDIT_COMPARE_GID_TO_FSGID:
4438c2ecf20Sopenharmony_ci		return audit_gid_comparator(cred->gid, f->op, cred->fsgid);
4448c2ecf20Sopenharmony_ci	/* egid comparisons */
4458c2ecf20Sopenharmony_ci	case AUDIT_COMPARE_EGID_TO_SGID:
4468c2ecf20Sopenharmony_ci		return audit_gid_comparator(cred->egid, f->op, cred->sgid);
4478c2ecf20Sopenharmony_ci	case AUDIT_COMPARE_EGID_TO_FSGID:
4488c2ecf20Sopenharmony_ci		return audit_gid_comparator(cred->egid, f->op, cred->fsgid);
4498c2ecf20Sopenharmony_ci	/* sgid comparison */
4508c2ecf20Sopenharmony_ci	case AUDIT_COMPARE_SGID_TO_FSGID:
4518c2ecf20Sopenharmony_ci		return audit_gid_comparator(cred->sgid, f->op, cred->fsgid);
4528c2ecf20Sopenharmony_ci	default:
4538c2ecf20Sopenharmony_ci		WARN(1, "Missing AUDIT_COMPARE define.  Report as a bug\n");
4548c2ecf20Sopenharmony_ci		return 0;
4558c2ecf20Sopenharmony_ci	}
4568c2ecf20Sopenharmony_ci	return 0;
4578c2ecf20Sopenharmony_ci}
4588c2ecf20Sopenharmony_ci
4598c2ecf20Sopenharmony_ci/* Determine if any context name data matches a rule's watch data */
4608c2ecf20Sopenharmony_ci/* Compare a task_struct with an audit_rule.  Return 1 on match, 0
4618c2ecf20Sopenharmony_ci * otherwise.
4628c2ecf20Sopenharmony_ci *
4638c2ecf20Sopenharmony_ci * If task_creation is true, this is an explicit indication that we are
4648c2ecf20Sopenharmony_ci * filtering a task rule at task creation time.  This and tsk == current are
4658c2ecf20Sopenharmony_ci * the only situations where tsk->cred may be accessed without an rcu read lock.
4668c2ecf20Sopenharmony_ci */
4678c2ecf20Sopenharmony_cistatic int audit_filter_rules(struct task_struct *tsk,
4688c2ecf20Sopenharmony_ci			      struct audit_krule *rule,
4698c2ecf20Sopenharmony_ci			      struct audit_context *ctx,
4708c2ecf20Sopenharmony_ci			      struct audit_names *name,
4718c2ecf20Sopenharmony_ci			      enum audit_state *state,
4728c2ecf20Sopenharmony_ci			      bool task_creation)
4738c2ecf20Sopenharmony_ci{
4748c2ecf20Sopenharmony_ci	const struct cred *cred;
4758c2ecf20Sopenharmony_ci	int i, need_sid = 1;
4768c2ecf20Sopenharmony_ci	u32 sid;
4778c2ecf20Sopenharmony_ci	unsigned int sessionid;
4788c2ecf20Sopenharmony_ci
4798c2ecf20Sopenharmony_ci	cred = rcu_dereference_check(tsk->cred, tsk == current || task_creation);
4808c2ecf20Sopenharmony_ci
4818c2ecf20Sopenharmony_ci	for (i = 0; i < rule->field_count; i++) {
4828c2ecf20Sopenharmony_ci		struct audit_field *f = &rule->fields[i];
4838c2ecf20Sopenharmony_ci		struct audit_names *n;
4848c2ecf20Sopenharmony_ci		int result = 0;
4858c2ecf20Sopenharmony_ci		pid_t pid;
4868c2ecf20Sopenharmony_ci
4878c2ecf20Sopenharmony_ci		switch (f->type) {
4888c2ecf20Sopenharmony_ci		case AUDIT_PID:
4898c2ecf20Sopenharmony_ci			pid = task_tgid_nr(tsk);
4908c2ecf20Sopenharmony_ci			result = audit_comparator(pid, f->op, f->val);
4918c2ecf20Sopenharmony_ci			break;
4928c2ecf20Sopenharmony_ci		case AUDIT_PPID:
4938c2ecf20Sopenharmony_ci			if (ctx) {
4948c2ecf20Sopenharmony_ci				if (!ctx->ppid)
4958c2ecf20Sopenharmony_ci					ctx->ppid = task_ppid_nr(tsk);
4968c2ecf20Sopenharmony_ci				result = audit_comparator(ctx->ppid, f->op, f->val);
4978c2ecf20Sopenharmony_ci			}
4988c2ecf20Sopenharmony_ci			break;
4998c2ecf20Sopenharmony_ci		case AUDIT_EXE:
5008c2ecf20Sopenharmony_ci			result = audit_exe_compare(tsk, rule->exe);
5018c2ecf20Sopenharmony_ci			if (f->op == Audit_not_equal)
5028c2ecf20Sopenharmony_ci				result = !result;
5038c2ecf20Sopenharmony_ci			break;
5048c2ecf20Sopenharmony_ci		case AUDIT_UID:
5058c2ecf20Sopenharmony_ci			result = audit_uid_comparator(cred->uid, f->op, f->uid);
5068c2ecf20Sopenharmony_ci			break;
5078c2ecf20Sopenharmony_ci		case AUDIT_EUID:
5088c2ecf20Sopenharmony_ci			result = audit_uid_comparator(cred->euid, f->op, f->uid);
5098c2ecf20Sopenharmony_ci			break;
5108c2ecf20Sopenharmony_ci		case AUDIT_SUID:
5118c2ecf20Sopenharmony_ci			result = audit_uid_comparator(cred->suid, f->op, f->uid);
5128c2ecf20Sopenharmony_ci			break;
5138c2ecf20Sopenharmony_ci		case AUDIT_FSUID:
5148c2ecf20Sopenharmony_ci			result = audit_uid_comparator(cred->fsuid, f->op, f->uid);
5158c2ecf20Sopenharmony_ci			break;
5168c2ecf20Sopenharmony_ci		case AUDIT_GID:
5178c2ecf20Sopenharmony_ci			result = audit_gid_comparator(cred->gid, f->op, f->gid);
5188c2ecf20Sopenharmony_ci			if (f->op == Audit_equal) {
5198c2ecf20Sopenharmony_ci				if (!result)
5208c2ecf20Sopenharmony_ci					result = groups_search(cred->group_info, f->gid);
5218c2ecf20Sopenharmony_ci			} else if (f->op == Audit_not_equal) {
5228c2ecf20Sopenharmony_ci				if (result)
5238c2ecf20Sopenharmony_ci					result = !groups_search(cred->group_info, f->gid);
5248c2ecf20Sopenharmony_ci			}
5258c2ecf20Sopenharmony_ci			break;
5268c2ecf20Sopenharmony_ci		case AUDIT_EGID:
5278c2ecf20Sopenharmony_ci			result = audit_gid_comparator(cred->egid, f->op, f->gid);
5288c2ecf20Sopenharmony_ci			if (f->op == Audit_equal) {
5298c2ecf20Sopenharmony_ci				if (!result)
5308c2ecf20Sopenharmony_ci					result = groups_search(cred->group_info, f->gid);
5318c2ecf20Sopenharmony_ci			} else if (f->op == Audit_not_equal) {
5328c2ecf20Sopenharmony_ci				if (result)
5338c2ecf20Sopenharmony_ci					result = !groups_search(cred->group_info, f->gid);
5348c2ecf20Sopenharmony_ci			}
5358c2ecf20Sopenharmony_ci			break;
5368c2ecf20Sopenharmony_ci		case AUDIT_SGID:
5378c2ecf20Sopenharmony_ci			result = audit_gid_comparator(cred->sgid, f->op, f->gid);
5388c2ecf20Sopenharmony_ci			break;
5398c2ecf20Sopenharmony_ci		case AUDIT_FSGID:
5408c2ecf20Sopenharmony_ci			result = audit_gid_comparator(cred->fsgid, f->op, f->gid);
5418c2ecf20Sopenharmony_ci			break;
5428c2ecf20Sopenharmony_ci		case AUDIT_SESSIONID:
5438c2ecf20Sopenharmony_ci			sessionid = audit_get_sessionid(tsk);
5448c2ecf20Sopenharmony_ci			result = audit_comparator(sessionid, f->op, f->val);
5458c2ecf20Sopenharmony_ci			break;
5468c2ecf20Sopenharmony_ci		case AUDIT_PERS:
5478c2ecf20Sopenharmony_ci			result = audit_comparator(tsk->personality, f->op, f->val);
5488c2ecf20Sopenharmony_ci			break;
5498c2ecf20Sopenharmony_ci		case AUDIT_ARCH:
5508c2ecf20Sopenharmony_ci			if (ctx)
5518c2ecf20Sopenharmony_ci				result = audit_comparator(ctx->arch, f->op, f->val);
5528c2ecf20Sopenharmony_ci			break;
5538c2ecf20Sopenharmony_ci
5548c2ecf20Sopenharmony_ci		case AUDIT_EXIT:
5558c2ecf20Sopenharmony_ci			if (ctx && ctx->return_valid)
5568c2ecf20Sopenharmony_ci				result = audit_comparator(ctx->return_code, f->op, f->val);
5578c2ecf20Sopenharmony_ci			break;
5588c2ecf20Sopenharmony_ci		case AUDIT_SUCCESS:
5598c2ecf20Sopenharmony_ci			if (ctx && ctx->return_valid) {
5608c2ecf20Sopenharmony_ci				if (f->val)
5618c2ecf20Sopenharmony_ci					result = audit_comparator(ctx->return_valid, f->op, AUDITSC_SUCCESS);
5628c2ecf20Sopenharmony_ci				else
5638c2ecf20Sopenharmony_ci					result = audit_comparator(ctx->return_valid, f->op, AUDITSC_FAILURE);
5648c2ecf20Sopenharmony_ci			}
5658c2ecf20Sopenharmony_ci			break;
5668c2ecf20Sopenharmony_ci		case AUDIT_DEVMAJOR:
5678c2ecf20Sopenharmony_ci			if (name) {
5688c2ecf20Sopenharmony_ci				if (audit_comparator(MAJOR(name->dev), f->op, f->val) ||
5698c2ecf20Sopenharmony_ci				    audit_comparator(MAJOR(name->rdev), f->op, f->val))
5708c2ecf20Sopenharmony_ci					++result;
5718c2ecf20Sopenharmony_ci			} else if (ctx) {
5728c2ecf20Sopenharmony_ci				list_for_each_entry(n, &ctx->names_list, list) {
5738c2ecf20Sopenharmony_ci					if (audit_comparator(MAJOR(n->dev), f->op, f->val) ||
5748c2ecf20Sopenharmony_ci					    audit_comparator(MAJOR(n->rdev), f->op, f->val)) {
5758c2ecf20Sopenharmony_ci						++result;
5768c2ecf20Sopenharmony_ci						break;
5778c2ecf20Sopenharmony_ci					}
5788c2ecf20Sopenharmony_ci				}
5798c2ecf20Sopenharmony_ci			}
5808c2ecf20Sopenharmony_ci			break;
5818c2ecf20Sopenharmony_ci		case AUDIT_DEVMINOR:
5828c2ecf20Sopenharmony_ci			if (name) {
5838c2ecf20Sopenharmony_ci				if (audit_comparator(MINOR(name->dev), f->op, f->val) ||
5848c2ecf20Sopenharmony_ci				    audit_comparator(MINOR(name->rdev), f->op, f->val))
5858c2ecf20Sopenharmony_ci					++result;
5868c2ecf20Sopenharmony_ci			} else if (ctx) {
5878c2ecf20Sopenharmony_ci				list_for_each_entry(n, &ctx->names_list, list) {
5888c2ecf20Sopenharmony_ci					if (audit_comparator(MINOR(n->dev), f->op, f->val) ||
5898c2ecf20Sopenharmony_ci					    audit_comparator(MINOR(n->rdev), f->op, f->val)) {
5908c2ecf20Sopenharmony_ci						++result;
5918c2ecf20Sopenharmony_ci						break;
5928c2ecf20Sopenharmony_ci					}
5938c2ecf20Sopenharmony_ci				}
5948c2ecf20Sopenharmony_ci			}
5958c2ecf20Sopenharmony_ci			break;
5968c2ecf20Sopenharmony_ci		case AUDIT_INODE:
5978c2ecf20Sopenharmony_ci			if (name)
5988c2ecf20Sopenharmony_ci				result = audit_comparator(name->ino, f->op, f->val);
5998c2ecf20Sopenharmony_ci			else if (ctx) {
6008c2ecf20Sopenharmony_ci				list_for_each_entry(n, &ctx->names_list, list) {
6018c2ecf20Sopenharmony_ci					if (audit_comparator(n->ino, f->op, f->val)) {
6028c2ecf20Sopenharmony_ci						++result;
6038c2ecf20Sopenharmony_ci						break;
6048c2ecf20Sopenharmony_ci					}
6058c2ecf20Sopenharmony_ci				}
6068c2ecf20Sopenharmony_ci			}
6078c2ecf20Sopenharmony_ci			break;
6088c2ecf20Sopenharmony_ci		case AUDIT_OBJ_UID:
6098c2ecf20Sopenharmony_ci			if (name) {
6108c2ecf20Sopenharmony_ci				result = audit_uid_comparator(name->uid, f->op, f->uid);
6118c2ecf20Sopenharmony_ci			} else if (ctx) {
6128c2ecf20Sopenharmony_ci				list_for_each_entry(n, &ctx->names_list, list) {
6138c2ecf20Sopenharmony_ci					if (audit_uid_comparator(n->uid, f->op, f->uid)) {
6148c2ecf20Sopenharmony_ci						++result;
6158c2ecf20Sopenharmony_ci						break;
6168c2ecf20Sopenharmony_ci					}
6178c2ecf20Sopenharmony_ci				}
6188c2ecf20Sopenharmony_ci			}
6198c2ecf20Sopenharmony_ci			break;
6208c2ecf20Sopenharmony_ci		case AUDIT_OBJ_GID:
6218c2ecf20Sopenharmony_ci			if (name) {
6228c2ecf20Sopenharmony_ci				result = audit_gid_comparator(name->gid, f->op, f->gid);
6238c2ecf20Sopenharmony_ci			} else if (ctx) {
6248c2ecf20Sopenharmony_ci				list_for_each_entry(n, &ctx->names_list, list) {
6258c2ecf20Sopenharmony_ci					if (audit_gid_comparator(n->gid, f->op, f->gid)) {
6268c2ecf20Sopenharmony_ci						++result;
6278c2ecf20Sopenharmony_ci						break;
6288c2ecf20Sopenharmony_ci					}
6298c2ecf20Sopenharmony_ci				}
6308c2ecf20Sopenharmony_ci			}
6318c2ecf20Sopenharmony_ci			break;
6328c2ecf20Sopenharmony_ci		case AUDIT_WATCH:
6338c2ecf20Sopenharmony_ci			if (name) {
6348c2ecf20Sopenharmony_ci				result = audit_watch_compare(rule->watch,
6358c2ecf20Sopenharmony_ci							     name->ino,
6368c2ecf20Sopenharmony_ci							     name->dev);
6378c2ecf20Sopenharmony_ci				if (f->op == Audit_not_equal)
6388c2ecf20Sopenharmony_ci					result = !result;
6398c2ecf20Sopenharmony_ci			}
6408c2ecf20Sopenharmony_ci			break;
6418c2ecf20Sopenharmony_ci		case AUDIT_DIR:
6428c2ecf20Sopenharmony_ci			if (ctx) {
6438c2ecf20Sopenharmony_ci				result = match_tree_refs(ctx, rule->tree);
6448c2ecf20Sopenharmony_ci				if (f->op == Audit_not_equal)
6458c2ecf20Sopenharmony_ci					result = !result;
6468c2ecf20Sopenharmony_ci			}
6478c2ecf20Sopenharmony_ci			break;
6488c2ecf20Sopenharmony_ci		case AUDIT_LOGINUID:
6498c2ecf20Sopenharmony_ci			result = audit_uid_comparator(audit_get_loginuid(tsk),
6508c2ecf20Sopenharmony_ci						      f->op, f->uid);
6518c2ecf20Sopenharmony_ci			break;
6528c2ecf20Sopenharmony_ci		case AUDIT_LOGINUID_SET:
6538c2ecf20Sopenharmony_ci			result = audit_comparator(audit_loginuid_set(tsk), f->op, f->val);
6548c2ecf20Sopenharmony_ci			break;
6558c2ecf20Sopenharmony_ci		case AUDIT_SADDR_FAM:
6568c2ecf20Sopenharmony_ci			if (ctx && ctx->sockaddr)
6578c2ecf20Sopenharmony_ci				result = audit_comparator(ctx->sockaddr->ss_family,
6588c2ecf20Sopenharmony_ci							  f->op, f->val);
6598c2ecf20Sopenharmony_ci			break;
6608c2ecf20Sopenharmony_ci		case AUDIT_SUBJ_USER:
6618c2ecf20Sopenharmony_ci		case AUDIT_SUBJ_ROLE:
6628c2ecf20Sopenharmony_ci		case AUDIT_SUBJ_TYPE:
6638c2ecf20Sopenharmony_ci		case AUDIT_SUBJ_SEN:
6648c2ecf20Sopenharmony_ci		case AUDIT_SUBJ_CLR:
6658c2ecf20Sopenharmony_ci			/* NOTE: this may return negative values indicating
6668c2ecf20Sopenharmony_ci			   a temporary error.  We simply treat this as a
6678c2ecf20Sopenharmony_ci			   match for now to avoid losing information that
6688c2ecf20Sopenharmony_ci			   may be wanted.   An error message will also be
6698c2ecf20Sopenharmony_ci			   logged upon error */
6708c2ecf20Sopenharmony_ci			if (f->lsm_rule) {
6718c2ecf20Sopenharmony_ci				if (need_sid) {
6728c2ecf20Sopenharmony_ci					security_task_getsecid(tsk, &sid);
6738c2ecf20Sopenharmony_ci					need_sid = 0;
6748c2ecf20Sopenharmony_ci				}
6758c2ecf20Sopenharmony_ci				result = security_audit_rule_match(sid, f->type,
6768c2ecf20Sopenharmony_ci								   f->op,
6778c2ecf20Sopenharmony_ci								   f->lsm_rule);
6788c2ecf20Sopenharmony_ci			}
6798c2ecf20Sopenharmony_ci			break;
6808c2ecf20Sopenharmony_ci		case AUDIT_OBJ_USER:
6818c2ecf20Sopenharmony_ci		case AUDIT_OBJ_ROLE:
6828c2ecf20Sopenharmony_ci		case AUDIT_OBJ_TYPE:
6838c2ecf20Sopenharmony_ci		case AUDIT_OBJ_LEV_LOW:
6848c2ecf20Sopenharmony_ci		case AUDIT_OBJ_LEV_HIGH:
6858c2ecf20Sopenharmony_ci			/* The above note for AUDIT_SUBJ_USER...AUDIT_SUBJ_CLR
6868c2ecf20Sopenharmony_ci			   also applies here */
6878c2ecf20Sopenharmony_ci			if (f->lsm_rule) {
6888c2ecf20Sopenharmony_ci				/* Find files that match */
6898c2ecf20Sopenharmony_ci				if (name) {
6908c2ecf20Sopenharmony_ci					result = security_audit_rule_match(
6918c2ecf20Sopenharmony_ci								name->osid,
6928c2ecf20Sopenharmony_ci								f->type,
6938c2ecf20Sopenharmony_ci								f->op,
6948c2ecf20Sopenharmony_ci								f->lsm_rule);
6958c2ecf20Sopenharmony_ci				} else if (ctx) {
6968c2ecf20Sopenharmony_ci					list_for_each_entry(n, &ctx->names_list, list) {
6978c2ecf20Sopenharmony_ci						if (security_audit_rule_match(
6988c2ecf20Sopenharmony_ci								n->osid,
6998c2ecf20Sopenharmony_ci								f->type,
7008c2ecf20Sopenharmony_ci								f->op,
7018c2ecf20Sopenharmony_ci								f->lsm_rule)) {
7028c2ecf20Sopenharmony_ci							++result;
7038c2ecf20Sopenharmony_ci							break;
7048c2ecf20Sopenharmony_ci						}
7058c2ecf20Sopenharmony_ci					}
7068c2ecf20Sopenharmony_ci				}
7078c2ecf20Sopenharmony_ci				/* Find ipc objects that match */
7088c2ecf20Sopenharmony_ci				if (!ctx || ctx->type != AUDIT_IPC)
7098c2ecf20Sopenharmony_ci					break;
7108c2ecf20Sopenharmony_ci				if (security_audit_rule_match(ctx->ipc.osid,
7118c2ecf20Sopenharmony_ci							      f->type, f->op,
7128c2ecf20Sopenharmony_ci							      f->lsm_rule))
7138c2ecf20Sopenharmony_ci					++result;
7148c2ecf20Sopenharmony_ci			}
7158c2ecf20Sopenharmony_ci			break;
7168c2ecf20Sopenharmony_ci		case AUDIT_ARG0:
7178c2ecf20Sopenharmony_ci		case AUDIT_ARG1:
7188c2ecf20Sopenharmony_ci		case AUDIT_ARG2:
7198c2ecf20Sopenharmony_ci		case AUDIT_ARG3:
7208c2ecf20Sopenharmony_ci			if (ctx)
7218c2ecf20Sopenharmony_ci				result = audit_comparator(ctx->argv[f->type-AUDIT_ARG0], f->op, f->val);
7228c2ecf20Sopenharmony_ci			break;
7238c2ecf20Sopenharmony_ci		case AUDIT_FILTERKEY:
7248c2ecf20Sopenharmony_ci			/* ignore this field for filtering */
7258c2ecf20Sopenharmony_ci			result = 1;
7268c2ecf20Sopenharmony_ci			break;
7278c2ecf20Sopenharmony_ci		case AUDIT_PERM:
7288c2ecf20Sopenharmony_ci			result = audit_match_perm(ctx, f->val);
7298c2ecf20Sopenharmony_ci			if (f->op == Audit_not_equal)
7308c2ecf20Sopenharmony_ci				result = !result;
7318c2ecf20Sopenharmony_ci			break;
7328c2ecf20Sopenharmony_ci		case AUDIT_FILETYPE:
7338c2ecf20Sopenharmony_ci			result = audit_match_filetype(ctx, f->val);
7348c2ecf20Sopenharmony_ci			if (f->op == Audit_not_equal)
7358c2ecf20Sopenharmony_ci				result = !result;
7368c2ecf20Sopenharmony_ci			break;
7378c2ecf20Sopenharmony_ci		case AUDIT_FIELD_COMPARE:
7388c2ecf20Sopenharmony_ci			result = audit_field_compare(tsk, cred, f, ctx, name);
7398c2ecf20Sopenharmony_ci			break;
7408c2ecf20Sopenharmony_ci		}
7418c2ecf20Sopenharmony_ci		if (!result)
7428c2ecf20Sopenharmony_ci			return 0;
7438c2ecf20Sopenharmony_ci	}
7448c2ecf20Sopenharmony_ci
7458c2ecf20Sopenharmony_ci	if (ctx) {
7468c2ecf20Sopenharmony_ci		if (rule->prio <= ctx->prio)
7478c2ecf20Sopenharmony_ci			return 0;
7488c2ecf20Sopenharmony_ci		if (rule->filterkey) {
7498c2ecf20Sopenharmony_ci			kfree(ctx->filterkey);
7508c2ecf20Sopenharmony_ci			ctx->filterkey = kstrdup(rule->filterkey, GFP_ATOMIC);
7518c2ecf20Sopenharmony_ci		}
7528c2ecf20Sopenharmony_ci		ctx->prio = rule->prio;
7538c2ecf20Sopenharmony_ci	}
7548c2ecf20Sopenharmony_ci	switch (rule->action) {
7558c2ecf20Sopenharmony_ci	case AUDIT_NEVER:
7568c2ecf20Sopenharmony_ci		*state = AUDIT_DISABLED;
7578c2ecf20Sopenharmony_ci		break;
7588c2ecf20Sopenharmony_ci	case AUDIT_ALWAYS:
7598c2ecf20Sopenharmony_ci		*state = AUDIT_RECORD_CONTEXT;
7608c2ecf20Sopenharmony_ci		break;
7618c2ecf20Sopenharmony_ci	}
7628c2ecf20Sopenharmony_ci	return 1;
7638c2ecf20Sopenharmony_ci}
7648c2ecf20Sopenharmony_ci
7658c2ecf20Sopenharmony_ci/* At process creation time, we can determine if system-call auditing is
7668c2ecf20Sopenharmony_ci * completely disabled for this task.  Since we only have the task
7678c2ecf20Sopenharmony_ci * structure at this point, we can only check uid and gid.
7688c2ecf20Sopenharmony_ci */
7698c2ecf20Sopenharmony_cistatic enum audit_state audit_filter_task(struct task_struct *tsk, char **key)
7708c2ecf20Sopenharmony_ci{
7718c2ecf20Sopenharmony_ci	struct audit_entry *e;
7728c2ecf20Sopenharmony_ci	enum audit_state   state;
7738c2ecf20Sopenharmony_ci
7748c2ecf20Sopenharmony_ci	rcu_read_lock();
7758c2ecf20Sopenharmony_ci	list_for_each_entry_rcu(e, &audit_filter_list[AUDIT_FILTER_TASK], list) {
7768c2ecf20Sopenharmony_ci		if (audit_filter_rules(tsk, &e->rule, NULL, NULL,
7778c2ecf20Sopenharmony_ci				       &state, true)) {
7788c2ecf20Sopenharmony_ci			if (state == AUDIT_RECORD_CONTEXT)
7798c2ecf20Sopenharmony_ci				*key = kstrdup(e->rule.filterkey, GFP_ATOMIC);
7808c2ecf20Sopenharmony_ci			rcu_read_unlock();
7818c2ecf20Sopenharmony_ci			return state;
7828c2ecf20Sopenharmony_ci		}
7838c2ecf20Sopenharmony_ci	}
7848c2ecf20Sopenharmony_ci	rcu_read_unlock();
7858c2ecf20Sopenharmony_ci	return AUDIT_BUILD_CONTEXT;
7868c2ecf20Sopenharmony_ci}
7878c2ecf20Sopenharmony_ci
7888c2ecf20Sopenharmony_cistatic int audit_in_mask(const struct audit_krule *rule, unsigned long val)
7898c2ecf20Sopenharmony_ci{
7908c2ecf20Sopenharmony_ci	int word, bit;
7918c2ecf20Sopenharmony_ci
7928c2ecf20Sopenharmony_ci	if (val > 0xffffffff)
7938c2ecf20Sopenharmony_ci		return false;
7948c2ecf20Sopenharmony_ci
7958c2ecf20Sopenharmony_ci	word = AUDIT_WORD(val);
7968c2ecf20Sopenharmony_ci	if (word >= AUDIT_BITMASK_SIZE)
7978c2ecf20Sopenharmony_ci		return false;
7988c2ecf20Sopenharmony_ci
7998c2ecf20Sopenharmony_ci	bit = AUDIT_BIT(val);
8008c2ecf20Sopenharmony_ci
8018c2ecf20Sopenharmony_ci	return rule->mask[word] & bit;
8028c2ecf20Sopenharmony_ci}
8038c2ecf20Sopenharmony_ci
8048c2ecf20Sopenharmony_ci/* At syscall entry and exit time, this filter is called if the
8058c2ecf20Sopenharmony_ci * audit_state is not low enough that auditing cannot take place, but is
8068c2ecf20Sopenharmony_ci * also not high enough that we already know we have to write an audit
8078c2ecf20Sopenharmony_ci * record (i.e., the state is AUDIT_SETUP_CONTEXT or AUDIT_BUILD_CONTEXT).
8088c2ecf20Sopenharmony_ci */
8098c2ecf20Sopenharmony_cistatic enum audit_state audit_filter_syscall(struct task_struct *tsk,
8108c2ecf20Sopenharmony_ci					     struct audit_context *ctx,
8118c2ecf20Sopenharmony_ci					     struct list_head *list)
8128c2ecf20Sopenharmony_ci{
8138c2ecf20Sopenharmony_ci	struct audit_entry *e;
8148c2ecf20Sopenharmony_ci	enum audit_state state;
8158c2ecf20Sopenharmony_ci
8168c2ecf20Sopenharmony_ci	if (auditd_test_task(tsk))
8178c2ecf20Sopenharmony_ci		return AUDIT_DISABLED;
8188c2ecf20Sopenharmony_ci
8198c2ecf20Sopenharmony_ci	rcu_read_lock();
8208c2ecf20Sopenharmony_ci	list_for_each_entry_rcu(e, list, list) {
8218c2ecf20Sopenharmony_ci		if (audit_in_mask(&e->rule, ctx->major) &&
8228c2ecf20Sopenharmony_ci		    audit_filter_rules(tsk, &e->rule, ctx, NULL,
8238c2ecf20Sopenharmony_ci				       &state, false)) {
8248c2ecf20Sopenharmony_ci			rcu_read_unlock();
8258c2ecf20Sopenharmony_ci			ctx->current_state = state;
8268c2ecf20Sopenharmony_ci			return state;
8278c2ecf20Sopenharmony_ci		}
8288c2ecf20Sopenharmony_ci	}
8298c2ecf20Sopenharmony_ci	rcu_read_unlock();
8308c2ecf20Sopenharmony_ci	return AUDIT_BUILD_CONTEXT;
8318c2ecf20Sopenharmony_ci}
8328c2ecf20Sopenharmony_ci
8338c2ecf20Sopenharmony_ci/*
8348c2ecf20Sopenharmony_ci * Given an audit_name check the inode hash table to see if they match.
8358c2ecf20Sopenharmony_ci * Called holding the rcu read lock to protect the use of audit_inode_hash
8368c2ecf20Sopenharmony_ci */
8378c2ecf20Sopenharmony_cistatic int audit_filter_inode_name(struct task_struct *tsk,
8388c2ecf20Sopenharmony_ci				   struct audit_names *n,
8398c2ecf20Sopenharmony_ci				   struct audit_context *ctx) {
8408c2ecf20Sopenharmony_ci	int h = audit_hash_ino((u32)n->ino);
8418c2ecf20Sopenharmony_ci	struct list_head *list = &audit_inode_hash[h];
8428c2ecf20Sopenharmony_ci	struct audit_entry *e;
8438c2ecf20Sopenharmony_ci	enum audit_state state;
8448c2ecf20Sopenharmony_ci
8458c2ecf20Sopenharmony_ci	list_for_each_entry_rcu(e, list, list) {
8468c2ecf20Sopenharmony_ci		if (audit_in_mask(&e->rule, ctx->major) &&
8478c2ecf20Sopenharmony_ci		    audit_filter_rules(tsk, &e->rule, ctx, n, &state, false)) {
8488c2ecf20Sopenharmony_ci			ctx->current_state = state;
8498c2ecf20Sopenharmony_ci			return 1;
8508c2ecf20Sopenharmony_ci		}
8518c2ecf20Sopenharmony_ci	}
8528c2ecf20Sopenharmony_ci	return 0;
8538c2ecf20Sopenharmony_ci}
8548c2ecf20Sopenharmony_ci
8558c2ecf20Sopenharmony_ci/* At syscall exit time, this filter is called if any audit_names have been
8568c2ecf20Sopenharmony_ci * collected during syscall processing.  We only check rules in sublists at hash
8578c2ecf20Sopenharmony_ci * buckets applicable to the inode numbers in audit_names.
8588c2ecf20Sopenharmony_ci * Regarding audit_state, same rules apply as for audit_filter_syscall().
8598c2ecf20Sopenharmony_ci */
8608c2ecf20Sopenharmony_civoid audit_filter_inodes(struct task_struct *tsk, struct audit_context *ctx)
8618c2ecf20Sopenharmony_ci{
8628c2ecf20Sopenharmony_ci	struct audit_names *n;
8638c2ecf20Sopenharmony_ci
8648c2ecf20Sopenharmony_ci	if (auditd_test_task(tsk))
8658c2ecf20Sopenharmony_ci		return;
8668c2ecf20Sopenharmony_ci
8678c2ecf20Sopenharmony_ci	rcu_read_lock();
8688c2ecf20Sopenharmony_ci
8698c2ecf20Sopenharmony_ci	list_for_each_entry(n, &ctx->names_list, list) {
8708c2ecf20Sopenharmony_ci		if (audit_filter_inode_name(tsk, n, ctx))
8718c2ecf20Sopenharmony_ci			break;
8728c2ecf20Sopenharmony_ci	}
8738c2ecf20Sopenharmony_ci	rcu_read_unlock();
8748c2ecf20Sopenharmony_ci}
8758c2ecf20Sopenharmony_ci
8768c2ecf20Sopenharmony_cistatic inline void audit_proctitle_free(struct audit_context *context)
8778c2ecf20Sopenharmony_ci{
8788c2ecf20Sopenharmony_ci	kfree(context->proctitle.value);
8798c2ecf20Sopenharmony_ci	context->proctitle.value = NULL;
8808c2ecf20Sopenharmony_ci	context->proctitle.len = 0;
8818c2ecf20Sopenharmony_ci}
8828c2ecf20Sopenharmony_ci
8838c2ecf20Sopenharmony_cistatic inline void audit_free_module(struct audit_context *context)
8848c2ecf20Sopenharmony_ci{
8858c2ecf20Sopenharmony_ci	if (context->type == AUDIT_KERN_MODULE) {
8868c2ecf20Sopenharmony_ci		kfree(context->module.name);
8878c2ecf20Sopenharmony_ci		context->module.name = NULL;
8888c2ecf20Sopenharmony_ci	}
8898c2ecf20Sopenharmony_ci}
8908c2ecf20Sopenharmony_cistatic inline void audit_free_names(struct audit_context *context)
8918c2ecf20Sopenharmony_ci{
8928c2ecf20Sopenharmony_ci	struct audit_names *n, *next;
8938c2ecf20Sopenharmony_ci
8948c2ecf20Sopenharmony_ci	list_for_each_entry_safe(n, next, &context->names_list, list) {
8958c2ecf20Sopenharmony_ci		list_del(&n->list);
8968c2ecf20Sopenharmony_ci		if (n->name)
8978c2ecf20Sopenharmony_ci			putname(n->name);
8988c2ecf20Sopenharmony_ci		if (n->should_free)
8998c2ecf20Sopenharmony_ci			kfree(n);
9008c2ecf20Sopenharmony_ci	}
9018c2ecf20Sopenharmony_ci	context->name_count = 0;
9028c2ecf20Sopenharmony_ci	path_put(&context->pwd);
9038c2ecf20Sopenharmony_ci	context->pwd.dentry = NULL;
9048c2ecf20Sopenharmony_ci	context->pwd.mnt = NULL;
9058c2ecf20Sopenharmony_ci}
9068c2ecf20Sopenharmony_ci
9078c2ecf20Sopenharmony_cistatic inline void audit_free_aux(struct audit_context *context)
9088c2ecf20Sopenharmony_ci{
9098c2ecf20Sopenharmony_ci	struct audit_aux_data *aux;
9108c2ecf20Sopenharmony_ci
9118c2ecf20Sopenharmony_ci	while ((aux = context->aux)) {
9128c2ecf20Sopenharmony_ci		context->aux = aux->next;
9138c2ecf20Sopenharmony_ci		kfree(aux);
9148c2ecf20Sopenharmony_ci	}
9158c2ecf20Sopenharmony_ci	while ((aux = context->aux_pids)) {
9168c2ecf20Sopenharmony_ci		context->aux_pids = aux->next;
9178c2ecf20Sopenharmony_ci		kfree(aux);
9188c2ecf20Sopenharmony_ci	}
9198c2ecf20Sopenharmony_ci}
9208c2ecf20Sopenharmony_ci
9218c2ecf20Sopenharmony_cistatic inline struct audit_context *audit_alloc_context(enum audit_state state)
9228c2ecf20Sopenharmony_ci{
9238c2ecf20Sopenharmony_ci	struct audit_context *context;
9248c2ecf20Sopenharmony_ci
9258c2ecf20Sopenharmony_ci	context = kzalloc(sizeof(*context), GFP_KERNEL);
9268c2ecf20Sopenharmony_ci	if (!context)
9278c2ecf20Sopenharmony_ci		return NULL;
9288c2ecf20Sopenharmony_ci	context->state = state;
9298c2ecf20Sopenharmony_ci	context->prio = state == AUDIT_RECORD_CONTEXT ? ~0ULL : 0;
9308c2ecf20Sopenharmony_ci	INIT_LIST_HEAD(&context->killed_trees);
9318c2ecf20Sopenharmony_ci	INIT_LIST_HEAD(&context->names_list);
9328c2ecf20Sopenharmony_ci	return context;
9338c2ecf20Sopenharmony_ci}
9348c2ecf20Sopenharmony_ci
9358c2ecf20Sopenharmony_ci/**
9368c2ecf20Sopenharmony_ci * audit_alloc - allocate an audit context block for a task
9378c2ecf20Sopenharmony_ci * @tsk: task
9388c2ecf20Sopenharmony_ci *
9398c2ecf20Sopenharmony_ci * Filter on the task information and allocate a per-task audit context
9408c2ecf20Sopenharmony_ci * if necessary.  Doing so turns on system call auditing for the
9418c2ecf20Sopenharmony_ci * specified task.  This is called from copy_process, so no lock is
9428c2ecf20Sopenharmony_ci * needed.
9438c2ecf20Sopenharmony_ci */
9448c2ecf20Sopenharmony_ciint audit_alloc(struct task_struct *tsk)
9458c2ecf20Sopenharmony_ci{
9468c2ecf20Sopenharmony_ci	struct audit_context *context;
9478c2ecf20Sopenharmony_ci	enum audit_state     state;
9488c2ecf20Sopenharmony_ci	char *key = NULL;
9498c2ecf20Sopenharmony_ci
9508c2ecf20Sopenharmony_ci	if (likely(!audit_ever_enabled))
9518c2ecf20Sopenharmony_ci		return 0; /* Return if not auditing. */
9528c2ecf20Sopenharmony_ci
9538c2ecf20Sopenharmony_ci	state = audit_filter_task(tsk, &key);
9548c2ecf20Sopenharmony_ci	if (state == AUDIT_DISABLED) {
9558c2ecf20Sopenharmony_ci		clear_tsk_thread_flag(tsk, TIF_SYSCALL_AUDIT);
9568c2ecf20Sopenharmony_ci		return 0;
9578c2ecf20Sopenharmony_ci	}
9588c2ecf20Sopenharmony_ci
9598c2ecf20Sopenharmony_ci	if (!(context = audit_alloc_context(state))) {
9608c2ecf20Sopenharmony_ci		kfree(key);
9618c2ecf20Sopenharmony_ci		audit_log_lost("out of memory in audit_alloc");
9628c2ecf20Sopenharmony_ci		return -ENOMEM;
9638c2ecf20Sopenharmony_ci	}
9648c2ecf20Sopenharmony_ci	context->filterkey = key;
9658c2ecf20Sopenharmony_ci
9668c2ecf20Sopenharmony_ci	audit_set_context(tsk, context);
9678c2ecf20Sopenharmony_ci	set_tsk_thread_flag(tsk, TIF_SYSCALL_AUDIT);
9688c2ecf20Sopenharmony_ci	return 0;
9698c2ecf20Sopenharmony_ci}
9708c2ecf20Sopenharmony_ci
9718c2ecf20Sopenharmony_cistatic inline void audit_free_context(struct audit_context *context)
9728c2ecf20Sopenharmony_ci{
9738c2ecf20Sopenharmony_ci	audit_free_module(context);
9748c2ecf20Sopenharmony_ci	audit_free_names(context);
9758c2ecf20Sopenharmony_ci	unroll_tree_refs(context, NULL, 0);
9768c2ecf20Sopenharmony_ci	free_tree_refs(context);
9778c2ecf20Sopenharmony_ci	audit_free_aux(context);
9788c2ecf20Sopenharmony_ci	kfree(context->filterkey);
9798c2ecf20Sopenharmony_ci	kfree(context->sockaddr);
9808c2ecf20Sopenharmony_ci	audit_proctitle_free(context);
9818c2ecf20Sopenharmony_ci	kfree(context);
9828c2ecf20Sopenharmony_ci}
9838c2ecf20Sopenharmony_ci
9848c2ecf20Sopenharmony_cistatic int audit_log_pid_context(struct audit_context *context, pid_t pid,
9858c2ecf20Sopenharmony_ci				 kuid_t auid, kuid_t uid, unsigned int sessionid,
9868c2ecf20Sopenharmony_ci				 u32 sid, char *comm)
9878c2ecf20Sopenharmony_ci{
9888c2ecf20Sopenharmony_ci	struct audit_buffer *ab;
9898c2ecf20Sopenharmony_ci	char *ctx = NULL;
9908c2ecf20Sopenharmony_ci	u32 len;
9918c2ecf20Sopenharmony_ci	int rc = 0;
9928c2ecf20Sopenharmony_ci
9938c2ecf20Sopenharmony_ci	ab = audit_log_start(context, GFP_KERNEL, AUDIT_OBJ_PID);
9948c2ecf20Sopenharmony_ci	if (!ab)
9958c2ecf20Sopenharmony_ci		return rc;
9968c2ecf20Sopenharmony_ci
9978c2ecf20Sopenharmony_ci	audit_log_format(ab, "opid=%d oauid=%d ouid=%d oses=%d", pid,
9988c2ecf20Sopenharmony_ci			 from_kuid(&init_user_ns, auid),
9998c2ecf20Sopenharmony_ci			 from_kuid(&init_user_ns, uid), sessionid);
10008c2ecf20Sopenharmony_ci	if (sid) {
10018c2ecf20Sopenharmony_ci		if (security_secid_to_secctx(sid, &ctx, &len)) {
10028c2ecf20Sopenharmony_ci			audit_log_format(ab, " obj=(none)");
10038c2ecf20Sopenharmony_ci			rc = 1;
10048c2ecf20Sopenharmony_ci		} else {
10058c2ecf20Sopenharmony_ci			audit_log_format(ab, " obj=%s", ctx);
10068c2ecf20Sopenharmony_ci			security_release_secctx(ctx, len);
10078c2ecf20Sopenharmony_ci		}
10088c2ecf20Sopenharmony_ci	}
10098c2ecf20Sopenharmony_ci	audit_log_format(ab, " ocomm=");
10108c2ecf20Sopenharmony_ci	audit_log_untrustedstring(ab, comm);
10118c2ecf20Sopenharmony_ci	audit_log_end(ab);
10128c2ecf20Sopenharmony_ci
10138c2ecf20Sopenharmony_ci	return rc;
10148c2ecf20Sopenharmony_ci}
10158c2ecf20Sopenharmony_ci
10168c2ecf20Sopenharmony_cistatic void audit_log_execve_info(struct audit_context *context,
10178c2ecf20Sopenharmony_ci				  struct audit_buffer **ab)
10188c2ecf20Sopenharmony_ci{
10198c2ecf20Sopenharmony_ci	long len_max;
10208c2ecf20Sopenharmony_ci	long len_rem;
10218c2ecf20Sopenharmony_ci	long len_full;
10228c2ecf20Sopenharmony_ci	long len_buf;
10238c2ecf20Sopenharmony_ci	long len_abuf = 0;
10248c2ecf20Sopenharmony_ci	long len_tmp;
10258c2ecf20Sopenharmony_ci	bool require_data;
10268c2ecf20Sopenharmony_ci	bool encode;
10278c2ecf20Sopenharmony_ci	unsigned int iter;
10288c2ecf20Sopenharmony_ci	unsigned int arg;
10298c2ecf20Sopenharmony_ci	char *buf_head;
10308c2ecf20Sopenharmony_ci	char *buf;
10318c2ecf20Sopenharmony_ci	const char __user *p = (const char __user *)current->mm->arg_start;
10328c2ecf20Sopenharmony_ci
10338c2ecf20Sopenharmony_ci	/* NOTE: this buffer needs to be large enough to hold all the non-arg
10348c2ecf20Sopenharmony_ci	 *       data we put in the audit record for this argument (see the
10358c2ecf20Sopenharmony_ci	 *       code below) ... at this point in time 96 is plenty */
10368c2ecf20Sopenharmony_ci	char abuf[96];
10378c2ecf20Sopenharmony_ci
10388c2ecf20Sopenharmony_ci	/* NOTE: we set MAX_EXECVE_AUDIT_LEN to a rather arbitrary limit, the
10398c2ecf20Sopenharmony_ci	 *       current value of 7500 is not as important as the fact that it
10408c2ecf20Sopenharmony_ci	 *       is less than 8k, a setting of 7500 gives us plenty of wiggle
10418c2ecf20Sopenharmony_ci	 *       room if we go over a little bit in the logging below */
10428c2ecf20Sopenharmony_ci	WARN_ON_ONCE(MAX_EXECVE_AUDIT_LEN > 7500);
10438c2ecf20Sopenharmony_ci	len_max = MAX_EXECVE_AUDIT_LEN;
10448c2ecf20Sopenharmony_ci
10458c2ecf20Sopenharmony_ci	/* scratch buffer to hold the userspace args */
10468c2ecf20Sopenharmony_ci	buf_head = kmalloc(MAX_EXECVE_AUDIT_LEN + 1, GFP_KERNEL);
10478c2ecf20Sopenharmony_ci	if (!buf_head) {
10488c2ecf20Sopenharmony_ci		audit_panic("out of memory for argv string");
10498c2ecf20Sopenharmony_ci		return;
10508c2ecf20Sopenharmony_ci	}
10518c2ecf20Sopenharmony_ci	buf = buf_head;
10528c2ecf20Sopenharmony_ci
10538c2ecf20Sopenharmony_ci	audit_log_format(*ab, "argc=%d", context->execve.argc);
10548c2ecf20Sopenharmony_ci
10558c2ecf20Sopenharmony_ci	len_rem = len_max;
10568c2ecf20Sopenharmony_ci	len_buf = 0;
10578c2ecf20Sopenharmony_ci	len_full = 0;
10588c2ecf20Sopenharmony_ci	require_data = true;
10598c2ecf20Sopenharmony_ci	encode = false;
10608c2ecf20Sopenharmony_ci	iter = 0;
10618c2ecf20Sopenharmony_ci	arg = 0;
10628c2ecf20Sopenharmony_ci	do {
10638c2ecf20Sopenharmony_ci		/* NOTE: we don't ever want to trust this value for anything
10648c2ecf20Sopenharmony_ci		 *       serious, but the audit record format insists we
10658c2ecf20Sopenharmony_ci		 *       provide an argument length for really long arguments,
10668c2ecf20Sopenharmony_ci		 *       e.g. > MAX_EXECVE_AUDIT_LEN, so we have no choice but
10678c2ecf20Sopenharmony_ci		 *       to use strncpy_from_user() to obtain this value for
10688c2ecf20Sopenharmony_ci		 *       recording in the log, although we don't use it
10698c2ecf20Sopenharmony_ci		 *       anywhere here to avoid a double-fetch problem */
10708c2ecf20Sopenharmony_ci		if (len_full == 0)
10718c2ecf20Sopenharmony_ci			len_full = strnlen_user(p, MAX_ARG_STRLEN) - 1;
10728c2ecf20Sopenharmony_ci
10738c2ecf20Sopenharmony_ci		/* read more data from userspace */
10748c2ecf20Sopenharmony_ci		if (require_data) {
10758c2ecf20Sopenharmony_ci			/* can we make more room in the buffer? */
10768c2ecf20Sopenharmony_ci			if (buf != buf_head) {
10778c2ecf20Sopenharmony_ci				memmove(buf_head, buf, len_buf);
10788c2ecf20Sopenharmony_ci				buf = buf_head;
10798c2ecf20Sopenharmony_ci			}
10808c2ecf20Sopenharmony_ci
10818c2ecf20Sopenharmony_ci			/* fetch as much as we can of the argument */
10828c2ecf20Sopenharmony_ci			len_tmp = strncpy_from_user(&buf_head[len_buf], p,
10838c2ecf20Sopenharmony_ci						    len_max - len_buf);
10848c2ecf20Sopenharmony_ci			if (len_tmp == -EFAULT) {
10858c2ecf20Sopenharmony_ci				/* unable to copy from userspace */
10868c2ecf20Sopenharmony_ci				send_sig(SIGKILL, current, 0);
10878c2ecf20Sopenharmony_ci				goto out;
10888c2ecf20Sopenharmony_ci			} else if (len_tmp == (len_max - len_buf)) {
10898c2ecf20Sopenharmony_ci				/* buffer is not large enough */
10908c2ecf20Sopenharmony_ci				require_data = true;
10918c2ecf20Sopenharmony_ci				/* NOTE: if we are going to span multiple
10928c2ecf20Sopenharmony_ci				 *       buffers force the encoding so we stand
10938c2ecf20Sopenharmony_ci				 *       a chance at a sane len_full value and
10948c2ecf20Sopenharmony_ci				 *       consistent record encoding */
10958c2ecf20Sopenharmony_ci				encode = true;
10968c2ecf20Sopenharmony_ci				len_full = len_full * 2;
10978c2ecf20Sopenharmony_ci				p += len_tmp;
10988c2ecf20Sopenharmony_ci			} else {
10998c2ecf20Sopenharmony_ci				require_data = false;
11008c2ecf20Sopenharmony_ci				if (!encode)
11018c2ecf20Sopenharmony_ci					encode = audit_string_contains_control(
11028c2ecf20Sopenharmony_ci								buf, len_tmp);
11038c2ecf20Sopenharmony_ci				/* try to use a trusted value for len_full */
11048c2ecf20Sopenharmony_ci				if (len_full < len_max)
11058c2ecf20Sopenharmony_ci					len_full = (encode ?
11068c2ecf20Sopenharmony_ci						    len_tmp * 2 : len_tmp);
11078c2ecf20Sopenharmony_ci				p += len_tmp + 1;
11088c2ecf20Sopenharmony_ci			}
11098c2ecf20Sopenharmony_ci			len_buf += len_tmp;
11108c2ecf20Sopenharmony_ci			buf_head[len_buf] = '\0';
11118c2ecf20Sopenharmony_ci
11128c2ecf20Sopenharmony_ci			/* length of the buffer in the audit record? */
11138c2ecf20Sopenharmony_ci			len_abuf = (encode ? len_buf * 2 : len_buf + 2);
11148c2ecf20Sopenharmony_ci		}
11158c2ecf20Sopenharmony_ci
11168c2ecf20Sopenharmony_ci		/* write as much as we can to the audit log */
11178c2ecf20Sopenharmony_ci		if (len_buf >= 0) {
11188c2ecf20Sopenharmony_ci			/* NOTE: some magic numbers here - basically if we
11198c2ecf20Sopenharmony_ci			 *       can't fit a reasonable amount of data into the
11208c2ecf20Sopenharmony_ci			 *       existing audit buffer, flush it and start with
11218c2ecf20Sopenharmony_ci			 *       a new buffer */
11228c2ecf20Sopenharmony_ci			if ((sizeof(abuf) + 8) > len_rem) {
11238c2ecf20Sopenharmony_ci				len_rem = len_max;
11248c2ecf20Sopenharmony_ci				audit_log_end(*ab);
11258c2ecf20Sopenharmony_ci				*ab = audit_log_start(context,
11268c2ecf20Sopenharmony_ci						      GFP_KERNEL, AUDIT_EXECVE);
11278c2ecf20Sopenharmony_ci				if (!*ab)
11288c2ecf20Sopenharmony_ci					goto out;
11298c2ecf20Sopenharmony_ci			}
11308c2ecf20Sopenharmony_ci
11318c2ecf20Sopenharmony_ci			/* create the non-arg portion of the arg record */
11328c2ecf20Sopenharmony_ci			len_tmp = 0;
11338c2ecf20Sopenharmony_ci			if (require_data || (iter > 0) ||
11348c2ecf20Sopenharmony_ci			    ((len_abuf + sizeof(abuf)) > len_rem)) {
11358c2ecf20Sopenharmony_ci				if (iter == 0) {
11368c2ecf20Sopenharmony_ci					len_tmp += snprintf(&abuf[len_tmp],
11378c2ecf20Sopenharmony_ci							sizeof(abuf) - len_tmp,
11388c2ecf20Sopenharmony_ci							" a%d_len=%lu",
11398c2ecf20Sopenharmony_ci							arg, len_full);
11408c2ecf20Sopenharmony_ci				}
11418c2ecf20Sopenharmony_ci				len_tmp += snprintf(&abuf[len_tmp],
11428c2ecf20Sopenharmony_ci						    sizeof(abuf) - len_tmp,
11438c2ecf20Sopenharmony_ci						    " a%d[%d]=", arg, iter++);
11448c2ecf20Sopenharmony_ci			} else
11458c2ecf20Sopenharmony_ci				len_tmp += snprintf(&abuf[len_tmp],
11468c2ecf20Sopenharmony_ci						    sizeof(abuf) - len_tmp,
11478c2ecf20Sopenharmony_ci						    " a%d=", arg);
11488c2ecf20Sopenharmony_ci			WARN_ON(len_tmp >= sizeof(abuf));
11498c2ecf20Sopenharmony_ci			abuf[sizeof(abuf) - 1] = '\0';
11508c2ecf20Sopenharmony_ci
11518c2ecf20Sopenharmony_ci			/* log the arg in the audit record */
11528c2ecf20Sopenharmony_ci			audit_log_format(*ab, "%s", abuf);
11538c2ecf20Sopenharmony_ci			len_rem -= len_tmp;
11548c2ecf20Sopenharmony_ci			len_tmp = len_buf;
11558c2ecf20Sopenharmony_ci			if (encode) {
11568c2ecf20Sopenharmony_ci				if (len_abuf > len_rem)
11578c2ecf20Sopenharmony_ci					len_tmp = len_rem / 2; /* encoding */
11588c2ecf20Sopenharmony_ci				audit_log_n_hex(*ab, buf, len_tmp);
11598c2ecf20Sopenharmony_ci				len_rem -= len_tmp * 2;
11608c2ecf20Sopenharmony_ci				len_abuf -= len_tmp * 2;
11618c2ecf20Sopenharmony_ci			} else {
11628c2ecf20Sopenharmony_ci				if (len_abuf > len_rem)
11638c2ecf20Sopenharmony_ci					len_tmp = len_rem - 2; /* quotes */
11648c2ecf20Sopenharmony_ci				audit_log_n_string(*ab, buf, len_tmp);
11658c2ecf20Sopenharmony_ci				len_rem -= len_tmp + 2;
11668c2ecf20Sopenharmony_ci				/* don't subtract the "2" because we still need
11678c2ecf20Sopenharmony_ci				 * to add quotes to the remaining string */
11688c2ecf20Sopenharmony_ci				len_abuf -= len_tmp;
11698c2ecf20Sopenharmony_ci			}
11708c2ecf20Sopenharmony_ci			len_buf -= len_tmp;
11718c2ecf20Sopenharmony_ci			buf += len_tmp;
11728c2ecf20Sopenharmony_ci		}
11738c2ecf20Sopenharmony_ci
11748c2ecf20Sopenharmony_ci		/* ready to move to the next argument? */
11758c2ecf20Sopenharmony_ci		if ((len_buf == 0) && !require_data) {
11768c2ecf20Sopenharmony_ci			arg++;
11778c2ecf20Sopenharmony_ci			iter = 0;
11788c2ecf20Sopenharmony_ci			len_full = 0;
11798c2ecf20Sopenharmony_ci			require_data = true;
11808c2ecf20Sopenharmony_ci			encode = false;
11818c2ecf20Sopenharmony_ci		}
11828c2ecf20Sopenharmony_ci	} while (arg < context->execve.argc);
11838c2ecf20Sopenharmony_ci
11848c2ecf20Sopenharmony_ci	/* NOTE: the caller handles the final audit_log_end() call */
11858c2ecf20Sopenharmony_ci
11868c2ecf20Sopenharmony_ciout:
11878c2ecf20Sopenharmony_ci	kfree(buf_head);
11888c2ecf20Sopenharmony_ci}
11898c2ecf20Sopenharmony_ci
11908c2ecf20Sopenharmony_cistatic void audit_log_cap(struct audit_buffer *ab, char *prefix,
11918c2ecf20Sopenharmony_ci			  kernel_cap_t *cap)
11928c2ecf20Sopenharmony_ci{
11938c2ecf20Sopenharmony_ci	int i;
11948c2ecf20Sopenharmony_ci
11958c2ecf20Sopenharmony_ci	if (cap_isclear(*cap)) {
11968c2ecf20Sopenharmony_ci		audit_log_format(ab, " %s=0", prefix);
11978c2ecf20Sopenharmony_ci		return;
11988c2ecf20Sopenharmony_ci	}
11998c2ecf20Sopenharmony_ci	audit_log_format(ab, " %s=", prefix);
12008c2ecf20Sopenharmony_ci	CAP_FOR_EACH_U32(i)
12018c2ecf20Sopenharmony_ci		audit_log_format(ab, "%08x", cap->cap[CAP_LAST_U32 - i]);
12028c2ecf20Sopenharmony_ci}
12038c2ecf20Sopenharmony_ci
12048c2ecf20Sopenharmony_cistatic void audit_log_fcaps(struct audit_buffer *ab, struct audit_names *name)
12058c2ecf20Sopenharmony_ci{
12068c2ecf20Sopenharmony_ci	if (name->fcap_ver == -1) {
12078c2ecf20Sopenharmony_ci		audit_log_format(ab, " cap_fe=? cap_fver=? cap_fp=? cap_fi=?");
12088c2ecf20Sopenharmony_ci		return;
12098c2ecf20Sopenharmony_ci	}
12108c2ecf20Sopenharmony_ci	audit_log_cap(ab, "cap_fp", &name->fcap.permitted);
12118c2ecf20Sopenharmony_ci	audit_log_cap(ab, "cap_fi", &name->fcap.inheritable);
12128c2ecf20Sopenharmony_ci	audit_log_format(ab, " cap_fe=%d cap_fver=%x cap_frootid=%d",
12138c2ecf20Sopenharmony_ci			 name->fcap.fE, name->fcap_ver,
12148c2ecf20Sopenharmony_ci			 from_kuid(&init_user_ns, name->fcap.rootid));
12158c2ecf20Sopenharmony_ci}
12168c2ecf20Sopenharmony_ci
12178c2ecf20Sopenharmony_cistatic void audit_log_time(struct audit_context *context, struct audit_buffer **ab)
12188c2ecf20Sopenharmony_ci{
12198c2ecf20Sopenharmony_ci	const struct audit_ntp_data *ntp = &context->time.ntp_data;
12208c2ecf20Sopenharmony_ci	const struct timespec64 *tk = &context->time.tk_injoffset;
12218c2ecf20Sopenharmony_ci	static const char * const ntp_name[] = {
12228c2ecf20Sopenharmony_ci		"offset",
12238c2ecf20Sopenharmony_ci		"freq",
12248c2ecf20Sopenharmony_ci		"status",
12258c2ecf20Sopenharmony_ci		"tai",
12268c2ecf20Sopenharmony_ci		"tick",
12278c2ecf20Sopenharmony_ci		"adjust",
12288c2ecf20Sopenharmony_ci	};
12298c2ecf20Sopenharmony_ci	int type;
12308c2ecf20Sopenharmony_ci
12318c2ecf20Sopenharmony_ci	if (context->type == AUDIT_TIME_ADJNTPVAL) {
12328c2ecf20Sopenharmony_ci		for (type = 0; type < AUDIT_NTP_NVALS; type++) {
12338c2ecf20Sopenharmony_ci			if (ntp->vals[type].newval != ntp->vals[type].oldval) {
12348c2ecf20Sopenharmony_ci				if (!*ab) {
12358c2ecf20Sopenharmony_ci					*ab = audit_log_start(context,
12368c2ecf20Sopenharmony_ci							GFP_KERNEL,
12378c2ecf20Sopenharmony_ci							AUDIT_TIME_ADJNTPVAL);
12388c2ecf20Sopenharmony_ci					if (!*ab)
12398c2ecf20Sopenharmony_ci						return;
12408c2ecf20Sopenharmony_ci				}
12418c2ecf20Sopenharmony_ci				audit_log_format(*ab, "op=%s old=%lli new=%lli",
12428c2ecf20Sopenharmony_ci						 ntp_name[type],
12438c2ecf20Sopenharmony_ci						 ntp->vals[type].oldval,
12448c2ecf20Sopenharmony_ci						 ntp->vals[type].newval);
12458c2ecf20Sopenharmony_ci				audit_log_end(*ab);
12468c2ecf20Sopenharmony_ci				*ab = NULL;
12478c2ecf20Sopenharmony_ci			}
12488c2ecf20Sopenharmony_ci		}
12498c2ecf20Sopenharmony_ci	}
12508c2ecf20Sopenharmony_ci	if (tk->tv_sec != 0 || tk->tv_nsec != 0) {
12518c2ecf20Sopenharmony_ci		if (!*ab) {
12528c2ecf20Sopenharmony_ci			*ab = audit_log_start(context, GFP_KERNEL,
12538c2ecf20Sopenharmony_ci					      AUDIT_TIME_INJOFFSET);
12548c2ecf20Sopenharmony_ci			if (!*ab)
12558c2ecf20Sopenharmony_ci				return;
12568c2ecf20Sopenharmony_ci		}
12578c2ecf20Sopenharmony_ci		audit_log_format(*ab, "sec=%lli nsec=%li",
12588c2ecf20Sopenharmony_ci				 (long long)tk->tv_sec, tk->tv_nsec);
12598c2ecf20Sopenharmony_ci		audit_log_end(*ab);
12608c2ecf20Sopenharmony_ci		*ab = NULL;
12618c2ecf20Sopenharmony_ci	}
12628c2ecf20Sopenharmony_ci}
12638c2ecf20Sopenharmony_ci
12648c2ecf20Sopenharmony_cistatic void show_special(struct audit_context *context, int *call_panic)
12658c2ecf20Sopenharmony_ci{
12668c2ecf20Sopenharmony_ci	struct audit_buffer *ab;
12678c2ecf20Sopenharmony_ci	int i;
12688c2ecf20Sopenharmony_ci
12698c2ecf20Sopenharmony_ci	ab = audit_log_start(context, GFP_KERNEL, context->type);
12708c2ecf20Sopenharmony_ci	if (!ab)
12718c2ecf20Sopenharmony_ci		return;
12728c2ecf20Sopenharmony_ci
12738c2ecf20Sopenharmony_ci	switch (context->type) {
12748c2ecf20Sopenharmony_ci	case AUDIT_SOCKETCALL: {
12758c2ecf20Sopenharmony_ci		int nargs = context->socketcall.nargs;
12768c2ecf20Sopenharmony_ci		audit_log_format(ab, "nargs=%d", nargs);
12778c2ecf20Sopenharmony_ci		for (i = 0; i < nargs; i++)
12788c2ecf20Sopenharmony_ci			audit_log_format(ab, " a%d=%lx", i,
12798c2ecf20Sopenharmony_ci				context->socketcall.args[i]);
12808c2ecf20Sopenharmony_ci		break; }
12818c2ecf20Sopenharmony_ci	case AUDIT_IPC: {
12828c2ecf20Sopenharmony_ci		u32 osid = context->ipc.osid;
12838c2ecf20Sopenharmony_ci
12848c2ecf20Sopenharmony_ci		audit_log_format(ab, "ouid=%u ogid=%u mode=%#ho",
12858c2ecf20Sopenharmony_ci				 from_kuid(&init_user_ns, context->ipc.uid),
12868c2ecf20Sopenharmony_ci				 from_kgid(&init_user_ns, context->ipc.gid),
12878c2ecf20Sopenharmony_ci				 context->ipc.mode);
12888c2ecf20Sopenharmony_ci		if (osid) {
12898c2ecf20Sopenharmony_ci			char *ctx = NULL;
12908c2ecf20Sopenharmony_ci			u32 len;
12918c2ecf20Sopenharmony_ci			if (security_secid_to_secctx(osid, &ctx, &len)) {
12928c2ecf20Sopenharmony_ci				audit_log_format(ab, " osid=%u", osid);
12938c2ecf20Sopenharmony_ci				*call_panic = 1;
12948c2ecf20Sopenharmony_ci			} else {
12958c2ecf20Sopenharmony_ci				audit_log_format(ab, " obj=%s", ctx);
12968c2ecf20Sopenharmony_ci				security_release_secctx(ctx, len);
12978c2ecf20Sopenharmony_ci			}
12988c2ecf20Sopenharmony_ci		}
12998c2ecf20Sopenharmony_ci		if (context->ipc.has_perm) {
13008c2ecf20Sopenharmony_ci			audit_log_end(ab);
13018c2ecf20Sopenharmony_ci			ab = audit_log_start(context, GFP_KERNEL,
13028c2ecf20Sopenharmony_ci					     AUDIT_IPC_SET_PERM);
13038c2ecf20Sopenharmony_ci			if (unlikely(!ab))
13048c2ecf20Sopenharmony_ci				return;
13058c2ecf20Sopenharmony_ci			audit_log_format(ab,
13068c2ecf20Sopenharmony_ci				"qbytes=%lx ouid=%u ogid=%u mode=%#ho",
13078c2ecf20Sopenharmony_ci				context->ipc.qbytes,
13088c2ecf20Sopenharmony_ci				context->ipc.perm_uid,
13098c2ecf20Sopenharmony_ci				context->ipc.perm_gid,
13108c2ecf20Sopenharmony_ci				context->ipc.perm_mode);
13118c2ecf20Sopenharmony_ci		}
13128c2ecf20Sopenharmony_ci		break; }
13138c2ecf20Sopenharmony_ci	case AUDIT_MQ_OPEN:
13148c2ecf20Sopenharmony_ci		audit_log_format(ab,
13158c2ecf20Sopenharmony_ci			"oflag=0x%x mode=%#ho mq_flags=0x%lx mq_maxmsg=%ld "
13168c2ecf20Sopenharmony_ci			"mq_msgsize=%ld mq_curmsgs=%ld",
13178c2ecf20Sopenharmony_ci			context->mq_open.oflag, context->mq_open.mode,
13188c2ecf20Sopenharmony_ci			context->mq_open.attr.mq_flags,
13198c2ecf20Sopenharmony_ci			context->mq_open.attr.mq_maxmsg,
13208c2ecf20Sopenharmony_ci			context->mq_open.attr.mq_msgsize,
13218c2ecf20Sopenharmony_ci			context->mq_open.attr.mq_curmsgs);
13228c2ecf20Sopenharmony_ci		break;
13238c2ecf20Sopenharmony_ci	case AUDIT_MQ_SENDRECV:
13248c2ecf20Sopenharmony_ci		audit_log_format(ab,
13258c2ecf20Sopenharmony_ci			"mqdes=%d msg_len=%zd msg_prio=%u "
13268c2ecf20Sopenharmony_ci			"abs_timeout_sec=%lld abs_timeout_nsec=%ld",
13278c2ecf20Sopenharmony_ci			context->mq_sendrecv.mqdes,
13288c2ecf20Sopenharmony_ci			context->mq_sendrecv.msg_len,
13298c2ecf20Sopenharmony_ci			context->mq_sendrecv.msg_prio,
13308c2ecf20Sopenharmony_ci			(long long) context->mq_sendrecv.abs_timeout.tv_sec,
13318c2ecf20Sopenharmony_ci			context->mq_sendrecv.abs_timeout.tv_nsec);
13328c2ecf20Sopenharmony_ci		break;
13338c2ecf20Sopenharmony_ci	case AUDIT_MQ_NOTIFY:
13348c2ecf20Sopenharmony_ci		audit_log_format(ab, "mqdes=%d sigev_signo=%d",
13358c2ecf20Sopenharmony_ci				context->mq_notify.mqdes,
13368c2ecf20Sopenharmony_ci				context->mq_notify.sigev_signo);
13378c2ecf20Sopenharmony_ci		break;
13388c2ecf20Sopenharmony_ci	case AUDIT_MQ_GETSETATTR: {
13398c2ecf20Sopenharmony_ci		struct mq_attr *attr = &context->mq_getsetattr.mqstat;
13408c2ecf20Sopenharmony_ci		audit_log_format(ab,
13418c2ecf20Sopenharmony_ci			"mqdes=%d mq_flags=0x%lx mq_maxmsg=%ld mq_msgsize=%ld "
13428c2ecf20Sopenharmony_ci			"mq_curmsgs=%ld ",
13438c2ecf20Sopenharmony_ci			context->mq_getsetattr.mqdes,
13448c2ecf20Sopenharmony_ci			attr->mq_flags, attr->mq_maxmsg,
13458c2ecf20Sopenharmony_ci			attr->mq_msgsize, attr->mq_curmsgs);
13468c2ecf20Sopenharmony_ci		break; }
13478c2ecf20Sopenharmony_ci	case AUDIT_CAPSET:
13488c2ecf20Sopenharmony_ci		audit_log_format(ab, "pid=%d", context->capset.pid);
13498c2ecf20Sopenharmony_ci		audit_log_cap(ab, "cap_pi", &context->capset.cap.inheritable);
13508c2ecf20Sopenharmony_ci		audit_log_cap(ab, "cap_pp", &context->capset.cap.permitted);
13518c2ecf20Sopenharmony_ci		audit_log_cap(ab, "cap_pe", &context->capset.cap.effective);
13528c2ecf20Sopenharmony_ci		audit_log_cap(ab, "cap_pa", &context->capset.cap.ambient);
13538c2ecf20Sopenharmony_ci		break;
13548c2ecf20Sopenharmony_ci	case AUDIT_MMAP:
13558c2ecf20Sopenharmony_ci		audit_log_format(ab, "fd=%d flags=0x%x", context->mmap.fd,
13568c2ecf20Sopenharmony_ci				 context->mmap.flags);
13578c2ecf20Sopenharmony_ci		break;
13588c2ecf20Sopenharmony_ci	case AUDIT_EXECVE:
13598c2ecf20Sopenharmony_ci		audit_log_execve_info(context, &ab);
13608c2ecf20Sopenharmony_ci		break;
13618c2ecf20Sopenharmony_ci	case AUDIT_KERN_MODULE:
13628c2ecf20Sopenharmony_ci		audit_log_format(ab, "name=");
13638c2ecf20Sopenharmony_ci		if (context->module.name) {
13648c2ecf20Sopenharmony_ci			audit_log_untrustedstring(ab, context->module.name);
13658c2ecf20Sopenharmony_ci		} else
13668c2ecf20Sopenharmony_ci			audit_log_format(ab, "(null)");
13678c2ecf20Sopenharmony_ci
13688c2ecf20Sopenharmony_ci		break;
13698c2ecf20Sopenharmony_ci	case AUDIT_TIME_ADJNTPVAL:
13708c2ecf20Sopenharmony_ci	case AUDIT_TIME_INJOFFSET:
13718c2ecf20Sopenharmony_ci		/* this call deviates from the rest, eating the buffer */
13728c2ecf20Sopenharmony_ci		audit_log_time(context, &ab);
13738c2ecf20Sopenharmony_ci		break;
13748c2ecf20Sopenharmony_ci	}
13758c2ecf20Sopenharmony_ci	audit_log_end(ab);
13768c2ecf20Sopenharmony_ci}
13778c2ecf20Sopenharmony_ci
13788c2ecf20Sopenharmony_cistatic inline int audit_proctitle_rtrim(char *proctitle, int len)
13798c2ecf20Sopenharmony_ci{
13808c2ecf20Sopenharmony_ci	char *end = proctitle + len - 1;
13818c2ecf20Sopenharmony_ci	while (end > proctitle && !isprint(*end))
13828c2ecf20Sopenharmony_ci		end--;
13838c2ecf20Sopenharmony_ci
13848c2ecf20Sopenharmony_ci	/* catch the case where proctitle is only 1 non-print character */
13858c2ecf20Sopenharmony_ci	len = end - proctitle + 1;
13868c2ecf20Sopenharmony_ci	len -= isprint(proctitle[len-1]) == 0;
13878c2ecf20Sopenharmony_ci	return len;
13888c2ecf20Sopenharmony_ci}
13898c2ecf20Sopenharmony_ci
13908c2ecf20Sopenharmony_ci/*
13918c2ecf20Sopenharmony_ci * audit_log_name - produce AUDIT_PATH record from struct audit_names
13928c2ecf20Sopenharmony_ci * @context: audit_context for the task
13938c2ecf20Sopenharmony_ci * @n: audit_names structure with reportable details
13948c2ecf20Sopenharmony_ci * @path: optional path to report instead of audit_names->name
13958c2ecf20Sopenharmony_ci * @record_num: record number to report when handling a list of names
13968c2ecf20Sopenharmony_ci * @call_panic: optional pointer to int that will be updated if secid fails
13978c2ecf20Sopenharmony_ci */
13988c2ecf20Sopenharmony_cistatic void audit_log_name(struct audit_context *context, struct audit_names *n,
13998c2ecf20Sopenharmony_ci		    const struct path *path, int record_num, int *call_panic)
14008c2ecf20Sopenharmony_ci{
14018c2ecf20Sopenharmony_ci	struct audit_buffer *ab;
14028c2ecf20Sopenharmony_ci
14038c2ecf20Sopenharmony_ci	ab = audit_log_start(context, GFP_KERNEL, AUDIT_PATH);
14048c2ecf20Sopenharmony_ci	if (!ab)
14058c2ecf20Sopenharmony_ci		return;
14068c2ecf20Sopenharmony_ci
14078c2ecf20Sopenharmony_ci	audit_log_format(ab, "item=%d", record_num);
14088c2ecf20Sopenharmony_ci
14098c2ecf20Sopenharmony_ci	if (path)
14108c2ecf20Sopenharmony_ci		audit_log_d_path(ab, " name=", path);
14118c2ecf20Sopenharmony_ci	else if (n->name) {
14128c2ecf20Sopenharmony_ci		switch (n->name_len) {
14138c2ecf20Sopenharmony_ci		case AUDIT_NAME_FULL:
14148c2ecf20Sopenharmony_ci			/* log the full path */
14158c2ecf20Sopenharmony_ci			audit_log_format(ab, " name=");
14168c2ecf20Sopenharmony_ci			audit_log_untrustedstring(ab, n->name->name);
14178c2ecf20Sopenharmony_ci			break;
14188c2ecf20Sopenharmony_ci		case 0:
14198c2ecf20Sopenharmony_ci			/* name was specified as a relative path and the
14208c2ecf20Sopenharmony_ci			 * directory component is the cwd
14218c2ecf20Sopenharmony_ci			 */
14228c2ecf20Sopenharmony_ci			audit_log_d_path(ab, " name=", &context->pwd);
14238c2ecf20Sopenharmony_ci			break;
14248c2ecf20Sopenharmony_ci		default:
14258c2ecf20Sopenharmony_ci			/* log the name's directory component */
14268c2ecf20Sopenharmony_ci			audit_log_format(ab, " name=");
14278c2ecf20Sopenharmony_ci			audit_log_n_untrustedstring(ab, n->name->name,
14288c2ecf20Sopenharmony_ci						    n->name_len);
14298c2ecf20Sopenharmony_ci		}
14308c2ecf20Sopenharmony_ci	} else
14318c2ecf20Sopenharmony_ci		audit_log_format(ab, " name=(null)");
14328c2ecf20Sopenharmony_ci
14338c2ecf20Sopenharmony_ci	if (n->ino != AUDIT_INO_UNSET)
14348c2ecf20Sopenharmony_ci		audit_log_format(ab, " inode=%lu dev=%02x:%02x mode=%#ho ouid=%u ogid=%u rdev=%02x:%02x",
14358c2ecf20Sopenharmony_ci				 n->ino,
14368c2ecf20Sopenharmony_ci				 MAJOR(n->dev),
14378c2ecf20Sopenharmony_ci				 MINOR(n->dev),
14388c2ecf20Sopenharmony_ci				 n->mode,
14398c2ecf20Sopenharmony_ci				 from_kuid(&init_user_ns, n->uid),
14408c2ecf20Sopenharmony_ci				 from_kgid(&init_user_ns, n->gid),
14418c2ecf20Sopenharmony_ci				 MAJOR(n->rdev),
14428c2ecf20Sopenharmony_ci				 MINOR(n->rdev));
14438c2ecf20Sopenharmony_ci	if (n->osid != 0) {
14448c2ecf20Sopenharmony_ci		char *ctx = NULL;
14458c2ecf20Sopenharmony_ci		u32 len;
14468c2ecf20Sopenharmony_ci
14478c2ecf20Sopenharmony_ci		if (security_secid_to_secctx(
14488c2ecf20Sopenharmony_ci			n->osid, &ctx, &len)) {
14498c2ecf20Sopenharmony_ci			audit_log_format(ab, " osid=%u", n->osid);
14508c2ecf20Sopenharmony_ci			if (call_panic)
14518c2ecf20Sopenharmony_ci				*call_panic = 2;
14528c2ecf20Sopenharmony_ci		} else {
14538c2ecf20Sopenharmony_ci			audit_log_format(ab, " obj=%s", ctx);
14548c2ecf20Sopenharmony_ci			security_release_secctx(ctx, len);
14558c2ecf20Sopenharmony_ci		}
14568c2ecf20Sopenharmony_ci	}
14578c2ecf20Sopenharmony_ci
14588c2ecf20Sopenharmony_ci	/* log the audit_names record type */
14598c2ecf20Sopenharmony_ci	switch (n->type) {
14608c2ecf20Sopenharmony_ci	case AUDIT_TYPE_NORMAL:
14618c2ecf20Sopenharmony_ci		audit_log_format(ab, " nametype=NORMAL");
14628c2ecf20Sopenharmony_ci		break;
14638c2ecf20Sopenharmony_ci	case AUDIT_TYPE_PARENT:
14648c2ecf20Sopenharmony_ci		audit_log_format(ab, " nametype=PARENT");
14658c2ecf20Sopenharmony_ci		break;
14668c2ecf20Sopenharmony_ci	case AUDIT_TYPE_CHILD_DELETE:
14678c2ecf20Sopenharmony_ci		audit_log_format(ab, " nametype=DELETE");
14688c2ecf20Sopenharmony_ci		break;
14698c2ecf20Sopenharmony_ci	case AUDIT_TYPE_CHILD_CREATE:
14708c2ecf20Sopenharmony_ci		audit_log_format(ab, " nametype=CREATE");
14718c2ecf20Sopenharmony_ci		break;
14728c2ecf20Sopenharmony_ci	default:
14738c2ecf20Sopenharmony_ci		audit_log_format(ab, " nametype=UNKNOWN");
14748c2ecf20Sopenharmony_ci		break;
14758c2ecf20Sopenharmony_ci	}
14768c2ecf20Sopenharmony_ci
14778c2ecf20Sopenharmony_ci	audit_log_fcaps(ab, n);
14788c2ecf20Sopenharmony_ci	audit_log_end(ab);
14798c2ecf20Sopenharmony_ci}
14808c2ecf20Sopenharmony_ci
14818c2ecf20Sopenharmony_cistatic void audit_log_proctitle(void)
14828c2ecf20Sopenharmony_ci{
14838c2ecf20Sopenharmony_ci	int res;
14848c2ecf20Sopenharmony_ci	char *buf;
14858c2ecf20Sopenharmony_ci	char *msg = "(null)";
14868c2ecf20Sopenharmony_ci	int len = strlen(msg);
14878c2ecf20Sopenharmony_ci	struct audit_context *context = audit_context();
14888c2ecf20Sopenharmony_ci	struct audit_buffer *ab;
14898c2ecf20Sopenharmony_ci
14908c2ecf20Sopenharmony_ci	if (!context || context->dummy)
14918c2ecf20Sopenharmony_ci		return;
14928c2ecf20Sopenharmony_ci
14938c2ecf20Sopenharmony_ci	ab = audit_log_start(context, GFP_KERNEL, AUDIT_PROCTITLE);
14948c2ecf20Sopenharmony_ci	if (!ab)
14958c2ecf20Sopenharmony_ci		return;	/* audit_panic or being filtered */
14968c2ecf20Sopenharmony_ci
14978c2ecf20Sopenharmony_ci	audit_log_format(ab, "proctitle=");
14988c2ecf20Sopenharmony_ci
14998c2ecf20Sopenharmony_ci	/* Not  cached */
15008c2ecf20Sopenharmony_ci	if (!context->proctitle.value) {
15018c2ecf20Sopenharmony_ci		buf = kmalloc(MAX_PROCTITLE_AUDIT_LEN, GFP_KERNEL);
15028c2ecf20Sopenharmony_ci		if (!buf)
15038c2ecf20Sopenharmony_ci			goto out;
15048c2ecf20Sopenharmony_ci		/* Historically called this from procfs naming */
15058c2ecf20Sopenharmony_ci		res = get_cmdline(current, buf, MAX_PROCTITLE_AUDIT_LEN);
15068c2ecf20Sopenharmony_ci		if (res == 0) {
15078c2ecf20Sopenharmony_ci			kfree(buf);
15088c2ecf20Sopenharmony_ci			goto out;
15098c2ecf20Sopenharmony_ci		}
15108c2ecf20Sopenharmony_ci		res = audit_proctitle_rtrim(buf, res);
15118c2ecf20Sopenharmony_ci		if (res == 0) {
15128c2ecf20Sopenharmony_ci			kfree(buf);
15138c2ecf20Sopenharmony_ci			goto out;
15148c2ecf20Sopenharmony_ci		}
15158c2ecf20Sopenharmony_ci		context->proctitle.value = buf;
15168c2ecf20Sopenharmony_ci		context->proctitle.len = res;
15178c2ecf20Sopenharmony_ci	}
15188c2ecf20Sopenharmony_ci	msg = context->proctitle.value;
15198c2ecf20Sopenharmony_ci	len = context->proctitle.len;
15208c2ecf20Sopenharmony_ciout:
15218c2ecf20Sopenharmony_ci	audit_log_n_untrustedstring(ab, msg, len);
15228c2ecf20Sopenharmony_ci	audit_log_end(ab);
15238c2ecf20Sopenharmony_ci}
15248c2ecf20Sopenharmony_ci
15258c2ecf20Sopenharmony_cistatic void audit_log_exit(void)
15268c2ecf20Sopenharmony_ci{
15278c2ecf20Sopenharmony_ci	int i, call_panic = 0;
15288c2ecf20Sopenharmony_ci	struct audit_context *context = audit_context();
15298c2ecf20Sopenharmony_ci	struct audit_buffer *ab;
15308c2ecf20Sopenharmony_ci	struct audit_aux_data *aux;
15318c2ecf20Sopenharmony_ci	struct audit_names *n;
15328c2ecf20Sopenharmony_ci
15338c2ecf20Sopenharmony_ci	context->personality = current->personality;
15348c2ecf20Sopenharmony_ci
15358c2ecf20Sopenharmony_ci	ab = audit_log_start(context, GFP_KERNEL, AUDIT_SYSCALL);
15368c2ecf20Sopenharmony_ci	if (!ab)
15378c2ecf20Sopenharmony_ci		return;		/* audit_panic has been called */
15388c2ecf20Sopenharmony_ci	audit_log_format(ab, "arch=%x syscall=%d",
15398c2ecf20Sopenharmony_ci			 context->arch, context->major);
15408c2ecf20Sopenharmony_ci	if (context->personality != PER_LINUX)
15418c2ecf20Sopenharmony_ci		audit_log_format(ab, " per=%lx", context->personality);
15428c2ecf20Sopenharmony_ci	if (context->return_valid)
15438c2ecf20Sopenharmony_ci		audit_log_format(ab, " success=%s exit=%ld",
15448c2ecf20Sopenharmony_ci				 (context->return_valid==AUDITSC_SUCCESS)?"yes":"no",
15458c2ecf20Sopenharmony_ci				 context->return_code);
15468c2ecf20Sopenharmony_ci
15478c2ecf20Sopenharmony_ci	audit_log_format(ab,
15488c2ecf20Sopenharmony_ci			 " a0=%lx a1=%lx a2=%lx a3=%lx items=%d",
15498c2ecf20Sopenharmony_ci			 context->argv[0],
15508c2ecf20Sopenharmony_ci			 context->argv[1],
15518c2ecf20Sopenharmony_ci			 context->argv[2],
15528c2ecf20Sopenharmony_ci			 context->argv[3],
15538c2ecf20Sopenharmony_ci			 context->name_count);
15548c2ecf20Sopenharmony_ci
15558c2ecf20Sopenharmony_ci	audit_log_task_info(ab);
15568c2ecf20Sopenharmony_ci	audit_log_key(ab, context->filterkey);
15578c2ecf20Sopenharmony_ci	audit_log_end(ab);
15588c2ecf20Sopenharmony_ci
15598c2ecf20Sopenharmony_ci	for (aux = context->aux; aux; aux = aux->next) {
15608c2ecf20Sopenharmony_ci
15618c2ecf20Sopenharmony_ci		ab = audit_log_start(context, GFP_KERNEL, aux->type);
15628c2ecf20Sopenharmony_ci		if (!ab)
15638c2ecf20Sopenharmony_ci			continue; /* audit_panic has been called */
15648c2ecf20Sopenharmony_ci
15658c2ecf20Sopenharmony_ci		switch (aux->type) {
15668c2ecf20Sopenharmony_ci
15678c2ecf20Sopenharmony_ci		case AUDIT_BPRM_FCAPS: {
15688c2ecf20Sopenharmony_ci			struct audit_aux_data_bprm_fcaps *axs = (void *)aux;
15698c2ecf20Sopenharmony_ci			audit_log_format(ab, "fver=%x", axs->fcap_ver);
15708c2ecf20Sopenharmony_ci			audit_log_cap(ab, "fp", &axs->fcap.permitted);
15718c2ecf20Sopenharmony_ci			audit_log_cap(ab, "fi", &axs->fcap.inheritable);
15728c2ecf20Sopenharmony_ci			audit_log_format(ab, " fe=%d", axs->fcap.fE);
15738c2ecf20Sopenharmony_ci			audit_log_cap(ab, "old_pp", &axs->old_pcap.permitted);
15748c2ecf20Sopenharmony_ci			audit_log_cap(ab, "old_pi", &axs->old_pcap.inheritable);
15758c2ecf20Sopenharmony_ci			audit_log_cap(ab, "old_pe", &axs->old_pcap.effective);
15768c2ecf20Sopenharmony_ci			audit_log_cap(ab, "old_pa", &axs->old_pcap.ambient);
15778c2ecf20Sopenharmony_ci			audit_log_cap(ab, "pp", &axs->new_pcap.permitted);
15788c2ecf20Sopenharmony_ci			audit_log_cap(ab, "pi", &axs->new_pcap.inheritable);
15798c2ecf20Sopenharmony_ci			audit_log_cap(ab, "pe", &axs->new_pcap.effective);
15808c2ecf20Sopenharmony_ci			audit_log_cap(ab, "pa", &axs->new_pcap.ambient);
15818c2ecf20Sopenharmony_ci			audit_log_format(ab, " frootid=%d",
15828c2ecf20Sopenharmony_ci					 from_kuid(&init_user_ns,
15838c2ecf20Sopenharmony_ci						   axs->fcap.rootid));
15848c2ecf20Sopenharmony_ci			break; }
15858c2ecf20Sopenharmony_ci
15868c2ecf20Sopenharmony_ci		}
15878c2ecf20Sopenharmony_ci		audit_log_end(ab);
15888c2ecf20Sopenharmony_ci	}
15898c2ecf20Sopenharmony_ci
15908c2ecf20Sopenharmony_ci	if (context->type)
15918c2ecf20Sopenharmony_ci		show_special(context, &call_panic);
15928c2ecf20Sopenharmony_ci
15938c2ecf20Sopenharmony_ci	if (context->fds[0] >= 0) {
15948c2ecf20Sopenharmony_ci		ab = audit_log_start(context, GFP_KERNEL, AUDIT_FD_PAIR);
15958c2ecf20Sopenharmony_ci		if (ab) {
15968c2ecf20Sopenharmony_ci			audit_log_format(ab, "fd0=%d fd1=%d",
15978c2ecf20Sopenharmony_ci					context->fds[0], context->fds[1]);
15988c2ecf20Sopenharmony_ci			audit_log_end(ab);
15998c2ecf20Sopenharmony_ci		}
16008c2ecf20Sopenharmony_ci	}
16018c2ecf20Sopenharmony_ci
16028c2ecf20Sopenharmony_ci	if (context->sockaddr_len) {
16038c2ecf20Sopenharmony_ci		ab = audit_log_start(context, GFP_KERNEL, AUDIT_SOCKADDR);
16048c2ecf20Sopenharmony_ci		if (ab) {
16058c2ecf20Sopenharmony_ci			audit_log_format(ab, "saddr=");
16068c2ecf20Sopenharmony_ci			audit_log_n_hex(ab, (void *)context->sockaddr,
16078c2ecf20Sopenharmony_ci					context->sockaddr_len);
16088c2ecf20Sopenharmony_ci			audit_log_end(ab);
16098c2ecf20Sopenharmony_ci		}
16108c2ecf20Sopenharmony_ci	}
16118c2ecf20Sopenharmony_ci
16128c2ecf20Sopenharmony_ci	for (aux = context->aux_pids; aux; aux = aux->next) {
16138c2ecf20Sopenharmony_ci		struct audit_aux_data_pids *axs = (void *)aux;
16148c2ecf20Sopenharmony_ci
16158c2ecf20Sopenharmony_ci		for (i = 0; i < axs->pid_count; i++)
16168c2ecf20Sopenharmony_ci			if (audit_log_pid_context(context, axs->target_pid[i],
16178c2ecf20Sopenharmony_ci						  axs->target_auid[i],
16188c2ecf20Sopenharmony_ci						  axs->target_uid[i],
16198c2ecf20Sopenharmony_ci						  axs->target_sessionid[i],
16208c2ecf20Sopenharmony_ci						  axs->target_sid[i],
16218c2ecf20Sopenharmony_ci						  axs->target_comm[i]))
16228c2ecf20Sopenharmony_ci				call_panic = 1;
16238c2ecf20Sopenharmony_ci	}
16248c2ecf20Sopenharmony_ci
16258c2ecf20Sopenharmony_ci	if (context->target_pid &&
16268c2ecf20Sopenharmony_ci	    audit_log_pid_context(context, context->target_pid,
16278c2ecf20Sopenharmony_ci				  context->target_auid, context->target_uid,
16288c2ecf20Sopenharmony_ci				  context->target_sessionid,
16298c2ecf20Sopenharmony_ci				  context->target_sid, context->target_comm))
16308c2ecf20Sopenharmony_ci			call_panic = 1;
16318c2ecf20Sopenharmony_ci
16328c2ecf20Sopenharmony_ci	if (context->pwd.dentry && context->pwd.mnt) {
16338c2ecf20Sopenharmony_ci		ab = audit_log_start(context, GFP_KERNEL, AUDIT_CWD);
16348c2ecf20Sopenharmony_ci		if (ab) {
16358c2ecf20Sopenharmony_ci			audit_log_d_path(ab, "cwd=", &context->pwd);
16368c2ecf20Sopenharmony_ci			audit_log_end(ab);
16378c2ecf20Sopenharmony_ci		}
16388c2ecf20Sopenharmony_ci	}
16398c2ecf20Sopenharmony_ci
16408c2ecf20Sopenharmony_ci	i = 0;
16418c2ecf20Sopenharmony_ci	list_for_each_entry(n, &context->names_list, list) {
16428c2ecf20Sopenharmony_ci		if (n->hidden)
16438c2ecf20Sopenharmony_ci			continue;
16448c2ecf20Sopenharmony_ci		audit_log_name(context, n, NULL, i++, &call_panic);
16458c2ecf20Sopenharmony_ci	}
16468c2ecf20Sopenharmony_ci
16478c2ecf20Sopenharmony_ci	audit_log_proctitle();
16488c2ecf20Sopenharmony_ci
16498c2ecf20Sopenharmony_ci	/* Send end of event record to help user space know we are finished */
16508c2ecf20Sopenharmony_ci	ab = audit_log_start(context, GFP_KERNEL, AUDIT_EOE);
16518c2ecf20Sopenharmony_ci	if (ab)
16528c2ecf20Sopenharmony_ci		audit_log_end(ab);
16538c2ecf20Sopenharmony_ci	if (call_panic)
16548c2ecf20Sopenharmony_ci		audit_panic("error converting sid to string");
16558c2ecf20Sopenharmony_ci}
16568c2ecf20Sopenharmony_ci
16578c2ecf20Sopenharmony_ci/**
16588c2ecf20Sopenharmony_ci * __audit_free - free a per-task audit context
16598c2ecf20Sopenharmony_ci * @tsk: task whose audit context block to free
16608c2ecf20Sopenharmony_ci *
16618c2ecf20Sopenharmony_ci * Called from copy_process and do_exit
16628c2ecf20Sopenharmony_ci */
16638c2ecf20Sopenharmony_civoid __audit_free(struct task_struct *tsk)
16648c2ecf20Sopenharmony_ci{
16658c2ecf20Sopenharmony_ci	struct audit_context *context = tsk->audit_context;
16668c2ecf20Sopenharmony_ci
16678c2ecf20Sopenharmony_ci	if (!context)
16688c2ecf20Sopenharmony_ci		return;
16698c2ecf20Sopenharmony_ci
16708c2ecf20Sopenharmony_ci	if (!list_empty(&context->killed_trees))
16718c2ecf20Sopenharmony_ci		audit_kill_trees(context);
16728c2ecf20Sopenharmony_ci
16738c2ecf20Sopenharmony_ci	/* We are called either by do_exit() or the fork() error handling code;
16748c2ecf20Sopenharmony_ci	 * in the former case tsk == current and in the latter tsk is a
16758c2ecf20Sopenharmony_ci	 * random task_struct that doesn't doesn't have any meaningful data we
16768c2ecf20Sopenharmony_ci	 * need to log via audit_log_exit().
16778c2ecf20Sopenharmony_ci	 */
16788c2ecf20Sopenharmony_ci	if (tsk == current && !context->dummy && context->in_syscall) {
16798c2ecf20Sopenharmony_ci		context->return_valid = 0;
16808c2ecf20Sopenharmony_ci		context->return_code = 0;
16818c2ecf20Sopenharmony_ci
16828c2ecf20Sopenharmony_ci		audit_filter_syscall(tsk, context,
16838c2ecf20Sopenharmony_ci				     &audit_filter_list[AUDIT_FILTER_EXIT]);
16848c2ecf20Sopenharmony_ci		audit_filter_inodes(tsk, context);
16858c2ecf20Sopenharmony_ci		if (context->current_state == AUDIT_RECORD_CONTEXT)
16868c2ecf20Sopenharmony_ci			audit_log_exit();
16878c2ecf20Sopenharmony_ci	}
16888c2ecf20Sopenharmony_ci
16898c2ecf20Sopenharmony_ci	audit_set_context(tsk, NULL);
16908c2ecf20Sopenharmony_ci	audit_free_context(context);
16918c2ecf20Sopenharmony_ci}
16928c2ecf20Sopenharmony_ci
16938c2ecf20Sopenharmony_ci/**
16948c2ecf20Sopenharmony_ci * __audit_syscall_entry - fill in an audit record at syscall entry
16958c2ecf20Sopenharmony_ci * @major: major syscall type (function)
16968c2ecf20Sopenharmony_ci * @a1: additional syscall register 1
16978c2ecf20Sopenharmony_ci * @a2: additional syscall register 2
16988c2ecf20Sopenharmony_ci * @a3: additional syscall register 3
16998c2ecf20Sopenharmony_ci * @a4: additional syscall register 4
17008c2ecf20Sopenharmony_ci *
17018c2ecf20Sopenharmony_ci * Fill in audit context at syscall entry.  This only happens if the
17028c2ecf20Sopenharmony_ci * audit context was created when the task was created and the state or
17038c2ecf20Sopenharmony_ci * filters demand the audit context be built.  If the state from the
17048c2ecf20Sopenharmony_ci * per-task filter or from the per-syscall filter is AUDIT_RECORD_CONTEXT,
17058c2ecf20Sopenharmony_ci * then the record will be written at syscall exit time (otherwise, it
17068c2ecf20Sopenharmony_ci * will only be written if another part of the kernel requests that it
17078c2ecf20Sopenharmony_ci * be written).
17088c2ecf20Sopenharmony_ci */
17098c2ecf20Sopenharmony_civoid __audit_syscall_entry(int major, unsigned long a1, unsigned long a2,
17108c2ecf20Sopenharmony_ci			   unsigned long a3, unsigned long a4)
17118c2ecf20Sopenharmony_ci{
17128c2ecf20Sopenharmony_ci	struct audit_context *context = audit_context();
17138c2ecf20Sopenharmony_ci	enum audit_state     state;
17148c2ecf20Sopenharmony_ci
17158c2ecf20Sopenharmony_ci	if (!audit_enabled || !context)
17168c2ecf20Sopenharmony_ci		return;
17178c2ecf20Sopenharmony_ci
17188c2ecf20Sopenharmony_ci	BUG_ON(context->in_syscall || context->name_count);
17198c2ecf20Sopenharmony_ci
17208c2ecf20Sopenharmony_ci	state = context->state;
17218c2ecf20Sopenharmony_ci	if (state == AUDIT_DISABLED)
17228c2ecf20Sopenharmony_ci		return;
17238c2ecf20Sopenharmony_ci
17248c2ecf20Sopenharmony_ci	context->dummy = !audit_n_rules;
17258c2ecf20Sopenharmony_ci	if (!context->dummy && state == AUDIT_BUILD_CONTEXT) {
17268c2ecf20Sopenharmony_ci		context->prio = 0;
17278c2ecf20Sopenharmony_ci		if (auditd_test_task(current))
17288c2ecf20Sopenharmony_ci			return;
17298c2ecf20Sopenharmony_ci	}
17308c2ecf20Sopenharmony_ci
17318c2ecf20Sopenharmony_ci	context->arch	    = syscall_get_arch(current);
17328c2ecf20Sopenharmony_ci	context->major      = major;
17338c2ecf20Sopenharmony_ci	context->argv[0]    = a1;
17348c2ecf20Sopenharmony_ci	context->argv[1]    = a2;
17358c2ecf20Sopenharmony_ci	context->argv[2]    = a3;
17368c2ecf20Sopenharmony_ci	context->argv[3]    = a4;
17378c2ecf20Sopenharmony_ci	context->serial     = 0;
17388c2ecf20Sopenharmony_ci	context->in_syscall = 1;
17398c2ecf20Sopenharmony_ci	context->current_state  = state;
17408c2ecf20Sopenharmony_ci	context->ppid       = 0;
17418c2ecf20Sopenharmony_ci	ktime_get_coarse_real_ts64(&context->ctime);
17428c2ecf20Sopenharmony_ci}
17438c2ecf20Sopenharmony_ci
17448c2ecf20Sopenharmony_ci/**
17458c2ecf20Sopenharmony_ci * __audit_syscall_exit - deallocate audit context after a system call
17468c2ecf20Sopenharmony_ci * @success: success value of the syscall
17478c2ecf20Sopenharmony_ci * @return_code: return value of the syscall
17488c2ecf20Sopenharmony_ci *
17498c2ecf20Sopenharmony_ci * Tear down after system call.  If the audit context has been marked as
17508c2ecf20Sopenharmony_ci * auditable (either because of the AUDIT_RECORD_CONTEXT state from
17518c2ecf20Sopenharmony_ci * filtering, or because some other part of the kernel wrote an audit
17528c2ecf20Sopenharmony_ci * message), then write out the syscall information.  In call cases,
17538c2ecf20Sopenharmony_ci * free the names stored from getname().
17548c2ecf20Sopenharmony_ci */
17558c2ecf20Sopenharmony_civoid __audit_syscall_exit(int success, long return_code)
17568c2ecf20Sopenharmony_ci{
17578c2ecf20Sopenharmony_ci	struct audit_context *context;
17588c2ecf20Sopenharmony_ci
17598c2ecf20Sopenharmony_ci	context = audit_context();
17608c2ecf20Sopenharmony_ci	if (!context)
17618c2ecf20Sopenharmony_ci		return;
17628c2ecf20Sopenharmony_ci
17638c2ecf20Sopenharmony_ci	if (!list_empty(&context->killed_trees))
17648c2ecf20Sopenharmony_ci		audit_kill_trees(context);
17658c2ecf20Sopenharmony_ci
17668c2ecf20Sopenharmony_ci	if (!context->dummy && context->in_syscall) {
17678c2ecf20Sopenharmony_ci		if (success)
17688c2ecf20Sopenharmony_ci			context->return_valid = AUDITSC_SUCCESS;
17698c2ecf20Sopenharmony_ci		else
17708c2ecf20Sopenharmony_ci			context->return_valid = AUDITSC_FAILURE;
17718c2ecf20Sopenharmony_ci
17728c2ecf20Sopenharmony_ci		/*
17738c2ecf20Sopenharmony_ci		 * we need to fix up the return code in the audit logs if the
17748c2ecf20Sopenharmony_ci		 * actual return codes are later going to be fixed up by the
17758c2ecf20Sopenharmony_ci		 * arch specific signal handlers
17768c2ecf20Sopenharmony_ci		 *
17778c2ecf20Sopenharmony_ci		 * This is actually a test for:
17788c2ecf20Sopenharmony_ci		 * (rc == ERESTARTSYS ) || (rc == ERESTARTNOINTR) ||
17798c2ecf20Sopenharmony_ci		 * (rc == ERESTARTNOHAND) || (rc == ERESTART_RESTARTBLOCK)
17808c2ecf20Sopenharmony_ci		 *
17818c2ecf20Sopenharmony_ci		 * but is faster than a bunch of ||
17828c2ecf20Sopenharmony_ci		 */
17838c2ecf20Sopenharmony_ci		if (unlikely(return_code <= -ERESTARTSYS) &&
17848c2ecf20Sopenharmony_ci		    (return_code >= -ERESTART_RESTARTBLOCK) &&
17858c2ecf20Sopenharmony_ci		    (return_code != -ENOIOCTLCMD))
17868c2ecf20Sopenharmony_ci			context->return_code = -EINTR;
17878c2ecf20Sopenharmony_ci		else
17888c2ecf20Sopenharmony_ci			context->return_code  = return_code;
17898c2ecf20Sopenharmony_ci
17908c2ecf20Sopenharmony_ci		audit_filter_syscall(current, context,
17918c2ecf20Sopenharmony_ci				     &audit_filter_list[AUDIT_FILTER_EXIT]);
17928c2ecf20Sopenharmony_ci		audit_filter_inodes(current, context);
17938c2ecf20Sopenharmony_ci		if (context->current_state == AUDIT_RECORD_CONTEXT)
17948c2ecf20Sopenharmony_ci			audit_log_exit();
17958c2ecf20Sopenharmony_ci	}
17968c2ecf20Sopenharmony_ci
17978c2ecf20Sopenharmony_ci	context->in_syscall = 0;
17988c2ecf20Sopenharmony_ci	context->prio = context->state == AUDIT_RECORD_CONTEXT ? ~0ULL : 0;
17998c2ecf20Sopenharmony_ci
18008c2ecf20Sopenharmony_ci	audit_free_module(context);
18018c2ecf20Sopenharmony_ci	audit_free_names(context);
18028c2ecf20Sopenharmony_ci	unroll_tree_refs(context, NULL, 0);
18038c2ecf20Sopenharmony_ci	audit_free_aux(context);
18048c2ecf20Sopenharmony_ci	context->aux = NULL;
18058c2ecf20Sopenharmony_ci	context->aux_pids = NULL;
18068c2ecf20Sopenharmony_ci	context->target_pid = 0;
18078c2ecf20Sopenharmony_ci	context->target_sid = 0;
18088c2ecf20Sopenharmony_ci	context->sockaddr_len = 0;
18098c2ecf20Sopenharmony_ci	context->type = 0;
18108c2ecf20Sopenharmony_ci	context->fds[0] = -1;
18118c2ecf20Sopenharmony_ci	if (context->state != AUDIT_RECORD_CONTEXT) {
18128c2ecf20Sopenharmony_ci		kfree(context->filterkey);
18138c2ecf20Sopenharmony_ci		context->filterkey = NULL;
18148c2ecf20Sopenharmony_ci	}
18158c2ecf20Sopenharmony_ci}
18168c2ecf20Sopenharmony_ci
18178c2ecf20Sopenharmony_cistatic inline void handle_one(const struct inode *inode)
18188c2ecf20Sopenharmony_ci{
18198c2ecf20Sopenharmony_ci	struct audit_context *context;
18208c2ecf20Sopenharmony_ci	struct audit_tree_refs *p;
18218c2ecf20Sopenharmony_ci	struct audit_chunk *chunk;
18228c2ecf20Sopenharmony_ci	int count;
18238c2ecf20Sopenharmony_ci	if (likely(!inode->i_fsnotify_marks))
18248c2ecf20Sopenharmony_ci		return;
18258c2ecf20Sopenharmony_ci	context = audit_context();
18268c2ecf20Sopenharmony_ci	p = context->trees;
18278c2ecf20Sopenharmony_ci	count = context->tree_count;
18288c2ecf20Sopenharmony_ci	rcu_read_lock();
18298c2ecf20Sopenharmony_ci	chunk = audit_tree_lookup(inode);
18308c2ecf20Sopenharmony_ci	rcu_read_unlock();
18318c2ecf20Sopenharmony_ci	if (!chunk)
18328c2ecf20Sopenharmony_ci		return;
18338c2ecf20Sopenharmony_ci	if (likely(put_tree_ref(context, chunk)))
18348c2ecf20Sopenharmony_ci		return;
18358c2ecf20Sopenharmony_ci	if (unlikely(!grow_tree_refs(context))) {
18368c2ecf20Sopenharmony_ci		pr_warn("out of memory, audit has lost a tree reference\n");
18378c2ecf20Sopenharmony_ci		audit_set_auditable(context);
18388c2ecf20Sopenharmony_ci		audit_put_chunk(chunk);
18398c2ecf20Sopenharmony_ci		unroll_tree_refs(context, p, count);
18408c2ecf20Sopenharmony_ci		return;
18418c2ecf20Sopenharmony_ci	}
18428c2ecf20Sopenharmony_ci	put_tree_ref(context, chunk);
18438c2ecf20Sopenharmony_ci}
18448c2ecf20Sopenharmony_ci
18458c2ecf20Sopenharmony_cistatic void handle_path(const struct dentry *dentry)
18468c2ecf20Sopenharmony_ci{
18478c2ecf20Sopenharmony_ci	struct audit_context *context;
18488c2ecf20Sopenharmony_ci	struct audit_tree_refs *p;
18498c2ecf20Sopenharmony_ci	const struct dentry *d, *parent;
18508c2ecf20Sopenharmony_ci	struct audit_chunk *drop;
18518c2ecf20Sopenharmony_ci	unsigned long seq;
18528c2ecf20Sopenharmony_ci	int count;
18538c2ecf20Sopenharmony_ci
18548c2ecf20Sopenharmony_ci	context = audit_context();
18558c2ecf20Sopenharmony_ci	p = context->trees;
18568c2ecf20Sopenharmony_ci	count = context->tree_count;
18578c2ecf20Sopenharmony_ciretry:
18588c2ecf20Sopenharmony_ci	drop = NULL;
18598c2ecf20Sopenharmony_ci	d = dentry;
18608c2ecf20Sopenharmony_ci	rcu_read_lock();
18618c2ecf20Sopenharmony_ci	seq = read_seqbegin(&rename_lock);
18628c2ecf20Sopenharmony_ci	for(;;) {
18638c2ecf20Sopenharmony_ci		struct inode *inode = d_backing_inode(d);
18648c2ecf20Sopenharmony_ci		if (inode && unlikely(inode->i_fsnotify_marks)) {
18658c2ecf20Sopenharmony_ci			struct audit_chunk *chunk;
18668c2ecf20Sopenharmony_ci			chunk = audit_tree_lookup(inode);
18678c2ecf20Sopenharmony_ci			if (chunk) {
18688c2ecf20Sopenharmony_ci				if (unlikely(!put_tree_ref(context, chunk))) {
18698c2ecf20Sopenharmony_ci					drop = chunk;
18708c2ecf20Sopenharmony_ci					break;
18718c2ecf20Sopenharmony_ci				}
18728c2ecf20Sopenharmony_ci			}
18738c2ecf20Sopenharmony_ci		}
18748c2ecf20Sopenharmony_ci		parent = d->d_parent;
18758c2ecf20Sopenharmony_ci		if (parent == d)
18768c2ecf20Sopenharmony_ci			break;
18778c2ecf20Sopenharmony_ci		d = parent;
18788c2ecf20Sopenharmony_ci	}
18798c2ecf20Sopenharmony_ci	if (unlikely(read_seqretry(&rename_lock, seq) || drop)) {  /* in this order */
18808c2ecf20Sopenharmony_ci		rcu_read_unlock();
18818c2ecf20Sopenharmony_ci		if (!drop) {
18828c2ecf20Sopenharmony_ci			/* just a race with rename */
18838c2ecf20Sopenharmony_ci			unroll_tree_refs(context, p, count);
18848c2ecf20Sopenharmony_ci			goto retry;
18858c2ecf20Sopenharmony_ci		}
18868c2ecf20Sopenharmony_ci		audit_put_chunk(drop);
18878c2ecf20Sopenharmony_ci		if (grow_tree_refs(context)) {
18888c2ecf20Sopenharmony_ci			/* OK, got more space */
18898c2ecf20Sopenharmony_ci			unroll_tree_refs(context, p, count);
18908c2ecf20Sopenharmony_ci			goto retry;
18918c2ecf20Sopenharmony_ci		}
18928c2ecf20Sopenharmony_ci		/* too bad */
18938c2ecf20Sopenharmony_ci		pr_warn("out of memory, audit has lost a tree reference\n");
18948c2ecf20Sopenharmony_ci		unroll_tree_refs(context, p, count);
18958c2ecf20Sopenharmony_ci		audit_set_auditable(context);
18968c2ecf20Sopenharmony_ci		return;
18978c2ecf20Sopenharmony_ci	}
18988c2ecf20Sopenharmony_ci	rcu_read_unlock();
18998c2ecf20Sopenharmony_ci}
19008c2ecf20Sopenharmony_ci
19018c2ecf20Sopenharmony_cistatic struct audit_names *audit_alloc_name(struct audit_context *context,
19028c2ecf20Sopenharmony_ci						unsigned char type)
19038c2ecf20Sopenharmony_ci{
19048c2ecf20Sopenharmony_ci	struct audit_names *aname;
19058c2ecf20Sopenharmony_ci
19068c2ecf20Sopenharmony_ci	if (context->name_count < AUDIT_NAMES) {
19078c2ecf20Sopenharmony_ci		aname = &context->preallocated_names[context->name_count];
19088c2ecf20Sopenharmony_ci		memset(aname, 0, sizeof(*aname));
19098c2ecf20Sopenharmony_ci	} else {
19108c2ecf20Sopenharmony_ci		aname = kzalloc(sizeof(*aname), GFP_NOFS);
19118c2ecf20Sopenharmony_ci		if (!aname)
19128c2ecf20Sopenharmony_ci			return NULL;
19138c2ecf20Sopenharmony_ci		aname->should_free = true;
19148c2ecf20Sopenharmony_ci	}
19158c2ecf20Sopenharmony_ci
19168c2ecf20Sopenharmony_ci	aname->ino = AUDIT_INO_UNSET;
19178c2ecf20Sopenharmony_ci	aname->type = type;
19188c2ecf20Sopenharmony_ci	list_add_tail(&aname->list, &context->names_list);
19198c2ecf20Sopenharmony_ci
19208c2ecf20Sopenharmony_ci	context->name_count++;
19218c2ecf20Sopenharmony_ci	return aname;
19228c2ecf20Sopenharmony_ci}
19238c2ecf20Sopenharmony_ci
19248c2ecf20Sopenharmony_ci/**
19258c2ecf20Sopenharmony_ci * __audit_reusename - fill out filename with info from existing entry
19268c2ecf20Sopenharmony_ci * @uptr: userland ptr to pathname
19278c2ecf20Sopenharmony_ci *
19288c2ecf20Sopenharmony_ci * Search the audit_names list for the current audit context. If there is an
19298c2ecf20Sopenharmony_ci * existing entry with a matching "uptr" then return the filename
19308c2ecf20Sopenharmony_ci * associated with that audit_name. If not, return NULL.
19318c2ecf20Sopenharmony_ci */
19328c2ecf20Sopenharmony_cistruct filename *
19338c2ecf20Sopenharmony_ci__audit_reusename(const __user char *uptr)
19348c2ecf20Sopenharmony_ci{
19358c2ecf20Sopenharmony_ci	struct audit_context *context = audit_context();
19368c2ecf20Sopenharmony_ci	struct audit_names *n;
19378c2ecf20Sopenharmony_ci
19388c2ecf20Sopenharmony_ci	list_for_each_entry(n, &context->names_list, list) {
19398c2ecf20Sopenharmony_ci		if (!n->name)
19408c2ecf20Sopenharmony_ci			continue;
19418c2ecf20Sopenharmony_ci		if (n->name->uptr == uptr) {
19428c2ecf20Sopenharmony_ci			n->name->refcnt++;
19438c2ecf20Sopenharmony_ci			return n->name;
19448c2ecf20Sopenharmony_ci		}
19458c2ecf20Sopenharmony_ci	}
19468c2ecf20Sopenharmony_ci	return NULL;
19478c2ecf20Sopenharmony_ci}
19488c2ecf20Sopenharmony_ci
19498c2ecf20Sopenharmony_ciinline void _audit_getcwd(struct audit_context *context)
19508c2ecf20Sopenharmony_ci{
19518c2ecf20Sopenharmony_ci	if (!context->pwd.dentry)
19528c2ecf20Sopenharmony_ci		get_fs_pwd(current->fs, &context->pwd);
19538c2ecf20Sopenharmony_ci}
19548c2ecf20Sopenharmony_ci
19558c2ecf20Sopenharmony_civoid __audit_getcwd(void)
19568c2ecf20Sopenharmony_ci{
19578c2ecf20Sopenharmony_ci	struct audit_context *context = audit_context();
19588c2ecf20Sopenharmony_ci
19598c2ecf20Sopenharmony_ci	if (context->in_syscall)
19608c2ecf20Sopenharmony_ci		_audit_getcwd(context);
19618c2ecf20Sopenharmony_ci}
19628c2ecf20Sopenharmony_ci
19638c2ecf20Sopenharmony_ci/**
19648c2ecf20Sopenharmony_ci * __audit_getname - add a name to the list
19658c2ecf20Sopenharmony_ci * @name: name to add
19668c2ecf20Sopenharmony_ci *
19678c2ecf20Sopenharmony_ci * Add a name to the list of audit names for this context.
19688c2ecf20Sopenharmony_ci * Called from fs/namei.c:getname().
19698c2ecf20Sopenharmony_ci */
19708c2ecf20Sopenharmony_civoid __audit_getname(struct filename *name)
19718c2ecf20Sopenharmony_ci{
19728c2ecf20Sopenharmony_ci	struct audit_context *context = audit_context();
19738c2ecf20Sopenharmony_ci	struct audit_names *n;
19748c2ecf20Sopenharmony_ci
19758c2ecf20Sopenharmony_ci	if (!context->in_syscall)
19768c2ecf20Sopenharmony_ci		return;
19778c2ecf20Sopenharmony_ci
19788c2ecf20Sopenharmony_ci	n = audit_alloc_name(context, AUDIT_TYPE_UNKNOWN);
19798c2ecf20Sopenharmony_ci	if (!n)
19808c2ecf20Sopenharmony_ci		return;
19818c2ecf20Sopenharmony_ci
19828c2ecf20Sopenharmony_ci	n->name = name;
19838c2ecf20Sopenharmony_ci	n->name_len = AUDIT_NAME_FULL;
19848c2ecf20Sopenharmony_ci	name->aname = n;
19858c2ecf20Sopenharmony_ci	name->refcnt++;
19868c2ecf20Sopenharmony_ci
19878c2ecf20Sopenharmony_ci	_audit_getcwd(context);
19888c2ecf20Sopenharmony_ci}
19898c2ecf20Sopenharmony_ci
19908c2ecf20Sopenharmony_cistatic inline int audit_copy_fcaps(struct audit_names *name,
19918c2ecf20Sopenharmony_ci				   const struct dentry *dentry)
19928c2ecf20Sopenharmony_ci{
19938c2ecf20Sopenharmony_ci	struct cpu_vfs_cap_data caps;
19948c2ecf20Sopenharmony_ci	int rc;
19958c2ecf20Sopenharmony_ci
19968c2ecf20Sopenharmony_ci	if (!dentry)
19978c2ecf20Sopenharmony_ci		return 0;
19988c2ecf20Sopenharmony_ci
19998c2ecf20Sopenharmony_ci	rc = get_vfs_caps_from_disk(dentry, &caps);
20008c2ecf20Sopenharmony_ci	if (rc)
20018c2ecf20Sopenharmony_ci		return rc;
20028c2ecf20Sopenharmony_ci
20038c2ecf20Sopenharmony_ci	name->fcap.permitted = caps.permitted;
20048c2ecf20Sopenharmony_ci	name->fcap.inheritable = caps.inheritable;
20058c2ecf20Sopenharmony_ci	name->fcap.fE = !!(caps.magic_etc & VFS_CAP_FLAGS_EFFECTIVE);
20068c2ecf20Sopenharmony_ci	name->fcap.rootid = caps.rootid;
20078c2ecf20Sopenharmony_ci	name->fcap_ver = (caps.magic_etc & VFS_CAP_REVISION_MASK) >>
20088c2ecf20Sopenharmony_ci				VFS_CAP_REVISION_SHIFT;
20098c2ecf20Sopenharmony_ci
20108c2ecf20Sopenharmony_ci	return 0;
20118c2ecf20Sopenharmony_ci}
20128c2ecf20Sopenharmony_ci
20138c2ecf20Sopenharmony_ci/* Copy inode data into an audit_names. */
20148c2ecf20Sopenharmony_cistatic void audit_copy_inode(struct audit_names *name,
20158c2ecf20Sopenharmony_ci			     const struct dentry *dentry,
20168c2ecf20Sopenharmony_ci			     struct inode *inode, unsigned int flags)
20178c2ecf20Sopenharmony_ci{
20188c2ecf20Sopenharmony_ci	name->ino   = inode->i_ino;
20198c2ecf20Sopenharmony_ci	name->dev   = inode->i_sb->s_dev;
20208c2ecf20Sopenharmony_ci	name->mode  = inode->i_mode;
20218c2ecf20Sopenharmony_ci	name->uid   = inode->i_uid;
20228c2ecf20Sopenharmony_ci	name->gid   = inode->i_gid;
20238c2ecf20Sopenharmony_ci	name->rdev  = inode->i_rdev;
20248c2ecf20Sopenharmony_ci	security_inode_getsecid(inode, &name->osid);
20258c2ecf20Sopenharmony_ci	if (flags & AUDIT_INODE_NOEVAL) {
20268c2ecf20Sopenharmony_ci		name->fcap_ver = -1;
20278c2ecf20Sopenharmony_ci		return;
20288c2ecf20Sopenharmony_ci	}
20298c2ecf20Sopenharmony_ci	audit_copy_fcaps(name, dentry);
20308c2ecf20Sopenharmony_ci}
20318c2ecf20Sopenharmony_ci
20328c2ecf20Sopenharmony_ci/**
20338c2ecf20Sopenharmony_ci * __audit_inode - store the inode and device from a lookup
20348c2ecf20Sopenharmony_ci * @name: name being audited
20358c2ecf20Sopenharmony_ci * @dentry: dentry being audited
20368c2ecf20Sopenharmony_ci * @flags: attributes for this particular entry
20378c2ecf20Sopenharmony_ci */
20388c2ecf20Sopenharmony_civoid __audit_inode(struct filename *name, const struct dentry *dentry,
20398c2ecf20Sopenharmony_ci		   unsigned int flags)
20408c2ecf20Sopenharmony_ci{
20418c2ecf20Sopenharmony_ci	struct audit_context *context = audit_context();
20428c2ecf20Sopenharmony_ci	struct inode *inode = d_backing_inode(dentry);
20438c2ecf20Sopenharmony_ci	struct audit_names *n;
20448c2ecf20Sopenharmony_ci	bool parent = flags & AUDIT_INODE_PARENT;
20458c2ecf20Sopenharmony_ci	struct audit_entry *e;
20468c2ecf20Sopenharmony_ci	struct list_head *list = &audit_filter_list[AUDIT_FILTER_FS];
20478c2ecf20Sopenharmony_ci	int i;
20488c2ecf20Sopenharmony_ci
20498c2ecf20Sopenharmony_ci	if (!context->in_syscall)
20508c2ecf20Sopenharmony_ci		return;
20518c2ecf20Sopenharmony_ci
20528c2ecf20Sopenharmony_ci	rcu_read_lock();
20538c2ecf20Sopenharmony_ci	list_for_each_entry_rcu(e, list, list) {
20548c2ecf20Sopenharmony_ci		for (i = 0; i < e->rule.field_count; i++) {
20558c2ecf20Sopenharmony_ci			struct audit_field *f = &e->rule.fields[i];
20568c2ecf20Sopenharmony_ci
20578c2ecf20Sopenharmony_ci			if (f->type == AUDIT_FSTYPE
20588c2ecf20Sopenharmony_ci			    && audit_comparator(inode->i_sb->s_magic,
20598c2ecf20Sopenharmony_ci						f->op, f->val)
20608c2ecf20Sopenharmony_ci			    && e->rule.action == AUDIT_NEVER) {
20618c2ecf20Sopenharmony_ci				rcu_read_unlock();
20628c2ecf20Sopenharmony_ci				return;
20638c2ecf20Sopenharmony_ci			}
20648c2ecf20Sopenharmony_ci		}
20658c2ecf20Sopenharmony_ci	}
20668c2ecf20Sopenharmony_ci	rcu_read_unlock();
20678c2ecf20Sopenharmony_ci
20688c2ecf20Sopenharmony_ci	if (!name)
20698c2ecf20Sopenharmony_ci		goto out_alloc;
20708c2ecf20Sopenharmony_ci
20718c2ecf20Sopenharmony_ci	/*
20728c2ecf20Sopenharmony_ci	 * If we have a pointer to an audit_names entry already, then we can
20738c2ecf20Sopenharmony_ci	 * just use it directly if the type is correct.
20748c2ecf20Sopenharmony_ci	 */
20758c2ecf20Sopenharmony_ci	n = name->aname;
20768c2ecf20Sopenharmony_ci	if (n) {
20778c2ecf20Sopenharmony_ci		if (parent) {
20788c2ecf20Sopenharmony_ci			if (n->type == AUDIT_TYPE_PARENT ||
20798c2ecf20Sopenharmony_ci			    n->type == AUDIT_TYPE_UNKNOWN)
20808c2ecf20Sopenharmony_ci				goto out;
20818c2ecf20Sopenharmony_ci		} else {
20828c2ecf20Sopenharmony_ci			if (n->type != AUDIT_TYPE_PARENT)
20838c2ecf20Sopenharmony_ci				goto out;
20848c2ecf20Sopenharmony_ci		}
20858c2ecf20Sopenharmony_ci	}
20868c2ecf20Sopenharmony_ci
20878c2ecf20Sopenharmony_ci	list_for_each_entry_reverse(n, &context->names_list, list) {
20888c2ecf20Sopenharmony_ci		if (n->ino) {
20898c2ecf20Sopenharmony_ci			/* valid inode number, use that for the comparison */
20908c2ecf20Sopenharmony_ci			if (n->ino != inode->i_ino ||
20918c2ecf20Sopenharmony_ci			    n->dev != inode->i_sb->s_dev)
20928c2ecf20Sopenharmony_ci				continue;
20938c2ecf20Sopenharmony_ci		} else if (n->name) {
20948c2ecf20Sopenharmony_ci			/* inode number has not been set, check the name */
20958c2ecf20Sopenharmony_ci			if (strcmp(n->name->name, name->name))
20968c2ecf20Sopenharmony_ci				continue;
20978c2ecf20Sopenharmony_ci		} else
20988c2ecf20Sopenharmony_ci			/* no inode and no name (?!) ... this is odd ... */
20998c2ecf20Sopenharmony_ci			continue;
21008c2ecf20Sopenharmony_ci
21018c2ecf20Sopenharmony_ci		/* match the correct record type */
21028c2ecf20Sopenharmony_ci		if (parent) {
21038c2ecf20Sopenharmony_ci			if (n->type == AUDIT_TYPE_PARENT ||
21048c2ecf20Sopenharmony_ci			    n->type == AUDIT_TYPE_UNKNOWN)
21058c2ecf20Sopenharmony_ci				goto out;
21068c2ecf20Sopenharmony_ci		} else {
21078c2ecf20Sopenharmony_ci			if (n->type != AUDIT_TYPE_PARENT)
21088c2ecf20Sopenharmony_ci				goto out;
21098c2ecf20Sopenharmony_ci		}
21108c2ecf20Sopenharmony_ci	}
21118c2ecf20Sopenharmony_ci
21128c2ecf20Sopenharmony_ciout_alloc:
21138c2ecf20Sopenharmony_ci	/* unable to find an entry with both a matching name and type */
21148c2ecf20Sopenharmony_ci	n = audit_alloc_name(context, AUDIT_TYPE_UNKNOWN);
21158c2ecf20Sopenharmony_ci	if (!n)
21168c2ecf20Sopenharmony_ci		return;
21178c2ecf20Sopenharmony_ci	if (name) {
21188c2ecf20Sopenharmony_ci		n->name = name;
21198c2ecf20Sopenharmony_ci		name->refcnt++;
21208c2ecf20Sopenharmony_ci	}
21218c2ecf20Sopenharmony_ci
21228c2ecf20Sopenharmony_ciout:
21238c2ecf20Sopenharmony_ci	if (parent) {
21248c2ecf20Sopenharmony_ci		n->name_len = n->name ? parent_len(n->name->name) : AUDIT_NAME_FULL;
21258c2ecf20Sopenharmony_ci		n->type = AUDIT_TYPE_PARENT;
21268c2ecf20Sopenharmony_ci		if (flags & AUDIT_INODE_HIDDEN)
21278c2ecf20Sopenharmony_ci			n->hidden = true;
21288c2ecf20Sopenharmony_ci	} else {
21298c2ecf20Sopenharmony_ci		n->name_len = AUDIT_NAME_FULL;
21308c2ecf20Sopenharmony_ci		n->type = AUDIT_TYPE_NORMAL;
21318c2ecf20Sopenharmony_ci	}
21328c2ecf20Sopenharmony_ci	handle_path(dentry);
21338c2ecf20Sopenharmony_ci	audit_copy_inode(n, dentry, inode, flags & AUDIT_INODE_NOEVAL);
21348c2ecf20Sopenharmony_ci}
21358c2ecf20Sopenharmony_ci
21368c2ecf20Sopenharmony_civoid __audit_file(const struct file *file)
21378c2ecf20Sopenharmony_ci{
21388c2ecf20Sopenharmony_ci	__audit_inode(NULL, file->f_path.dentry, 0);
21398c2ecf20Sopenharmony_ci}
21408c2ecf20Sopenharmony_ci
21418c2ecf20Sopenharmony_ci/**
21428c2ecf20Sopenharmony_ci * __audit_inode_child - collect inode info for created/removed objects
21438c2ecf20Sopenharmony_ci * @parent: inode of dentry parent
21448c2ecf20Sopenharmony_ci * @dentry: dentry being audited
21458c2ecf20Sopenharmony_ci * @type:   AUDIT_TYPE_* value that we're looking for
21468c2ecf20Sopenharmony_ci *
21478c2ecf20Sopenharmony_ci * For syscalls that create or remove filesystem objects, audit_inode
21488c2ecf20Sopenharmony_ci * can only collect information for the filesystem object's parent.
21498c2ecf20Sopenharmony_ci * This call updates the audit context with the child's information.
21508c2ecf20Sopenharmony_ci * Syscalls that create a new filesystem object must be hooked after
21518c2ecf20Sopenharmony_ci * the object is created.  Syscalls that remove a filesystem object
21528c2ecf20Sopenharmony_ci * must be hooked prior, in order to capture the target inode during
21538c2ecf20Sopenharmony_ci * unsuccessful attempts.
21548c2ecf20Sopenharmony_ci */
21558c2ecf20Sopenharmony_civoid __audit_inode_child(struct inode *parent,
21568c2ecf20Sopenharmony_ci			 const struct dentry *dentry,
21578c2ecf20Sopenharmony_ci			 const unsigned char type)
21588c2ecf20Sopenharmony_ci{
21598c2ecf20Sopenharmony_ci	struct audit_context *context = audit_context();
21608c2ecf20Sopenharmony_ci	struct inode *inode = d_backing_inode(dentry);
21618c2ecf20Sopenharmony_ci	const struct qstr *dname = &dentry->d_name;
21628c2ecf20Sopenharmony_ci	struct audit_names *n, *found_parent = NULL, *found_child = NULL;
21638c2ecf20Sopenharmony_ci	struct audit_entry *e;
21648c2ecf20Sopenharmony_ci	struct list_head *list = &audit_filter_list[AUDIT_FILTER_FS];
21658c2ecf20Sopenharmony_ci	int i;
21668c2ecf20Sopenharmony_ci
21678c2ecf20Sopenharmony_ci	if (!context->in_syscall)
21688c2ecf20Sopenharmony_ci		return;
21698c2ecf20Sopenharmony_ci
21708c2ecf20Sopenharmony_ci	rcu_read_lock();
21718c2ecf20Sopenharmony_ci	list_for_each_entry_rcu(e, list, list) {
21728c2ecf20Sopenharmony_ci		for (i = 0; i < e->rule.field_count; i++) {
21738c2ecf20Sopenharmony_ci			struct audit_field *f = &e->rule.fields[i];
21748c2ecf20Sopenharmony_ci
21758c2ecf20Sopenharmony_ci			if (f->type == AUDIT_FSTYPE
21768c2ecf20Sopenharmony_ci			    && audit_comparator(parent->i_sb->s_magic,
21778c2ecf20Sopenharmony_ci						f->op, f->val)
21788c2ecf20Sopenharmony_ci			    && e->rule.action == AUDIT_NEVER) {
21798c2ecf20Sopenharmony_ci				rcu_read_unlock();
21808c2ecf20Sopenharmony_ci				return;
21818c2ecf20Sopenharmony_ci			}
21828c2ecf20Sopenharmony_ci		}
21838c2ecf20Sopenharmony_ci	}
21848c2ecf20Sopenharmony_ci	rcu_read_unlock();
21858c2ecf20Sopenharmony_ci
21868c2ecf20Sopenharmony_ci	if (inode)
21878c2ecf20Sopenharmony_ci		handle_one(inode);
21888c2ecf20Sopenharmony_ci
21898c2ecf20Sopenharmony_ci	/* look for a parent entry first */
21908c2ecf20Sopenharmony_ci	list_for_each_entry(n, &context->names_list, list) {
21918c2ecf20Sopenharmony_ci		if (!n->name ||
21928c2ecf20Sopenharmony_ci		    (n->type != AUDIT_TYPE_PARENT &&
21938c2ecf20Sopenharmony_ci		     n->type != AUDIT_TYPE_UNKNOWN))
21948c2ecf20Sopenharmony_ci			continue;
21958c2ecf20Sopenharmony_ci
21968c2ecf20Sopenharmony_ci		if (n->ino == parent->i_ino && n->dev == parent->i_sb->s_dev &&
21978c2ecf20Sopenharmony_ci		    !audit_compare_dname_path(dname,
21988c2ecf20Sopenharmony_ci					      n->name->name, n->name_len)) {
21998c2ecf20Sopenharmony_ci			if (n->type == AUDIT_TYPE_UNKNOWN)
22008c2ecf20Sopenharmony_ci				n->type = AUDIT_TYPE_PARENT;
22018c2ecf20Sopenharmony_ci			found_parent = n;
22028c2ecf20Sopenharmony_ci			break;
22038c2ecf20Sopenharmony_ci		}
22048c2ecf20Sopenharmony_ci	}
22058c2ecf20Sopenharmony_ci
22068c2ecf20Sopenharmony_ci	cond_resched();
22078c2ecf20Sopenharmony_ci
22088c2ecf20Sopenharmony_ci	/* is there a matching child entry? */
22098c2ecf20Sopenharmony_ci	list_for_each_entry(n, &context->names_list, list) {
22108c2ecf20Sopenharmony_ci		/* can only match entries that have a name */
22118c2ecf20Sopenharmony_ci		if (!n->name ||
22128c2ecf20Sopenharmony_ci		    (n->type != type && n->type != AUDIT_TYPE_UNKNOWN))
22138c2ecf20Sopenharmony_ci			continue;
22148c2ecf20Sopenharmony_ci
22158c2ecf20Sopenharmony_ci		if (!strcmp(dname->name, n->name->name) ||
22168c2ecf20Sopenharmony_ci		    !audit_compare_dname_path(dname, n->name->name,
22178c2ecf20Sopenharmony_ci						found_parent ?
22188c2ecf20Sopenharmony_ci						found_parent->name_len :
22198c2ecf20Sopenharmony_ci						AUDIT_NAME_FULL)) {
22208c2ecf20Sopenharmony_ci			if (n->type == AUDIT_TYPE_UNKNOWN)
22218c2ecf20Sopenharmony_ci				n->type = type;
22228c2ecf20Sopenharmony_ci			found_child = n;
22238c2ecf20Sopenharmony_ci			break;
22248c2ecf20Sopenharmony_ci		}
22258c2ecf20Sopenharmony_ci	}
22268c2ecf20Sopenharmony_ci
22278c2ecf20Sopenharmony_ci	if (!found_parent) {
22288c2ecf20Sopenharmony_ci		/* create a new, "anonymous" parent record */
22298c2ecf20Sopenharmony_ci		n = audit_alloc_name(context, AUDIT_TYPE_PARENT);
22308c2ecf20Sopenharmony_ci		if (!n)
22318c2ecf20Sopenharmony_ci			return;
22328c2ecf20Sopenharmony_ci		audit_copy_inode(n, NULL, parent, 0);
22338c2ecf20Sopenharmony_ci	}
22348c2ecf20Sopenharmony_ci
22358c2ecf20Sopenharmony_ci	if (!found_child) {
22368c2ecf20Sopenharmony_ci		found_child = audit_alloc_name(context, type);
22378c2ecf20Sopenharmony_ci		if (!found_child)
22388c2ecf20Sopenharmony_ci			return;
22398c2ecf20Sopenharmony_ci
22408c2ecf20Sopenharmony_ci		/* Re-use the name belonging to the slot for a matching parent
22418c2ecf20Sopenharmony_ci		 * directory. All names for this context are relinquished in
22428c2ecf20Sopenharmony_ci		 * audit_free_names() */
22438c2ecf20Sopenharmony_ci		if (found_parent) {
22448c2ecf20Sopenharmony_ci			found_child->name = found_parent->name;
22458c2ecf20Sopenharmony_ci			found_child->name_len = AUDIT_NAME_FULL;
22468c2ecf20Sopenharmony_ci			found_child->name->refcnt++;
22478c2ecf20Sopenharmony_ci		}
22488c2ecf20Sopenharmony_ci	}
22498c2ecf20Sopenharmony_ci
22508c2ecf20Sopenharmony_ci	if (inode)
22518c2ecf20Sopenharmony_ci		audit_copy_inode(found_child, dentry, inode, 0);
22528c2ecf20Sopenharmony_ci	else
22538c2ecf20Sopenharmony_ci		found_child->ino = AUDIT_INO_UNSET;
22548c2ecf20Sopenharmony_ci}
22558c2ecf20Sopenharmony_ciEXPORT_SYMBOL_GPL(__audit_inode_child);
22568c2ecf20Sopenharmony_ci
22578c2ecf20Sopenharmony_ci/**
22588c2ecf20Sopenharmony_ci * auditsc_get_stamp - get local copies of audit_context values
22598c2ecf20Sopenharmony_ci * @ctx: audit_context for the task
22608c2ecf20Sopenharmony_ci * @t: timespec64 to store time recorded in the audit_context
22618c2ecf20Sopenharmony_ci * @serial: serial value that is recorded in the audit_context
22628c2ecf20Sopenharmony_ci *
22638c2ecf20Sopenharmony_ci * Also sets the context as auditable.
22648c2ecf20Sopenharmony_ci */
22658c2ecf20Sopenharmony_ciint auditsc_get_stamp(struct audit_context *ctx,
22668c2ecf20Sopenharmony_ci		       struct timespec64 *t, unsigned int *serial)
22678c2ecf20Sopenharmony_ci{
22688c2ecf20Sopenharmony_ci	if (!ctx->in_syscall)
22698c2ecf20Sopenharmony_ci		return 0;
22708c2ecf20Sopenharmony_ci	if (!ctx->serial)
22718c2ecf20Sopenharmony_ci		ctx->serial = audit_serial();
22728c2ecf20Sopenharmony_ci	t->tv_sec  = ctx->ctime.tv_sec;
22738c2ecf20Sopenharmony_ci	t->tv_nsec = ctx->ctime.tv_nsec;
22748c2ecf20Sopenharmony_ci	*serial    = ctx->serial;
22758c2ecf20Sopenharmony_ci	if (!ctx->prio) {
22768c2ecf20Sopenharmony_ci		ctx->prio = 1;
22778c2ecf20Sopenharmony_ci		ctx->current_state = AUDIT_RECORD_CONTEXT;
22788c2ecf20Sopenharmony_ci	}
22798c2ecf20Sopenharmony_ci	return 1;
22808c2ecf20Sopenharmony_ci}
22818c2ecf20Sopenharmony_ci
22828c2ecf20Sopenharmony_ci/**
22838c2ecf20Sopenharmony_ci * __audit_mq_open - record audit data for a POSIX MQ open
22848c2ecf20Sopenharmony_ci * @oflag: open flag
22858c2ecf20Sopenharmony_ci * @mode: mode bits
22868c2ecf20Sopenharmony_ci * @attr: queue attributes
22878c2ecf20Sopenharmony_ci *
22888c2ecf20Sopenharmony_ci */
22898c2ecf20Sopenharmony_civoid __audit_mq_open(int oflag, umode_t mode, struct mq_attr *attr)
22908c2ecf20Sopenharmony_ci{
22918c2ecf20Sopenharmony_ci	struct audit_context *context = audit_context();
22928c2ecf20Sopenharmony_ci
22938c2ecf20Sopenharmony_ci	if (attr)
22948c2ecf20Sopenharmony_ci		memcpy(&context->mq_open.attr, attr, sizeof(struct mq_attr));
22958c2ecf20Sopenharmony_ci	else
22968c2ecf20Sopenharmony_ci		memset(&context->mq_open.attr, 0, sizeof(struct mq_attr));
22978c2ecf20Sopenharmony_ci
22988c2ecf20Sopenharmony_ci	context->mq_open.oflag = oflag;
22998c2ecf20Sopenharmony_ci	context->mq_open.mode = mode;
23008c2ecf20Sopenharmony_ci
23018c2ecf20Sopenharmony_ci	context->type = AUDIT_MQ_OPEN;
23028c2ecf20Sopenharmony_ci}
23038c2ecf20Sopenharmony_ci
23048c2ecf20Sopenharmony_ci/**
23058c2ecf20Sopenharmony_ci * __audit_mq_sendrecv - record audit data for a POSIX MQ timed send/receive
23068c2ecf20Sopenharmony_ci * @mqdes: MQ descriptor
23078c2ecf20Sopenharmony_ci * @msg_len: Message length
23088c2ecf20Sopenharmony_ci * @msg_prio: Message priority
23098c2ecf20Sopenharmony_ci * @abs_timeout: Message timeout in absolute time
23108c2ecf20Sopenharmony_ci *
23118c2ecf20Sopenharmony_ci */
23128c2ecf20Sopenharmony_civoid __audit_mq_sendrecv(mqd_t mqdes, size_t msg_len, unsigned int msg_prio,
23138c2ecf20Sopenharmony_ci			const struct timespec64 *abs_timeout)
23148c2ecf20Sopenharmony_ci{
23158c2ecf20Sopenharmony_ci	struct audit_context *context = audit_context();
23168c2ecf20Sopenharmony_ci	struct timespec64 *p = &context->mq_sendrecv.abs_timeout;
23178c2ecf20Sopenharmony_ci
23188c2ecf20Sopenharmony_ci	if (abs_timeout)
23198c2ecf20Sopenharmony_ci		memcpy(p, abs_timeout, sizeof(*p));
23208c2ecf20Sopenharmony_ci	else
23218c2ecf20Sopenharmony_ci		memset(p, 0, sizeof(*p));
23228c2ecf20Sopenharmony_ci
23238c2ecf20Sopenharmony_ci	context->mq_sendrecv.mqdes = mqdes;
23248c2ecf20Sopenharmony_ci	context->mq_sendrecv.msg_len = msg_len;
23258c2ecf20Sopenharmony_ci	context->mq_sendrecv.msg_prio = msg_prio;
23268c2ecf20Sopenharmony_ci
23278c2ecf20Sopenharmony_ci	context->type = AUDIT_MQ_SENDRECV;
23288c2ecf20Sopenharmony_ci}
23298c2ecf20Sopenharmony_ci
23308c2ecf20Sopenharmony_ci/**
23318c2ecf20Sopenharmony_ci * __audit_mq_notify - record audit data for a POSIX MQ notify
23328c2ecf20Sopenharmony_ci * @mqdes: MQ descriptor
23338c2ecf20Sopenharmony_ci * @notification: Notification event
23348c2ecf20Sopenharmony_ci *
23358c2ecf20Sopenharmony_ci */
23368c2ecf20Sopenharmony_ci
23378c2ecf20Sopenharmony_civoid __audit_mq_notify(mqd_t mqdes, const struct sigevent *notification)
23388c2ecf20Sopenharmony_ci{
23398c2ecf20Sopenharmony_ci	struct audit_context *context = audit_context();
23408c2ecf20Sopenharmony_ci
23418c2ecf20Sopenharmony_ci	if (notification)
23428c2ecf20Sopenharmony_ci		context->mq_notify.sigev_signo = notification->sigev_signo;
23438c2ecf20Sopenharmony_ci	else
23448c2ecf20Sopenharmony_ci		context->mq_notify.sigev_signo = 0;
23458c2ecf20Sopenharmony_ci
23468c2ecf20Sopenharmony_ci	context->mq_notify.mqdes = mqdes;
23478c2ecf20Sopenharmony_ci	context->type = AUDIT_MQ_NOTIFY;
23488c2ecf20Sopenharmony_ci}
23498c2ecf20Sopenharmony_ci
23508c2ecf20Sopenharmony_ci/**
23518c2ecf20Sopenharmony_ci * __audit_mq_getsetattr - record audit data for a POSIX MQ get/set attribute
23528c2ecf20Sopenharmony_ci * @mqdes: MQ descriptor
23538c2ecf20Sopenharmony_ci * @mqstat: MQ flags
23548c2ecf20Sopenharmony_ci *
23558c2ecf20Sopenharmony_ci */
23568c2ecf20Sopenharmony_civoid __audit_mq_getsetattr(mqd_t mqdes, struct mq_attr *mqstat)
23578c2ecf20Sopenharmony_ci{
23588c2ecf20Sopenharmony_ci	struct audit_context *context = audit_context();
23598c2ecf20Sopenharmony_ci	context->mq_getsetattr.mqdes = mqdes;
23608c2ecf20Sopenharmony_ci	context->mq_getsetattr.mqstat = *mqstat;
23618c2ecf20Sopenharmony_ci	context->type = AUDIT_MQ_GETSETATTR;
23628c2ecf20Sopenharmony_ci}
23638c2ecf20Sopenharmony_ci
23648c2ecf20Sopenharmony_ci/**
23658c2ecf20Sopenharmony_ci * __audit_ipc_obj - record audit data for ipc object
23668c2ecf20Sopenharmony_ci * @ipcp: ipc permissions
23678c2ecf20Sopenharmony_ci *
23688c2ecf20Sopenharmony_ci */
23698c2ecf20Sopenharmony_civoid __audit_ipc_obj(struct kern_ipc_perm *ipcp)
23708c2ecf20Sopenharmony_ci{
23718c2ecf20Sopenharmony_ci	struct audit_context *context = audit_context();
23728c2ecf20Sopenharmony_ci	context->ipc.uid = ipcp->uid;
23738c2ecf20Sopenharmony_ci	context->ipc.gid = ipcp->gid;
23748c2ecf20Sopenharmony_ci	context->ipc.mode = ipcp->mode;
23758c2ecf20Sopenharmony_ci	context->ipc.has_perm = 0;
23768c2ecf20Sopenharmony_ci	security_ipc_getsecid(ipcp, &context->ipc.osid);
23778c2ecf20Sopenharmony_ci	context->type = AUDIT_IPC;
23788c2ecf20Sopenharmony_ci}
23798c2ecf20Sopenharmony_ci
23808c2ecf20Sopenharmony_ci/**
23818c2ecf20Sopenharmony_ci * __audit_ipc_set_perm - record audit data for new ipc permissions
23828c2ecf20Sopenharmony_ci * @qbytes: msgq bytes
23838c2ecf20Sopenharmony_ci * @uid: msgq user id
23848c2ecf20Sopenharmony_ci * @gid: msgq group id
23858c2ecf20Sopenharmony_ci * @mode: msgq mode (permissions)
23868c2ecf20Sopenharmony_ci *
23878c2ecf20Sopenharmony_ci * Called only after audit_ipc_obj().
23888c2ecf20Sopenharmony_ci */
23898c2ecf20Sopenharmony_civoid __audit_ipc_set_perm(unsigned long qbytes, uid_t uid, gid_t gid, umode_t mode)
23908c2ecf20Sopenharmony_ci{
23918c2ecf20Sopenharmony_ci	struct audit_context *context = audit_context();
23928c2ecf20Sopenharmony_ci
23938c2ecf20Sopenharmony_ci	context->ipc.qbytes = qbytes;
23948c2ecf20Sopenharmony_ci	context->ipc.perm_uid = uid;
23958c2ecf20Sopenharmony_ci	context->ipc.perm_gid = gid;
23968c2ecf20Sopenharmony_ci	context->ipc.perm_mode = mode;
23978c2ecf20Sopenharmony_ci	context->ipc.has_perm = 1;
23988c2ecf20Sopenharmony_ci}
23998c2ecf20Sopenharmony_ci
24008c2ecf20Sopenharmony_civoid __audit_bprm(struct linux_binprm *bprm)
24018c2ecf20Sopenharmony_ci{
24028c2ecf20Sopenharmony_ci	struct audit_context *context = audit_context();
24038c2ecf20Sopenharmony_ci
24048c2ecf20Sopenharmony_ci	context->type = AUDIT_EXECVE;
24058c2ecf20Sopenharmony_ci	context->execve.argc = bprm->argc;
24068c2ecf20Sopenharmony_ci}
24078c2ecf20Sopenharmony_ci
24088c2ecf20Sopenharmony_ci
24098c2ecf20Sopenharmony_ci/**
24108c2ecf20Sopenharmony_ci * __audit_socketcall - record audit data for sys_socketcall
24118c2ecf20Sopenharmony_ci * @nargs: number of args, which should not be more than AUDITSC_ARGS.
24128c2ecf20Sopenharmony_ci * @args: args array
24138c2ecf20Sopenharmony_ci *
24148c2ecf20Sopenharmony_ci */
24158c2ecf20Sopenharmony_ciint __audit_socketcall(int nargs, unsigned long *args)
24168c2ecf20Sopenharmony_ci{
24178c2ecf20Sopenharmony_ci	struct audit_context *context = audit_context();
24188c2ecf20Sopenharmony_ci
24198c2ecf20Sopenharmony_ci	if (nargs <= 0 || nargs > AUDITSC_ARGS || !args)
24208c2ecf20Sopenharmony_ci		return -EINVAL;
24218c2ecf20Sopenharmony_ci	context->type = AUDIT_SOCKETCALL;
24228c2ecf20Sopenharmony_ci	context->socketcall.nargs = nargs;
24238c2ecf20Sopenharmony_ci	memcpy(context->socketcall.args, args, nargs * sizeof(unsigned long));
24248c2ecf20Sopenharmony_ci	return 0;
24258c2ecf20Sopenharmony_ci}
24268c2ecf20Sopenharmony_ci
24278c2ecf20Sopenharmony_ci/**
24288c2ecf20Sopenharmony_ci * __audit_fd_pair - record audit data for pipe and socketpair
24298c2ecf20Sopenharmony_ci * @fd1: the first file descriptor
24308c2ecf20Sopenharmony_ci * @fd2: the second file descriptor
24318c2ecf20Sopenharmony_ci *
24328c2ecf20Sopenharmony_ci */
24338c2ecf20Sopenharmony_civoid __audit_fd_pair(int fd1, int fd2)
24348c2ecf20Sopenharmony_ci{
24358c2ecf20Sopenharmony_ci	struct audit_context *context = audit_context();
24368c2ecf20Sopenharmony_ci	context->fds[0] = fd1;
24378c2ecf20Sopenharmony_ci	context->fds[1] = fd2;
24388c2ecf20Sopenharmony_ci}
24398c2ecf20Sopenharmony_ci
24408c2ecf20Sopenharmony_ci/**
24418c2ecf20Sopenharmony_ci * __audit_sockaddr - record audit data for sys_bind, sys_connect, sys_sendto
24428c2ecf20Sopenharmony_ci * @len: data length in user space
24438c2ecf20Sopenharmony_ci * @a: data address in kernel space
24448c2ecf20Sopenharmony_ci *
24458c2ecf20Sopenharmony_ci * Returns 0 for success or NULL context or < 0 on error.
24468c2ecf20Sopenharmony_ci */
24478c2ecf20Sopenharmony_ciint __audit_sockaddr(int len, void *a)
24488c2ecf20Sopenharmony_ci{
24498c2ecf20Sopenharmony_ci	struct audit_context *context = audit_context();
24508c2ecf20Sopenharmony_ci
24518c2ecf20Sopenharmony_ci	if (!context->sockaddr) {
24528c2ecf20Sopenharmony_ci		void *p = kmalloc(sizeof(struct sockaddr_storage), GFP_KERNEL);
24538c2ecf20Sopenharmony_ci		if (!p)
24548c2ecf20Sopenharmony_ci			return -ENOMEM;
24558c2ecf20Sopenharmony_ci		context->sockaddr = p;
24568c2ecf20Sopenharmony_ci	}
24578c2ecf20Sopenharmony_ci
24588c2ecf20Sopenharmony_ci	context->sockaddr_len = len;
24598c2ecf20Sopenharmony_ci	memcpy(context->sockaddr, a, len);
24608c2ecf20Sopenharmony_ci	return 0;
24618c2ecf20Sopenharmony_ci}
24628c2ecf20Sopenharmony_ci
24638c2ecf20Sopenharmony_civoid __audit_ptrace(struct task_struct *t)
24648c2ecf20Sopenharmony_ci{
24658c2ecf20Sopenharmony_ci	struct audit_context *context = audit_context();
24668c2ecf20Sopenharmony_ci
24678c2ecf20Sopenharmony_ci	context->target_pid = task_tgid_nr(t);
24688c2ecf20Sopenharmony_ci	context->target_auid = audit_get_loginuid(t);
24698c2ecf20Sopenharmony_ci	context->target_uid = task_uid(t);
24708c2ecf20Sopenharmony_ci	context->target_sessionid = audit_get_sessionid(t);
24718c2ecf20Sopenharmony_ci	security_task_getsecid(t, &context->target_sid);
24728c2ecf20Sopenharmony_ci	memcpy(context->target_comm, t->comm, TASK_COMM_LEN);
24738c2ecf20Sopenharmony_ci}
24748c2ecf20Sopenharmony_ci
24758c2ecf20Sopenharmony_ci/**
24768c2ecf20Sopenharmony_ci * audit_signal_info_syscall - record signal info for syscalls
24778c2ecf20Sopenharmony_ci * @t: task being signaled
24788c2ecf20Sopenharmony_ci *
24798c2ecf20Sopenharmony_ci * If the audit subsystem is being terminated, record the task (pid)
24808c2ecf20Sopenharmony_ci * and uid that is doing that.
24818c2ecf20Sopenharmony_ci */
24828c2ecf20Sopenharmony_ciint audit_signal_info_syscall(struct task_struct *t)
24838c2ecf20Sopenharmony_ci{
24848c2ecf20Sopenharmony_ci	struct audit_aux_data_pids *axp;
24858c2ecf20Sopenharmony_ci	struct audit_context *ctx = audit_context();
24868c2ecf20Sopenharmony_ci	kuid_t t_uid = task_uid(t);
24878c2ecf20Sopenharmony_ci
24888c2ecf20Sopenharmony_ci	if (!audit_signals || audit_dummy_context())
24898c2ecf20Sopenharmony_ci		return 0;
24908c2ecf20Sopenharmony_ci
24918c2ecf20Sopenharmony_ci	/* optimize the common case by putting first signal recipient directly
24928c2ecf20Sopenharmony_ci	 * in audit_context */
24938c2ecf20Sopenharmony_ci	if (!ctx->target_pid) {
24948c2ecf20Sopenharmony_ci		ctx->target_pid = task_tgid_nr(t);
24958c2ecf20Sopenharmony_ci		ctx->target_auid = audit_get_loginuid(t);
24968c2ecf20Sopenharmony_ci		ctx->target_uid = t_uid;
24978c2ecf20Sopenharmony_ci		ctx->target_sessionid = audit_get_sessionid(t);
24988c2ecf20Sopenharmony_ci		security_task_getsecid(t, &ctx->target_sid);
24998c2ecf20Sopenharmony_ci		memcpy(ctx->target_comm, t->comm, TASK_COMM_LEN);
25008c2ecf20Sopenharmony_ci		return 0;
25018c2ecf20Sopenharmony_ci	}
25028c2ecf20Sopenharmony_ci
25038c2ecf20Sopenharmony_ci	axp = (void *)ctx->aux_pids;
25048c2ecf20Sopenharmony_ci	if (!axp || axp->pid_count == AUDIT_AUX_PIDS) {
25058c2ecf20Sopenharmony_ci		axp = kzalloc(sizeof(*axp), GFP_ATOMIC);
25068c2ecf20Sopenharmony_ci		if (!axp)
25078c2ecf20Sopenharmony_ci			return -ENOMEM;
25088c2ecf20Sopenharmony_ci
25098c2ecf20Sopenharmony_ci		axp->d.type = AUDIT_OBJ_PID;
25108c2ecf20Sopenharmony_ci		axp->d.next = ctx->aux_pids;
25118c2ecf20Sopenharmony_ci		ctx->aux_pids = (void *)axp;
25128c2ecf20Sopenharmony_ci	}
25138c2ecf20Sopenharmony_ci	BUG_ON(axp->pid_count >= AUDIT_AUX_PIDS);
25148c2ecf20Sopenharmony_ci
25158c2ecf20Sopenharmony_ci	axp->target_pid[axp->pid_count] = task_tgid_nr(t);
25168c2ecf20Sopenharmony_ci	axp->target_auid[axp->pid_count] = audit_get_loginuid(t);
25178c2ecf20Sopenharmony_ci	axp->target_uid[axp->pid_count] = t_uid;
25188c2ecf20Sopenharmony_ci	axp->target_sessionid[axp->pid_count] = audit_get_sessionid(t);
25198c2ecf20Sopenharmony_ci	security_task_getsecid(t, &axp->target_sid[axp->pid_count]);
25208c2ecf20Sopenharmony_ci	memcpy(axp->target_comm[axp->pid_count], t->comm, TASK_COMM_LEN);
25218c2ecf20Sopenharmony_ci	axp->pid_count++;
25228c2ecf20Sopenharmony_ci
25238c2ecf20Sopenharmony_ci	return 0;
25248c2ecf20Sopenharmony_ci}
25258c2ecf20Sopenharmony_ci
25268c2ecf20Sopenharmony_ci/**
25278c2ecf20Sopenharmony_ci * __audit_log_bprm_fcaps - store information about a loading bprm and relevant fcaps
25288c2ecf20Sopenharmony_ci * @bprm: pointer to the bprm being processed
25298c2ecf20Sopenharmony_ci * @new: the proposed new credentials
25308c2ecf20Sopenharmony_ci * @old: the old credentials
25318c2ecf20Sopenharmony_ci *
25328c2ecf20Sopenharmony_ci * Simply check if the proc already has the caps given by the file and if not
25338c2ecf20Sopenharmony_ci * store the priv escalation info for later auditing at the end of the syscall
25348c2ecf20Sopenharmony_ci *
25358c2ecf20Sopenharmony_ci * -Eric
25368c2ecf20Sopenharmony_ci */
25378c2ecf20Sopenharmony_ciint __audit_log_bprm_fcaps(struct linux_binprm *bprm,
25388c2ecf20Sopenharmony_ci			   const struct cred *new, const struct cred *old)
25398c2ecf20Sopenharmony_ci{
25408c2ecf20Sopenharmony_ci	struct audit_aux_data_bprm_fcaps *ax;
25418c2ecf20Sopenharmony_ci	struct audit_context *context = audit_context();
25428c2ecf20Sopenharmony_ci	struct cpu_vfs_cap_data vcaps;
25438c2ecf20Sopenharmony_ci
25448c2ecf20Sopenharmony_ci	ax = kmalloc(sizeof(*ax), GFP_KERNEL);
25458c2ecf20Sopenharmony_ci	if (!ax)
25468c2ecf20Sopenharmony_ci		return -ENOMEM;
25478c2ecf20Sopenharmony_ci
25488c2ecf20Sopenharmony_ci	ax->d.type = AUDIT_BPRM_FCAPS;
25498c2ecf20Sopenharmony_ci	ax->d.next = context->aux;
25508c2ecf20Sopenharmony_ci	context->aux = (void *)ax;
25518c2ecf20Sopenharmony_ci
25528c2ecf20Sopenharmony_ci	get_vfs_caps_from_disk(bprm->file->f_path.dentry, &vcaps);
25538c2ecf20Sopenharmony_ci
25548c2ecf20Sopenharmony_ci	ax->fcap.permitted = vcaps.permitted;
25558c2ecf20Sopenharmony_ci	ax->fcap.inheritable = vcaps.inheritable;
25568c2ecf20Sopenharmony_ci	ax->fcap.fE = !!(vcaps.magic_etc & VFS_CAP_FLAGS_EFFECTIVE);
25578c2ecf20Sopenharmony_ci	ax->fcap.rootid = vcaps.rootid;
25588c2ecf20Sopenharmony_ci	ax->fcap_ver = (vcaps.magic_etc & VFS_CAP_REVISION_MASK) >> VFS_CAP_REVISION_SHIFT;
25598c2ecf20Sopenharmony_ci
25608c2ecf20Sopenharmony_ci	ax->old_pcap.permitted   = old->cap_permitted;
25618c2ecf20Sopenharmony_ci	ax->old_pcap.inheritable = old->cap_inheritable;
25628c2ecf20Sopenharmony_ci	ax->old_pcap.effective   = old->cap_effective;
25638c2ecf20Sopenharmony_ci	ax->old_pcap.ambient     = old->cap_ambient;
25648c2ecf20Sopenharmony_ci
25658c2ecf20Sopenharmony_ci	ax->new_pcap.permitted   = new->cap_permitted;
25668c2ecf20Sopenharmony_ci	ax->new_pcap.inheritable = new->cap_inheritable;
25678c2ecf20Sopenharmony_ci	ax->new_pcap.effective   = new->cap_effective;
25688c2ecf20Sopenharmony_ci	ax->new_pcap.ambient     = new->cap_ambient;
25698c2ecf20Sopenharmony_ci	return 0;
25708c2ecf20Sopenharmony_ci}
25718c2ecf20Sopenharmony_ci
25728c2ecf20Sopenharmony_ci/**
25738c2ecf20Sopenharmony_ci * __audit_log_capset - store information about the arguments to the capset syscall
25748c2ecf20Sopenharmony_ci * @new: the new credentials
25758c2ecf20Sopenharmony_ci * @old: the old (current) credentials
25768c2ecf20Sopenharmony_ci *
25778c2ecf20Sopenharmony_ci * Record the arguments userspace sent to sys_capset for later printing by the
25788c2ecf20Sopenharmony_ci * audit system if applicable
25798c2ecf20Sopenharmony_ci */
25808c2ecf20Sopenharmony_civoid __audit_log_capset(const struct cred *new, const struct cred *old)
25818c2ecf20Sopenharmony_ci{
25828c2ecf20Sopenharmony_ci	struct audit_context *context = audit_context();
25838c2ecf20Sopenharmony_ci	context->capset.pid = task_tgid_nr(current);
25848c2ecf20Sopenharmony_ci	context->capset.cap.effective   = new->cap_effective;
25858c2ecf20Sopenharmony_ci	context->capset.cap.inheritable = new->cap_effective;
25868c2ecf20Sopenharmony_ci	context->capset.cap.permitted   = new->cap_permitted;
25878c2ecf20Sopenharmony_ci	context->capset.cap.ambient     = new->cap_ambient;
25888c2ecf20Sopenharmony_ci	context->type = AUDIT_CAPSET;
25898c2ecf20Sopenharmony_ci}
25908c2ecf20Sopenharmony_ci
25918c2ecf20Sopenharmony_civoid __audit_mmap_fd(int fd, int flags)
25928c2ecf20Sopenharmony_ci{
25938c2ecf20Sopenharmony_ci	struct audit_context *context = audit_context();
25948c2ecf20Sopenharmony_ci	context->mmap.fd = fd;
25958c2ecf20Sopenharmony_ci	context->mmap.flags = flags;
25968c2ecf20Sopenharmony_ci	context->type = AUDIT_MMAP;
25978c2ecf20Sopenharmony_ci}
25988c2ecf20Sopenharmony_ci
25998c2ecf20Sopenharmony_civoid __audit_log_kern_module(char *name)
26008c2ecf20Sopenharmony_ci{
26018c2ecf20Sopenharmony_ci	struct audit_context *context = audit_context();
26028c2ecf20Sopenharmony_ci
26038c2ecf20Sopenharmony_ci	context->module.name = kstrdup(name, GFP_KERNEL);
26048c2ecf20Sopenharmony_ci	if (!context->module.name)
26058c2ecf20Sopenharmony_ci		audit_log_lost("out of memory in __audit_log_kern_module");
26068c2ecf20Sopenharmony_ci	context->type = AUDIT_KERN_MODULE;
26078c2ecf20Sopenharmony_ci}
26088c2ecf20Sopenharmony_ci
26098c2ecf20Sopenharmony_civoid __audit_fanotify(unsigned int response)
26108c2ecf20Sopenharmony_ci{
26118c2ecf20Sopenharmony_ci	audit_log(audit_context(), GFP_KERNEL,
26128c2ecf20Sopenharmony_ci		AUDIT_FANOTIFY,	"resp=%u", response);
26138c2ecf20Sopenharmony_ci}
26148c2ecf20Sopenharmony_ci
26158c2ecf20Sopenharmony_civoid __audit_tk_injoffset(struct timespec64 offset)
26168c2ecf20Sopenharmony_ci{
26178c2ecf20Sopenharmony_ci	struct audit_context *context = audit_context();
26188c2ecf20Sopenharmony_ci
26198c2ecf20Sopenharmony_ci	/* only set type if not already set by NTP */
26208c2ecf20Sopenharmony_ci	if (!context->type)
26218c2ecf20Sopenharmony_ci		context->type = AUDIT_TIME_INJOFFSET;
26228c2ecf20Sopenharmony_ci	memcpy(&context->time.tk_injoffset, &offset, sizeof(offset));
26238c2ecf20Sopenharmony_ci}
26248c2ecf20Sopenharmony_ci
26258c2ecf20Sopenharmony_civoid __audit_ntp_log(const struct audit_ntp_data *ad)
26268c2ecf20Sopenharmony_ci{
26278c2ecf20Sopenharmony_ci	struct audit_context *context = audit_context();
26288c2ecf20Sopenharmony_ci	int type;
26298c2ecf20Sopenharmony_ci
26308c2ecf20Sopenharmony_ci	for (type = 0; type < AUDIT_NTP_NVALS; type++)
26318c2ecf20Sopenharmony_ci		if (ad->vals[type].newval != ad->vals[type].oldval) {
26328c2ecf20Sopenharmony_ci			/* unconditionally set type, overwriting TK */
26338c2ecf20Sopenharmony_ci			context->type = AUDIT_TIME_ADJNTPVAL;
26348c2ecf20Sopenharmony_ci			memcpy(&context->time.ntp_data, ad, sizeof(*ad));
26358c2ecf20Sopenharmony_ci			break;
26368c2ecf20Sopenharmony_ci		}
26378c2ecf20Sopenharmony_ci}
26388c2ecf20Sopenharmony_ci
26398c2ecf20Sopenharmony_civoid __audit_log_nfcfg(const char *name, u8 af, unsigned int nentries,
26408c2ecf20Sopenharmony_ci		       enum audit_nfcfgop op, gfp_t gfp)
26418c2ecf20Sopenharmony_ci{
26428c2ecf20Sopenharmony_ci	struct audit_buffer *ab;
26438c2ecf20Sopenharmony_ci	char comm[sizeof(current->comm)];
26448c2ecf20Sopenharmony_ci
26458c2ecf20Sopenharmony_ci	ab = audit_log_start(audit_context(), gfp, AUDIT_NETFILTER_CFG);
26468c2ecf20Sopenharmony_ci	if (!ab)
26478c2ecf20Sopenharmony_ci		return;
26488c2ecf20Sopenharmony_ci	audit_log_format(ab, "table=%s family=%u entries=%u op=%s",
26498c2ecf20Sopenharmony_ci			 name, af, nentries, audit_nfcfgs[op].s);
26508c2ecf20Sopenharmony_ci
26518c2ecf20Sopenharmony_ci	audit_log_format(ab, " pid=%u", task_pid_nr(current));
26528c2ecf20Sopenharmony_ci	audit_log_task_context(ab); /* subj= */
26538c2ecf20Sopenharmony_ci	audit_log_format(ab, " comm=");
26548c2ecf20Sopenharmony_ci	audit_log_untrustedstring(ab, get_task_comm(comm, current));
26558c2ecf20Sopenharmony_ci	audit_log_end(ab);
26568c2ecf20Sopenharmony_ci}
26578c2ecf20Sopenharmony_ciEXPORT_SYMBOL_GPL(__audit_log_nfcfg);
26588c2ecf20Sopenharmony_ci
26598c2ecf20Sopenharmony_cistatic void audit_log_task(struct audit_buffer *ab)
26608c2ecf20Sopenharmony_ci{
26618c2ecf20Sopenharmony_ci	kuid_t auid, uid;
26628c2ecf20Sopenharmony_ci	kgid_t gid;
26638c2ecf20Sopenharmony_ci	unsigned int sessionid;
26648c2ecf20Sopenharmony_ci	char comm[sizeof(current->comm)];
26658c2ecf20Sopenharmony_ci
26668c2ecf20Sopenharmony_ci	auid = audit_get_loginuid(current);
26678c2ecf20Sopenharmony_ci	sessionid = audit_get_sessionid(current);
26688c2ecf20Sopenharmony_ci	current_uid_gid(&uid, &gid);
26698c2ecf20Sopenharmony_ci
26708c2ecf20Sopenharmony_ci	audit_log_format(ab, "auid=%u uid=%u gid=%u ses=%u",
26718c2ecf20Sopenharmony_ci			 from_kuid(&init_user_ns, auid),
26728c2ecf20Sopenharmony_ci			 from_kuid(&init_user_ns, uid),
26738c2ecf20Sopenharmony_ci			 from_kgid(&init_user_ns, gid),
26748c2ecf20Sopenharmony_ci			 sessionid);
26758c2ecf20Sopenharmony_ci	audit_log_task_context(ab);
26768c2ecf20Sopenharmony_ci	audit_log_format(ab, " pid=%d comm=", task_tgid_nr(current));
26778c2ecf20Sopenharmony_ci	audit_log_untrustedstring(ab, get_task_comm(comm, current));
26788c2ecf20Sopenharmony_ci	audit_log_d_path_exe(ab, current->mm);
26798c2ecf20Sopenharmony_ci}
26808c2ecf20Sopenharmony_ci
26818c2ecf20Sopenharmony_ci/**
26828c2ecf20Sopenharmony_ci * audit_core_dumps - record information about processes that end abnormally
26838c2ecf20Sopenharmony_ci * @signr: signal value
26848c2ecf20Sopenharmony_ci *
26858c2ecf20Sopenharmony_ci * If a process ends with a core dump, something fishy is going on and we
26868c2ecf20Sopenharmony_ci * should record the event for investigation.
26878c2ecf20Sopenharmony_ci */
26888c2ecf20Sopenharmony_civoid audit_core_dumps(long signr)
26898c2ecf20Sopenharmony_ci{
26908c2ecf20Sopenharmony_ci	struct audit_buffer *ab;
26918c2ecf20Sopenharmony_ci
26928c2ecf20Sopenharmony_ci	if (!audit_enabled)
26938c2ecf20Sopenharmony_ci		return;
26948c2ecf20Sopenharmony_ci
26958c2ecf20Sopenharmony_ci	if (signr == SIGQUIT)	/* don't care for those */
26968c2ecf20Sopenharmony_ci		return;
26978c2ecf20Sopenharmony_ci
26988c2ecf20Sopenharmony_ci	ab = audit_log_start(audit_context(), GFP_KERNEL, AUDIT_ANOM_ABEND);
26998c2ecf20Sopenharmony_ci	if (unlikely(!ab))
27008c2ecf20Sopenharmony_ci		return;
27018c2ecf20Sopenharmony_ci	audit_log_task(ab);
27028c2ecf20Sopenharmony_ci	audit_log_format(ab, " sig=%ld res=1", signr);
27038c2ecf20Sopenharmony_ci	audit_log_end(ab);
27048c2ecf20Sopenharmony_ci}
27058c2ecf20Sopenharmony_ci
27068c2ecf20Sopenharmony_ci/**
27078c2ecf20Sopenharmony_ci * audit_seccomp - record information about a seccomp action
27088c2ecf20Sopenharmony_ci * @syscall: syscall number
27098c2ecf20Sopenharmony_ci * @signr: signal value
27108c2ecf20Sopenharmony_ci * @code: the seccomp action
27118c2ecf20Sopenharmony_ci *
27128c2ecf20Sopenharmony_ci * Record the information associated with a seccomp action. Event filtering for
27138c2ecf20Sopenharmony_ci * seccomp actions that are not to be logged is done in seccomp_log().
27148c2ecf20Sopenharmony_ci * Therefore, this function forces auditing independent of the audit_enabled
27158c2ecf20Sopenharmony_ci * and dummy context state because seccomp actions should be logged even when
27168c2ecf20Sopenharmony_ci * audit is not in use.
27178c2ecf20Sopenharmony_ci */
27188c2ecf20Sopenharmony_civoid audit_seccomp(unsigned long syscall, long signr, int code)
27198c2ecf20Sopenharmony_ci{
27208c2ecf20Sopenharmony_ci	struct audit_buffer *ab;
27218c2ecf20Sopenharmony_ci
27228c2ecf20Sopenharmony_ci	ab = audit_log_start(audit_context(), GFP_KERNEL, AUDIT_SECCOMP);
27238c2ecf20Sopenharmony_ci	if (unlikely(!ab))
27248c2ecf20Sopenharmony_ci		return;
27258c2ecf20Sopenharmony_ci	audit_log_task(ab);
27268c2ecf20Sopenharmony_ci	audit_log_format(ab, " sig=%ld arch=%x syscall=%ld compat=%d ip=0x%lx code=0x%x",
27278c2ecf20Sopenharmony_ci			 signr, syscall_get_arch(current), syscall,
27288c2ecf20Sopenharmony_ci			 in_compat_syscall(), KSTK_EIP(current), code);
27298c2ecf20Sopenharmony_ci	audit_log_end(ab);
27308c2ecf20Sopenharmony_ci}
27318c2ecf20Sopenharmony_ci
27328c2ecf20Sopenharmony_civoid audit_seccomp_actions_logged(const char *names, const char *old_names,
27338c2ecf20Sopenharmony_ci				  int res)
27348c2ecf20Sopenharmony_ci{
27358c2ecf20Sopenharmony_ci	struct audit_buffer *ab;
27368c2ecf20Sopenharmony_ci
27378c2ecf20Sopenharmony_ci	if (!audit_enabled)
27388c2ecf20Sopenharmony_ci		return;
27398c2ecf20Sopenharmony_ci
27408c2ecf20Sopenharmony_ci	ab = audit_log_start(audit_context(), GFP_KERNEL,
27418c2ecf20Sopenharmony_ci			     AUDIT_CONFIG_CHANGE);
27428c2ecf20Sopenharmony_ci	if (unlikely(!ab))
27438c2ecf20Sopenharmony_ci		return;
27448c2ecf20Sopenharmony_ci
27458c2ecf20Sopenharmony_ci	audit_log_format(ab,
27468c2ecf20Sopenharmony_ci			 "op=seccomp-logging actions=%s old-actions=%s res=%d",
27478c2ecf20Sopenharmony_ci			 names, old_names, res);
27488c2ecf20Sopenharmony_ci	audit_log_end(ab);
27498c2ecf20Sopenharmony_ci}
27508c2ecf20Sopenharmony_ci
27518c2ecf20Sopenharmony_cistruct list_head *audit_killed_trees(void)
27528c2ecf20Sopenharmony_ci{
27538c2ecf20Sopenharmony_ci	struct audit_context *ctx = audit_context();
27548c2ecf20Sopenharmony_ci	if (likely(!ctx || !ctx->in_syscall))
27558c2ecf20Sopenharmony_ci		return NULL;
27568c2ecf20Sopenharmony_ci	return &ctx->killed_trees;
27578c2ecf20Sopenharmony_ci}
2758