1 /*
2 * Copyright (c) 2019-2021 Dmitry V. Levin <ldv@strace.io>
3 * All rights reserved.
4 *
5 * SPDX-License-Identifier: LGPL-2.1-or-later
6 */
7
8 #include "defs.h"
9 #include <linux/fcntl.h>
10 #include <linux/mount.h>
11 #include "xlat/mount_setattr_flags.h"
12 #include "xlat/mount_attr_attr.h"
13 #include "xlat/mount_attr_propagation.h"
14
15 static void
16 print_mount_attr(struct tcb *const tcp,
17 const kernel_ulong_t addr,
18 const kernel_ulong_t size)
19 {
20 struct mount_attr attr;
21
22 if (size < MOUNT_ATTR_SIZE_VER0) {
23 printaddr(addr);
24 return;
25 }
26
27 if (umoven_or_printaddr(tcp, addr, MIN(sizeof(attr), size), &attr))
28 return;
29
30 tprint_struct_begin();
31
32 PRINT_FIELD_FLAGS(attr, attr_set, mount_attr_attr, "MOUNT_ATTR_???");
33 tprint_struct_next();
34
35 PRINT_FIELD_FLAGS(attr, attr_clr, mount_attr_attr, "MOUNT_ATTR_???");
36 tprint_struct_next();
37
38 PRINT_FIELD_XVAL(attr, propagation, mount_attr_propagation, "MS_???");
39 tprint_struct_next();
40
41 if (attr.userns_fd > INT_MAX ||
42 !((attr.attr_set | attr.attr_clr) & MOUNT_ATTR_IDMAP)) {
43 PRINT_FIELD_U(attr, userns_fd);
44 } else {
45 PRINT_FIELD_FD(attr, userns_fd, tcp);
46 }
47
48 if (size > sizeof(attr)) {
49 print_nonzero_bytes(tcp, tprint_struct_next, addr, sizeof(attr),
50 MIN(size, get_pagesize()), QUOTE_FORCE_HEX);
51 }
52
53 tprint_struct_end();
54 }
55
56 SYS_FUNC(mount_setattr)
57 {
58 /* dirfd */
59 print_dirfd(tcp, tcp->u_arg[0]);
60 tprint_arg_next();
61
62 /* pathname */
63 printpath(tcp, tcp->u_arg[1]);
64 tprint_arg_next();
65
66 /* flags */
67 printflags(mount_setattr_flags, tcp->u_arg[2], "AT_???");
68 tprint_arg_next();
69
70 /* uattr */
71 print_mount_attr(tcp, tcp->u_arg[3], tcp->u_arg[4]);
72 tprint_arg_next();
73
74 /* usize */
75 PRINT_VAL_U(tcp->u_arg[4]);
76
77 return RVAL_DECODED | RVAL_FD;
78 }