]> granicus.if.org Git - strace/blob - kexec.c
Robustify mpers.awk against invalid input
[strace] / kexec.c
1 #include "defs.h"
2
3 #include "xlat/kexec_load_flags.h"
4 #include "xlat/kexec_arch_values.h"
5
6 #ifndef KEXEC_ARCH_MASK
7 # define KEXEC_ARCH_MASK 0xffff0000
8 #endif
9 #ifndef KEXEC_SEGMENT_MAX
10 # define KEXEC_SEGMENT_MAX 16
11 #endif
12
13 static void
14 print_seg(const unsigned long *seg)
15 {
16         tprints("{");
17         printaddr(seg[0]);
18         tprintf(", %lu, ", seg[1]);
19         printaddr(seg[2]);
20         tprintf(", %lu}", seg[3]);
21 }
22
23 static void
24 print_kexec_segments(struct tcb *tcp, const unsigned long addr,
25                      const unsigned long len)
26 {
27         unsigned long seg[4];
28         const size_t sizeof_seg = ARRAY_SIZE(seg) * current_wordsize;
29         unsigned int i;
30
31         if (!len) {
32                 tprints("[]");
33                 return;
34         }
35
36         if (len > KEXEC_SEGMENT_MAX) {
37                 printaddr(addr);
38                 return;
39         }
40
41         if (umove_ulong_array_or_printaddr(tcp, addr, seg, ARRAY_SIZE(seg)))
42                 return;
43
44         tprints("[");
45         print_seg(seg);
46
47         for (i = 1; i < len; ++i) {
48                 tprints(", ");
49                 if (umove_ulong_array_or_printaddr(tcp,
50                                                    addr + i * sizeof_seg,
51                                                    seg, ARRAY_SIZE(seg)))
52                         break;
53                 print_seg(seg);
54         }
55
56         tprints("]");
57 }
58
59 SYS_FUNC(kexec_load)
60 {
61         unsigned long n;
62
63         /* entry, nr_segments */
64         printaddr(tcp->u_arg[0]);
65         tprintf(", %lu, ", tcp->u_arg[1]);
66
67         /* segments */
68         print_kexec_segments(tcp, tcp->u_arg[2], tcp->u_arg[1]);
69         tprints(", ");
70
71         /* flags */
72         n = tcp->u_arg[3];
73         printxval(kexec_arch_values, n & KEXEC_ARCH_MASK, "KEXEC_ARCH_???");
74         n &= ~KEXEC_ARCH_MASK;
75         if (n) {
76                 tprints("|");
77                 printflags(kexec_load_flags, n, "KEXEC_???");
78         }
79
80         return RVAL_DECODED;
81 }
82
83 #include "xlat/kexec_file_load_flags.h"
84
85 SYS_FUNC(kexec_file_load)
86 {
87         /* kernel_fd */
88         printfd(tcp, tcp->u_arg[0]);
89         tprints(", ");
90         /* initrd_fd */
91         printfd(tcp, tcp->u_arg[1]);
92         tprints(", ");
93         /* cmdline_len */
94         tprintf("%lu, ", tcp->u_arg[2]);
95         /* cmdline */
96         printstr(tcp, tcp->u_arg[3], tcp->u_arg[2]);
97         tprints(", ");
98         /* flags */
99         printflags(kexec_file_load_flags, tcp->u_arg[4], "KEXEC_FILE_???");
100
101         return RVAL_DECODED;
102 }