1 /*
2 * Copyright (c) 2021 Eugene Syromyatnikov <evgsyr@gmail.com>
3 * All rights reserved.
4 *
5 * SPDX-License-Identifier: LGPL-2.1-or-later
6 */
7
8 #include "defs.h"
9
10 #include <linux/landlock.h>
11
12 #include "xlat/landlock_create_ruleset_flags.h"
13 #include "xlat/landlock_rule_types.h"
14 #include "xlat/landlock_ruleset_access_fs.h"
15
16 static void
17 print_landlock_ruleset_attr(struct tcb *tcp, const kernel_ulong_t addr,
18 const kernel_ulong_t size)
19 {
20 struct landlock_ruleset_attr attr;
21
22 if (size < offsetofend(typeof(attr), handled_access_fs)) {
23 printaddr(addr);
24 return;
25 }
26
27 if (umoven_or_printaddr(tcp, addr, MIN(size, sizeof(attr)), &attr))
28 return;
29
30 tprint_struct_begin();
31 PRINT_FIELD_FLAGS(attr, handled_access_fs, landlock_ruleset_access_fs,
32 "LANDLOCK_ACCESS_FS_???");
33
34 if (size > offsetofend(typeof(attr), handled_access_fs)) {
35 tprint_arg_next();
36 tprint_more_data_follows();
37 }
38
39 tprint_struct_end();
40 }
41
42 SYS_FUNC(landlock_create_ruleset)
43 {
44 kernel_ulong_t attr = tcp->u_arg[0];
45 kernel_ulong_t size = tcp->u_arg[1];
46 unsigned int flags = tcp->u_arg[2];
47 int fd_flag = flags & LANDLOCK_CREATE_RULESET_VERSION ? 0 : RVAL_FD;
48
49 /* attr */
50 print_landlock_ruleset_attr(tcp, attr, size);
51 tprint_arg_next();
52
53 /* size */
54 PRINT_VAL_U(size);
55 tprint_arg_next();
56
57 /* flags */
58 printflags(landlock_create_ruleset_flags, flags,
59 "LANDLOCK_CREATE_RULESET_???");
60
61 return RVAL_DECODED | fd_flag;
62 }
63
64 static void
65 print_landlock_path_beneath_attr(struct tcb *tcp, const kernel_ulong_t addr)
66 {
67 struct landlock_path_beneath_attr attr;
68
69 if (umove_or_printaddr(tcp, addr, &attr))
70 return;
71
72 tprint_struct_begin();
73 PRINT_FIELD_FLAGS(attr, allowed_access, landlock_ruleset_access_fs,
74 "LANDLOCK_ACCESS_FS_???");
75 tprint_struct_next();
76 PRINT_FIELD_FD(attr, parent_fd, tcp);
77 tprint_struct_end();
78 }
79
80 SYS_FUNC(landlock_add_rule)
81 {
82 unsigned int rule_type = tcp->u_arg[1];
83
84 /* ruleset_fd */
85 printfd(tcp, tcp->u_arg[0]);
86 tprint_arg_next();
87
88 /* rule_type */
89 printxval(landlock_rule_types, rule_type, "LANDLOCK_RULE_???");
90 tprint_arg_next();
91
92 /* rule_attr */
93 switch (rule_type) {
94 case LANDLOCK_RULE_PATH_BENEATH:
95 print_landlock_path_beneath_attr(tcp, tcp->u_arg[2]);
96 break;
97
98 default:
99 printaddr(tcp->u_arg[2]);
100 }
101 tprint_arg_next();
102
103 /* flags */
104 PRINT_VAL_X((unsigned int) tcp->u_arg[3]);
105
106 return RVAL_DECODED;
107 }
108
109 SYS_FUNC(landlock_restrict_self)
110 {
111 /* ruleset_fd */
112 printfd(tcp, tcp->u_arg[0]);
113 tprint_arg_next();
114
115 /* flags */
116 PRINT_VAL_X((unsigned int) tcp->u_arg[1]);
117
118 return RVAL_DECODED;
119 }