Skip to content

Commit 74b862c

Browse files
ralfbaechleSomasundaram Krishnasamy
authored andcommitted
MIPS: Add syscall auditing support
The original patch is from Ralf. I have maintained it for more than six years on Loongson platform, and it works perfectly. Most of the commit messages are written by Ralf. MIPS doesn't quite fit into the existing pattern of other architectures and I'd appreciate your comments and maybe even an Acked-by. - Linux on MIPS extends the traditional syscall table used by older UNIX implementations. This is why 32-bit Linux syscalls are starting from 4000; the native 64-bit syscalls start from 5000 and the N32 compat ABI from 6000. The existing syscall bitmap is only large enough for at most 2048 syscalls, so I had to increase AUDIT_BITMASK_SIZE to 256 which provides enough space for 8192 syscalls. Because include/uapi/linux/ audit.h and AUDIT_BITMASK_SIZE are exported to userspace I've used an #ifdef __mips__ for this. - The code treats the little endian MIPS architecture as separate from big endian. Combined with the 3 ABIs that's 6 combinations. I tried to sort of follow the example set by ARM which explicitly lists the (rare) big endian architecture variant - but it doesn't seem to very useful so I wonder if this could be squashed to just the three ABIs without consideration of endianness? Signed-off-by: Ralf Baechle <[email protected]> Signed-off-by: Huacai Chen <[email protected]> Reviewed-by: Jiaxun Yang <[email protected]> Source: https://www.spinics.net/lists/mips/msg76903.html - includes code cleanup to silent few checkpatch.pl errors and warnings. Orabug: 31245225 Signed-off-by: Vijay Kumar <[email protected]> Reviewed-by: Dave Kleikamp <[email protected]> Signed-off-by: Somasundaram Krishnasamy <[email protected]>
1 parent fec87f9 commit 74b862c

File tree

13 files changed

+320
-9
lines changed

13 files changed

+320
-9
lines changed

arch/mips/Kconfig

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ config MIPS
1515
select ARCH_USE_QUEUED_RWLOCKS
1616
select ARCH_USE_QUEUED_SPINLOCKS
1717
select ARCH_WANT_IPC_PARSE_VERSION
18+
select AUDIT_ARCH
1819
select BUILDTIME_EXTABLE_SORT
1920
select CLONE_BACKWARDS
2021
select CPU_PM if CPU_IDLE
@@ -29,6 +30,7 @@ config MIPS
2930
select GENERIC_SMP_IDLE_THREAD
3031
select GENERIC_TIME_VSYSCALL
3132
select HANDLE_DOMAIN_IRQ
33+
select HAVE_ARCH_AUDITSYSCALL
3234
select HAVE_ARCH_JUMP_LABEL
3335
select HAVE_ARCH_KGDB
3436
select HAVE_ARCH_MMAP_RND_BITS if MMU
@@ -1069,6 +1071,15 @@ config FW_ARC
10691071
config ARCH_MAY_HAVE_PC_FDC
10701072
bool
10711073

1074+
config AUDIT_ARCH
1075+
bool
1076+
1077+
config AUDITSYSCALL_O32
1078+
bool
1079+
1080+
config AUDITSYSCALL_N32
1081+
bool
1082+
10721083
config BOOT_RAW
10731084
bool
10741085

@@ -3172,6 +3183,7 @@ config MIPS32_O32
31723183
select COMPAT
31733184
select MIPS32_COMPAT
31743185
select SYSVIPC_COMPAT if SYSVIPC
3186+
select AUDITSYSCALL_O32 if AUDITSYSCALL
31753187
help
31763188
Select this option if you want to run o32 binaries. These are pure
31773189
32-bit binaries as used by the 32-bit Linux/MIPS port. Most of
@@ -3185,6 +3197,7 @@ config MIPS32_N32
31853197
select COMPAT
31863198
select MIPS32_COMPAT
31873199
select SYSVIPC_COMPAT if SYSVIPC
3200+
select AUDITSYSCALL_N32 if AUDITSYSCALL
31883201
help
31893202
Select this option if you want to run n32 binaries. These are
31903203
64-bit binaries using 32-bit quantities for addressing and certain

