]> granicus.if.org Git - strace/blob - block.c
Fix decoding of getsockname, getpeername, accept, and accept4 syscalls
[strace] / block.c
1 /*
2  * Copyright (c) 2009, 2010 Jeff Mahoney <jeffm@suse.com>
3  * Copyright (c) 2011-2016 Dmitry V. Levin <ldv@altlinux.org>
4  * All rights reserved.
5  *
6  * Redistribution and use in source and binary forms, with or without
7  * modification, are permitted provided that the following conditions
8  * are met:
9  * 1. Redistributions of source code must retain the above copyright
10  *    notice, this list of conditions and the following disclaimer.
11  * 2. Redistributions in binary form must reproduce the above copyright
12  *    notice, this list of conditions and the following disclaimer in the
13  *    documentation and/or other materials provided with the distribution.
14  * 3. The name of the author may not be used to endorse or promote products
15  *    derived from this software without specific prior written permission.
16  *
17  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
18  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
19  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
20  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
21  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
22  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
26  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27  */
28
29 #include "defs.h"
30
31 #include DEF_MPERS_TYPE(struct_blk_user_trace_setup)
32 #include DEF_MPERS_TYPE(struct_blkpg_ioctl_arg)
33 #include DEF_MPERS_TYPE(struct_blkpg_partition)
34
35 #include <linux/blkpg.h>
36 #include <linux/fs.h>
37
38 #define BLKTRACE_BDEV_SIZE      32
39 typedef struct blk_user_trace_setup {
40         char name[BLKTRACE_BDEV_SIZE];  /* output */
41         uint16_t act_mask;              /* input */
42         uint32_t buf_size;              /* input */
43         uint32_t buf_nr;                /* input */
44         uint64_t start_lba;
45         uint64_t end_lba;
46         uint32_t pid;
47 } struct_blk_user_trace_setup;
48
49 typedef struct blkpg_ioctl_arg struct_blkpg_ioctl_arg;
50 typedef struct blkpg_partition struct_blkpg_partition;
51
52 #include MPERS_DEFS
53
54 /*
55  * ioctl numbers <= 114 are present in Linux 2.4.  The following ones have been
56  * added since then and headers containing them may not be available on every
57  * system.
58  */
59
60 #ifndef BLKTRACESETUP
61 # define BLKTRACESETUP _IOWR(0x12, 115, struct_blk_user_trace_setup)
62 #endif
63 #ifndef BLKTRACESTART
64 # define BLKTRACESTART _IO(0x12,116)
65 #endif
66 #ifndef BLKTRACESTOP
67 # define BLKTRACESTOP _IO(0x12,117)
68 #endif
69 #ifndef BLKTRACETEARDOWN
70 # define BLKTRACETEARDOWN _IO(0x12,118)
71 #endif
72 #ifndef BLKDISCARD
73 # define BLKDISCARD _IO(0x12,119)
74 #endif
75 #ifndef BLKIOMIN
76 # define BLKIOMIN _IO(0x12,120)
77 #endif
78 #ifndef BLKIOOPT
79 # define BLKIOOPT _IO(0x12,121)
80 #endif
81 #ifndef BLKALIGNOFF
82 # define BLKALIGNOFF _IO(0x12,122)
83 #endif
84 #ifndef BLKPBSZGET
85 # define BLKPBSZGET _IO(0x12,123)
86 #endif
87 #ifndef BLKDISCARDZEROES
88 # define BLKDISCARDZEROES _IO(0x12,124)
89 #endif
90 #ifndef BLKSECDISCARD
91 # define BLKSECDISCARD _IO(0x12,125)
92 #endif
93 #ifndef BLKROTATIONAL
94 # define BLKROTATIONAL _IO(0x12,126)
95 #endif
96 #ifndef BLKZEROOUT
97 # define BLKZEROOUT _IO(0x12,127)
98 #endif
99 #ifndef BLKDAXGET
100 # define BLKDAXGET _IO(0x12,129)
101 #endif
102
103 #include "xlat/blkpg_ops.h"
104
105 static void
106 print_blkpg_req(struct tcb *tcp, const struct_blkpg_ioctl_arg *blkpg)
107 {
108         struct_blkpg_partition p;
109
110         tprints("{");
111         printxval(blkpg_ops, blkpg->op, "BLKPG_???");
112
113         tprintf(", flags=%d, datalen=%d, data=",
114                 blkpg->flags, blkpg->datalen);
115
116         if (!umove_or_printaddr(tcp, (long) blkpg->data, &p)) {
117                 tprintf("{start=%lld, length=%lld, pno=%d, devname=",
118                         (long long) p.start, (long long) p.length, p.pno);
119                 print_quoted_string(p.devname, sizeof(p.devname),
120                                     QUOTE_0_TERMINATED);
121                 tprints(", volname=");
122                 print_quoted_string(p.volname, sizeof(p.volname),
123                                     QUOTE_0_TERMINATED);
124                 tprints("}");
125         }
126         tprints("}");
127 }
128
129 MPERS_PRINTER_DECL(int, block_ioctl, struct tcb *tcp,
130                    const unsigned int code, const long arg)
131 {
132         switch (code) {
133         /* take arg as a value, not as a pointer */
134         case BLKRASET:
135         case BLKFRASET:
136                 tprintf(", %lu", arg);
137                 break;
138
139         /* return an unsigned short */
140         case BLKSECTGET:
141         case BLKROTATIONAL:
142                 if (entering(tcp))
143                         return 0;
144                 tprints(", ");
145                 printnum_short(tcp, arg, "%hu");
146                 break;
147
148         /* return a signed int */
149         case BLKROGET:
150         case BLKBSZGET:
151         case BLKSSZGET:
152         case BLKALIGNOFF:
153         case BLKDAXGET:
154                 if (entering(tcp))
155                         return 0;
156                 /* fall through */
157         /* take a signed int */
158         case BLKROSET:
159         case BLKBSZSET:
160                 tprints(", ");
161                 printnum_int(tcp, arg, "%d");
162                 break;
163
164         /* return an unsigned int */
165         case BLKPBSZGET:
166         case BLKIOMIN:
167         case BLKIOOPT:
168         case BLKDISCARDZEROES:
169                 if (entering(tcp))
170                         return 0;
171                 tprints(", ");
172                 printnum_int(tcp, arg, "%u");
173                 break;
174
175         /* return a signed long */
176         case BLKRAGET:
177         case BLKFRAGET:
178                 if (entering(tcp))
179                         return 0;
180                 tprints(", ");
181                 printnum_slong(tcp, arg);
182                 break;
183
184         /* returns an unsigned long */
185         case BLKGETSIZE:
186                 if (entering(tcp))
187                         return 0;
188                 tprints(", ");
189                 printnum_ulong(tcp, arg);
190                 break;
191
192 #ifdef HAVE_BLKGETSIZE64
193         /* returns an uint64_t */
194         case BLKGETSIZE64:
195                 if (entering(tcp))
196                         return 0;
197                 tprints(", ");
198                 printnum_int64(tcp, arg, "%" PRIu64);
199                 break;
200 #endif
201
202         /* takes a pair of uint64_t */
203         case BLKDISCARD:
204         case BLKSECDISCARD:
205         case BLKZEROOUT:
206                 tprints(", ");
207                 printpair_int64(tcp, arg, "%" PRIu64);
208                 break;
209
210         /* More complex types */
211         case BLKPG: {
212                 struct_blkpg_ioctl_arg blkpg;
213
214                 tprints(", ");
215                 if (!umove_or_printaddr(tcp, arg, &blkpg))
216                         print_blkpg_req(tcp, &blkpg);
217                 break;
218         }
219
220         case BLKTRACESETUP:
221                 if (entering(tcp)) {
222                         struct_blk_user_trace_setup buts;
223
224                         tprints(", ");
225                         if (umove_or_printaddr(tcp, arg, &buts))
226                                 break;
227                         tprintf("{act_mask=%u, buf_size=%u, "
228                                 "buf_nr=%u, start_lba=%" PRIu64 ", "
229                                 "end_lba=%" PRIu64 ", pid=%u",
230                                 (unsigned)buts.act_mask, buts.buf_size,
231                                 buts.buf_nr, buts.start_lba,
232                                 buts.end_lba, buts.pid);
233                         return 1;
234                 } else {
235                         struct_blk_user_trace_setup buts;
236
237                         if (!syserror(tcp) && !umove(tcp, arg, &buts)) {
238                                 tprints(", name=");
239                                 print_quoted_string(buts.name, sizeof(buts.name),
240                                                     QUOTE_0_TERMINATED);
241                         }
242                         tprints("}");
243                         break;
244                 }
245
246         /* No arguments */
247         case BLKRRPART:
248         case BLKFLSBUF:
249         case BLKTRACESTART:
250         case BLKTRACESTOP:
251         case BLKTRACETEARDOWN:
252                 break;
253         default:
254                 return RVAL_DECODED;
255         }
256
257         return RVAL_DECODED | 1;
258 }