Branch data Line data Source code
1 : : /*
2 : : * Copyright (c) 2012 The Chromium OS Authors.
3 : : * Written by Mike Frysinger <vapier@gentoo.org>.
4 : : *
5 : : * Redistribution and use in source and binary forms, with or without
6 : : * modification, are permitted provided that the following conditions
7 : : * are met:
8 : : * 1. Redistributions of source code must retain the above copyright
9 : : * notice, this list of conditions and the following disclaimer.
10 : : * 2. Redistributions in binary form must reproduce the above copyright
11 : : * notice, this list of conditions and the following disclaimer in the
12 : : * documentation and/or other materials provided with the distribution.
13 : : * 3. The name of the author may not be used to endorse or promote products
14 : : * derived from this software without specific prior written permission.
15 : : *
16 : : * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
17 : : * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
18 : : * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
19 : : * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
20 : : * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
21 : : * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
22 : : * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
23 : : * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 : : * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
25 : : * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 : : */
27 : :
28 : : #include "defs.h"
29 : : #include <linux/ioctl.h>
30 : : #include <linux/loop.h>
31 : :
32 : : typedef struct loop_info struct_loop_info;
33 : :
34 : : #include DEF_MPERS_TYPE(struct_loop_info)
35 : :
36 : : #include MPERS_DEFS
37 : :
38 : : #include "xlat/loop_cmds.h"
39 : : #include "xlat/loop_flags_options.h"
40 : : #include "xlat/loop_crypt_type_options.h"
41 : :
42 : : static void
43 : 90 : decode_loop_info(struct tcb *const tcp, const kernel_ulong_t addr)
44 : : {
45 : : struct_loop_info info;
46 : :
47 : 90 : tprints(", ");
48 [ + + ]: 90 : if (umove_or_printaddr(tcp, addr, &info))
49 : 70 : return;
50 : :
51 : 20 : tprintf("{lo_number=%d", info.lo_number);
52 : :
53 [ + + ]: 20 : if (!abbrev(tcp)) {
54 : 10 : tprints(", lo_device=");
55 : 10 : print_dev_t(info.lo_device);
56 : 10 : tprintf(", lo_inode=%" PRI_klu, (kernel_ulong_t) info.lo_inode);
57 : 10 : tprints(", lo_rdevice=");
58 : 10 : print_dev_t(info.lo_rdevice);
59 : : }
60 : :
61 : 20 : tprintf(", lo_offset=%#x", info.lo_offset);
62 : :
63 [ + + ][ + + ]: 20 : if (!abbrev(tcp) || info.lo_encrypt_type != LO_CRYPT_NONE) {
64 : 15 : tprints(", lo_encrypt_type=");
65 : 15 : printxval(loop_crypt_type_options, info.lo_encrypt_type,
66 : : "LO_CRYPT_???");
67 : : /*
68 : : * It is converted to unsigned before use in kernel, see
69 : : * loop_info64_from_old in drivers/block/loop.c
70 : : */
71 : 15 : tprintf(", lo_encrypt_key_size=%" PRIu32,
72 : 15 : (uint32_t) info.lo_encrypt_key_size);
73 : : }
74 : :
75 : 20 : tprints(", lo_flags=");
76 : 20 : printflags(loop_flags_options, info.lo_flags, "LO_FLAGS_???");
77 : :
78 : 20 : tprints(", lo_name=");
79 : 20 : print_quoted_string(info.lo_name, LO_NAME_SIZE,
80 : : QUOTE_0_TERMINATED);
81 : :
82 [ + + ][ + + ]: 20 : if (!abbrev(tcp) || info.lo_encrypt_type != LO_CRYPT_NONE) {
83 : 15 : tprints(", lo_encrypt_key=");
84 : 15 : print_quoted_string((void *) info.lo_encrypt_key,
85 : 15 : MIN((uint32_t) info.lo_encrypt_key_size,
86 : : LO_KEY_SIZE), 0);
87 : : }
88 : :
89 [ + + ]: 20 : if (!abbrev(tcp))
90 : 10 : tprintf(", lo_init=[%#" PRI_klx ", %#" PRI_klx "]"
91 : : ", reserved=[%#hhx, %#hhx, %#hhx, %#hhx]}",
92 : 2 : (kernel_ulong_t) info.lo_init[0],
93 : 2 : (kernel_ulong_t) info.lo_init[1],
94 : 20 : info.reserved[0], info.reserved[1],
95 : 20 : info.reserved[2], info.reserved[3]);
96 : : else
97 : 20 : tprints(", ...}");
98 : : }
99 : :
100 : : static void
101 : 90 : decode_loop_info64(struct tcb *const tcp, const kernel_ulong_t addr)
102 : : {
103 : : struct loop_info64 info64;
104 : :
105 : 90 : tprints(", ");
106 [ + + ]: 90 : if (umove_or_printaddr(tcp, addr, &info64))
107 : 70 : return;
108 : :
109 [ + + ]: 20 : if (!abbrev(tcp)) {
110 : 10 : tprints("{lo_device=");
111 : 10 : print_dev_t(info64.lo_device);
112 : 10 : tprintf(", lo_inode=%" PRIu64, (uint64_t) info64.lo_inode);
113 : 10 : tprints(", lo_rdevice=");
114 : 10 : print_dev_t(info64.lo_rdevice);
115 : 10 : tprintf(", lo_offset=%#" PRIx64 ", lo_sizelimit=%" PRIu64
116 : : ", lo_number=%" PRIu32,
117 : 10 : (uint64_t) info64.lo_offset,
118 : 10 : (uint64_t) info64.lo_sizelimit,
119 : 10 : (uint32_t) info64.lo_number);
120 : : } else {
121 : 10 : tprintf("{lo_offset=%#" PRIx64 ", lo_number=%" PRIu32,
122 : 10 : (uint64_t) info64.lo_offset,
123 : 10 : (uint32_t) info64.lo_number);
124 : : }
125 : :
126 [ + + ][ + + ]: 20 : if (!abbrev(tcp) || info64.lo_encrypt_type != LO_CRYPT_NONE) {
127 : 15 : tprints(", lo_encrypt_type=");
128 : 15 : printxval(loop_crypt_type_options, info64.lo_encrypt_type,
129 : : "LO_CRYPT_???");
130 : 15 : tprintf(", lo_encrypt_key_size=%" PRIu32,
131 : : info64.lo_encrypt_key_size);
132 : : }
133 : :
134 : 20 : tprints(", lo_flags=");
135 : 20 : printflags(loop_flags_options, info64.lo_flags, "LO_FLAGS_???");
136 : :
137 : 20 : tprints(", lo_file_name=");
138 : 20 : print_quoted_string((void *) info64.lo_file_name,
139 : : LO_NAME_SIZE, QUOTE_0_TERMINATED);
140 : :
141 [ + + ][ + + ]: 20 : if (!abbrev(tcp) || info64.lo_encrypt_type != LO_CRYPT_NONE) {
142 : 15 : tprints(", lo_crypt_name=");
143 : 15 : print_quoted_string((void *) info64.lo_crypt_name,
144 : : LO_NAME_SIZE, QUOTE_0_TERMINATED);
145 : 15 : tprints(", lo_encrypt_key=");
146 : 15 : print_quoted_string((void *) info64.lo_encrypt_key,
147 : 15 : MIN(info64.lo_encrypt_key_size,
148 : : LO_KEY_SIZE), 0);
149 : : }
150 : :
151 [ + + ]: 20 : if (!abbrev(tcp))
152 : 10 : tprintf(", lo_init=[%#" PRIx64 ", %#" PRIx64 "]}",
153 : 10 : (uint64_t) info64.lo_init[0],
154 : 10 : (uint64_t) info64.lo_init[1]);
155 : : else
156 : 20 : tprints(", ...}");
157 : : }
158 : :
159 : 405 : MPERS_PRINTER_DECL(int, loop_ioctl,
160 : : struct tcb *tcp, const unsigned int code,
161 : : const kernel_ulong_t arg)
162 : : {
163 [ + + + + : 405 : switch (code) {
+ + + +
+ ]
164 : : case LOOP_GET_STATUS:
165 [ + + ]: 60 : if (entering(tcp))
166 : 30 : return 0;
167 : : /* fall through */
168 : : case LOOP_SET_STATUS:
169 : 90 : decode_loop_info(tcp, arg);
170 : 90 : break;
171 : :
172 : : case LOOP_GET_STATUS64:
173 [ + + ]: 60 : if (entering(tcp))
174 : 30 : return 0;
175 : : /* fall through */
176 : : case LOOP_SET_STATUS64:
177 : 90 : decode_loop_info64(tcp, arg);
178 : 90 : break;
179 : :
180 : : case LOOP_CLR_FD:
181 : : case LOOP_SET_CAPACITY:
182 : : /* newer loop-control stuff */
183 : : case LOOP_CTL_GET_FREE:
184 : : /* Takes no arguments */
185 : 45 : break;
186 : :
187 : : case LOOP_SET_FD:
188 : : case LOOP_CHANGE_FD:
189 : 30 : tprints(", ");
190 : 30 : printfd(tcp, arg);
191 : 30 : break;
192 : :
193 : : /* newer loop-control stuff */
194 : : case LOOP_CTL_ADD:
195 : : case LOOP_CTL_REMOVE:
196 : 30 : tprintf(", %d", (int) arg);
197 : 30 : break;
198 : :
199 : : case LOOP_SET_DIRECT_IO:
200 : 15 : tprintf(", %" PRI_klu, arg);
201 : 15 : break;
202 : :
203 : : default:
204 : 45 : return RVAL_DECODED;
205 : : }
206 : :
207 : 300 : return RVAL_DECODED | 1;
208 : : }
|