arch/mips/include/asm/abi.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ struct mips_abi {
2121
int (* const setup_rt_frame)(void *sig_return, struct ksignal *ksig,
2222
struct pt_regs *regs, sigset_t *set);
2323
const unsigned long restart;
24+
const int audit_arch;
2425

2526
unsigned off_sc_fpregs;
2627
unsigned off_sc_fpc_csr;

arch/mips/include/asm/unistd.h

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -67,4 +67,14 @@
6767

6868
#endif /* !__ASSEMBLY__ */
6969

70+
#ifdef CONFIG_MIPS32_N32
71+
#define NR_syscalls (__NR_N32_Linux + __NR_N32_Linux_syscalls)
72+
#elif defined(CONFIG_64BIT)
73+
#define NR_syscalls (__NR_64_Linux + __NR_64_Linux_syscalls)
74+
#elif defined(CONFIG_32BIT)
75+
#define NR_syscalls (__NR_O32_Linux + __NR_O32_Linux_syscalls)
76+
#else
77+
#error Must know ABIs in use to define NR_syscalls
78+
#endif
79+
7080
#endif /* _ASM_UNISTD_H */

arch/mips/include/uapi/asm/unistd.h

Lines changed: 13 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -7,15 +7,16 @@
77
* Copyright (C) 1995, 96, 97, 98, 99, 2000 by Ralf Baechle
88
* Copyright (C) 1999, 2000 Silicon Graphics, Inc.
99
*
10-
* Changed system calls macros _syscall5 - _syscall7 to push args 5 to 7 onto
11-
* the stack. Robin Farine for ACN S.A, Copyright (C) 1996 by ACN S.A
1210
*/
1311
#ifndef _UAPI_ASM_UNISTD_H
1412
#define _UAPI_ASM_UNISTD_H
1513

1614
#include <asm/sgidefs.h>
1715

18-
#if _MIPS_SIM == _MIPS_SIM_ABI32
16+
#if (defined(__WANT_SYSCALL_NUMBERS) && \
17+
(__WANT_SYSCALL_NUMBERS == _MIPS_SIM_ABI32)) || \
18+
(!defined(__WANT_SYSCALL_NUMBERS) && _MIPS_SIM == _MIPS_SIM_ABI32)
19+
1920

2021
/*
2122
* Linux o32 style syscalls are in the range from 4000 to 4999.
@@ -394,13 +395,14 @@
394395
* Offset of the last Linux o32 flavoured syscall
395396
*/
396397
#define __NR_Linux_syscalls 366
397-
398-
#endif /* _MIPS_SIM == _MIPS_SIM_ABI32 */
398+
#endif /* Want O32 || _MIPS_SIM == _MIPS_SIM_ABI32 */
399399

400400
#define __NR_O32_Linux 4000
401401
#define __NR_O32_Linux_syscalls 366
402402

403-
#if _MIPS_SIM == _MIPS_SIM_ABI64
403+
#if (defined(__WANT_SYSCALL_NUMBERS) && \
404+
(__WANT_SYSCALL_NUMBERS == _MIPS_SIM_ABI64)) || \
405+
(!defined(__WANT_SYSCALL_NUMBERS) && _MIPS_SIM == _MIPS_SIM_ABI64)
404406

405407
/*
406408
* Linux 64-bit syscalls are in the range from 5000 to 5999.
@@ -739,12 +741,14 @@
739741
*/
740742
#define __NR_Linux_syscalls 326
741743

742-
#endif /* _MIPS_SIM == _MIPS_SIM_ABI64 */
744+
#endif /* Want N64 || _MIPS_SIM == _MIPS_SIM_ABI64 */
743745

744746
#define __NR_64_Linux 5000
745747
#define __NR_64_Linux_syscalls 326
746748

747-
#if _MIPS_SIM == _MIPS_SIM_NABI32
749+
#if (defined(__WANT_SYSCALL_NUMBERS) && \
750+
(__WANT_SYSCALL_NUMBERS == _MIPS_SIM_NABI32)) || \
751+
(!defined(__WANT_SYSCALL_NUMBERS) && _MIPS_SIM == _MIPS_SIM_NABI32)
748752

749753
/*
750754
* Linux N32 syscalls are in the range from 6000 to 6999.
@@ -1087,7 +1091,7 @@
10871091
*/
10881092
#define __NR_Linux_syscalls 330
10891093

1090-
#endif /* _MIPS_SIM == _MIPS_SIM_NABI32 */
1094+
#endif /* Want N32 || _MIPS_SIM == _MIPS_SIM_NABI32 */
10911095

10921096
#define __NR_N32_Linux 6000
10931097
#define __NR_N32_Linux_syscalls 330

arch/mips/kernel/Makefile

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -107,6 +107,10 @@ obj-$(CONFIG_HW_PERF_EVENTS) += perf_event_mipsxx.o
107107
obj-$(CONFIG_JUMP_LABEL) += jump_label.o
108108
obj-$(CONFIG_UPROBES) += uprobes.o
109109

110+
obj-$(CONFIG_AUDITSYSCALL_O32) += audit-o32.o
111+
obj-$(CONFIG_AUDITSYSCALL_N32) += audit-n32.o
112+
obj-$(CONFIG_AUDITSYSCALL) += audit-native.o
113+
110114
obj-$(CONFIG_MIPS_CM) += mips-cm.o
111115
obj-$(CONFIG_MIPS_CPC) += mips-cpc.o
112116

arch/mips/kernel/audit-n32.c

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
#define __WANT_SYSCALL_NUMBERS _MIPS_SIM_NABI32
2+
3+
#include <linux/init.h>
4+
#include <linux/types.h>
5+
#include <linux/audit.h>
6+
#include <asm/unistd.h>
7+
8+
static unsigned int dir_class_n32[] = {
9+
#include <asm-generic/audit_dir_write.h>
10+
~0U
11+
};
12+
13+
static unsigned int read_class_n32[] = {
14+
#include <asm-generic/audit_read.h>
15+
0U
16+
};
17+
18+
static unsigned int write_class_n32[] = {
19+
#include <asm-generic/audit_write.h>
20+
~0U
21+
};
22+
23+
static unsigned int chattr_class_n32[] = {
24+
#include <asm-generic/audit_change_attr.h>
25+
~0U
26+
};
27+
28+
static unsigned int signal_class_n32[] = {
29+
#include <asm-generic/audit_signal.h>
30+
~0U
31+
};
32+
33+
int audit_classify_syscall_n32(int abi, unsigned int syscall)
34+
{
35+
switch (syscall) {
36+
case __NR_open:
37+
return 2;
38+
case __NR_openat:
39+
return 3;
40+
case __NR_execve:
41+
return 5;
42+
default:
43+
return 0;
44+
}
45+
}
46+
47+
static int __init audit_classes_n32_init(void)
48+
{
49+
audit_register_class(AUDIT_CLASS_WRITE_N32, write_class_n32);
50+
audit_register_class(AUDIT_CLASS_READ_N32, read_class_n32);
51+
audit_register_class(AUDIT_CLASS_DIR_WRITE_N32, dir_class_n32);
52+
audit_register_class(AUDIT_CLASS_CHATTR_N32, chattr_class_n32);
53+
audit_register_class(AUDIT_CLASS_SIGNAL_N32, signal_class_n32);
54+
55+
return 0;
56+
}
57+
58+
arch_initcall(audit_classes_n32_init);
59+

arch/mips/kernel/audit-native.c

Lines changed: 102 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,102 @@
1+
#include <linux/init.h>
2+
#include <linux/types.h>
3+
#include <linux/audit.h>
4+
#include <asm/unistd.h>
5+
6+
static unsigned int dir_class[] = {
7+
#include <asm-generic/audit_dir_write.h>
8+
~0U
9+
};
10+
11+
static unsigned int read_class[] = {
12+
#include <asm-generic/audit_read.h>
13+
~0U
14+
};
15+
16+
static unsigned int write_class[] = {
17+
#include <asm-generic/audit_write.h>
18+
~0U
19+
};
20+
21+
static unsigned int chattr_class[] = {
22+
#include <asm-generic/audit_change_attr.h>
23+
~0U
24+
};
25+
26+
static unsigned int signal_class[] = {
27+
#include <asm-generic/audit_signal.h>
28+
~0U
29+
};
30+
31+
32+
/*
33+
* Pretend to be a single architecture
34+
*/
35+
int audit_classify_arch(int arch)
36+
{
37+
return 0;
38+
}
39+
40+
extern int audit_classify_syscall_o32(int abi, unsigned int syscall);
41+
extern int audit_classify_syscall_n32(int abi, unsigned int syscall);
42+
43+
int audit_classify_syscall(int abi, unsigned int syscall)
44+
{
45+
int res;
46+
47+
switch (syscall) {
48+
case __NR_open:
49+
res = 2;
50+
break;
51+
case __NR_openat:
52+
res = 3;
53+
break;
54+
#ifdef __NR_socketcall /* Only exists on O32 */
55+
case __NR_socketcall:
56+
res = 4;
57+
break;
58+
#endif
59+
case __NR_execve:
60+
res = 5;
61+
break;
62+
default:
63+
#ifdef CONFIG_AUDITSYSCALL_O32
64+
res = audit_classify_syscall_o32(abi, syscall);
65+
if (res)
66+
break;
67+
#endif
68+
#ifdef CONFIG_AUDITSYSCALL_N32
69+
res = audit_classify_syscall_n32(abi, syscall);
70+
if (res)
71+
break;
72+
#endif
73+
switch (abi) {
74+
case AUDIT_ARCH_MIPS:
75+
case AUDIT_ARCH_MIPSEL:
76+
res = 1;
77+
break;
78+
case AUDIT_ARCH_MIPS64:
79+
case AUDIT_ARCH_MIPSEL64:
80+
res = 0;
81+
break;
82+
case AUDIT_ARCH_MIPS64N32:
83+
case AUDIT_ARCH_MIPSEL64N32:
84+
res = 6;
85+
}
86+
}
87+
88+
return res;
89+
}
90+
91+
static int __init audit_classes_init(void)
92+
{
93+
audit_register_class(AUDIT_CLASS_WRITE, write_class);
94+
audit_register_class(AUDIT_CLASS_READ, read_class);
95+
audit_register_class(AUDIT_CLASS_DIR_WRITE, dir_class);
96+
audit_register_class(AUDIT_CLASS_CHATTR, chattr_class);
97+
audit_register_class(AUDIT_CLASS_SIGNAL, signal_class);
98+
99+
return 0;
100+
}
101+
102+
arch_initcall(audit_classes_init);

arch/mips/kernel/audit-o32.c

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
#define __WANT_SYSCALL_NUMBERS _MIPS_SIM_ABI32
2+
3+
#include <linux/init.h>
4+
#include <linux/types.h>
5+
#include <linux/audit.h>
6+
#include <linux/unistd.h>
7+
8+
static unsigned int dir_class_o32[] = {
9+
#include <asm-generic/audit_dir_write.h>
10+
~0U
11+
};
12+
13+
static unsigned int read_class_o32[] = {
14+
#include <asm-generic/audit_read.h>
15+
~0U
16+
};
17+
18+
static unsigned int write_class_o32[] = {
19+
#include <asm-generic/audit_write.h>
20+
~0U
21+
};
22+
23+
static unsigned int chattr_class_o32[] = {
24+
#include <asm-generic/audit_change_attr.h>
25+
~0U
26+
};
27+
28+
static unsigned int signal_class_o32[] = {
29+
#include <asm-generic/audit_signal.h>
30+
~0U
31+
};
32+
33+
int audit_classify_syscall_o32(int abi, unsigned int syscall)
34+
{
35+
switch (syscall) {
36+
case __NR_open:
37+
return 2;
38+
case __NR_openat:
39+
return 3;
40+
case __NR_socketcall:
41+
return 4;
42+
case __NR_execve:
43+
return 5;
44+
default:
45+
return 0;
46+
}
47+
}
48+
49+
static int __init audit_classes_o32_init(void)
50+
{
51+
audit_register_class(AUDIT_CLASS_WRITE_32, write_class_o32);
52+
audit_register_class(AUDIT_CLASS_READ_32, read_class_o32);
53+
audit_register_class(AUDIT_CLASS_DIR_WRITE_32, dir_class_o32);
54+
audit_register_class(AUDIT_CLASS_CHATTR_32, chattr_class_o32);
55+
audit_register_class(AUDIT_CLASS_SIGNAL_32, signal_class_o32);
56+
57+
return 0;
58+
}
59+
60+
arch_initcall(audit_classes_o32_init);
61+

0 commit comments

Comments
 (0)