]> granicus.if.org Git - strace/blob - file.c
get_scno: add diagnostics for invalid syscall numbers
[strace] / file.c
1 /*
2  * Copyright (c) 1991, 1992 Paul Kranenburg <pk@cs.few.eur.nl>
3  * Copyright (c) 1993 Branko Lankester <branko@hacktic.nl>
4  * Copyright (c) 1993, 1994, 1995, 1996 Rick Sladkey <jrs@world.std.com>
5  * Copyright (c) 1996-1999 Wichert Akkerman <wichert@cistron.nl>
6  * All rights reserved.
7  *
8  * Redistribution and use in source and binary forms, with or without
9  * modification, are permitted provided that the following conditions
10  * are met:
11  * 1. Redistributions of source code must retain the above copyright
12  *    notice, this list of conditions and the following disclaimer.
13  * 2. Redistributions in binary form must reproduce the above copyright
14  *    notice, this list of conditions and the following disclaimer in the
15  *    documentation and/or other materials provided with the distribution.
16  * 3. The name of the author may not be used to endorse or promote products
17  *    derived from this software without specific prior written permission.
18  *
19  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
20  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
21  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
22  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
23  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
24  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
25  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
26  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
28  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29  */
30
31 #include "defs.h"
32
33 #undef dev_t
34 #undef ino_t
35 #undef mode_t
36 #undef nlink_t
37 #undef uid_t
38 #undef gid_t
39 #undef off_t
40 #undef loff_t
41 #define dev_t __kernel_dev_t
42 #define ino_t __kernel_ino_t
43 #define mode_t __kernel_mode_t
44 #define nlink_t __kernel_nlink_t
45 #define uid_t __kernel_uid_t
46 #define gid_t __kernel_gid_t
47 #define off_t __kernel_off_t
48 #define loff_t __kernel_loff_t
49
50 #include <asm/stat.h>
51
52 #undef dev_t
53 #undef ino_t
54 #undef mode_t
55 #undef nlink_t
56 #undef uid_t
57 #undef gid_t
58 #undef off_t
59 #undef loff_t
60 #define dev_t dev_t
61 #define ino_t ino_t
62 #define mode_t mode_t
63 #define nlink_t nlink_t
64 #define uid_t uid_t
65 #define gid_t gid_t
66 #define off_t off_t
67 #define loff_t loff_t
68
69 /* for S_IFMT */
70 #define stat libc_stat
71 #define stat64 libc_stat64
72 #include <sys/stat.h>
73 #undef stat
74 #undef stat64
75 /* These might be macros. */
76 #undef st_atime
77 #undef st_mtime
78 #undef st_ctime
79
80 #if defined MAJOR_IN_SYSMACROS
81 # include <sys/sysmacros.h>
82 #elif defined MAJOR_IN_MKDEV
83 # include <sys/mkdev.h>
84 #endif
85
86 /* several stats */
87
88 #include "printstat.h"
89
90 #undef STAT32_PERSONALITY
91 #if SUPPORTED_PERSONALITIES > 1
92 # if defined AARCH64 || defined X86_64 || defined X32
93 struct stat32 {
94         unsigned int    st_dev;
95         unsigned int    st_ino;
96         unsigned short  st_mode;
97         unsigned short  st_nlink;
98         unsigned short  st_uid;
99         unsigned short  st_gid;
100         unsigned int    st_rdev;
101         unsigned int    st_size;
102         unsigned int    st_blksize;
103         unsigned int    st_blocks;
104         unsigned int    st_atime;
105         unsigned int    st_atime_nsec;
106         unsigned int    st_mtime;
107         unsigned int    st_mtime_nsec;
108         unsigned int    st_ctime;
109         unsigned int    st_ctime_nsec;
110         unsigned int    __unused4;
111         unsigned int    __unused5;
112 };
113 #  ifdef AARCH64
114 #   define STAT32_PERSONALITY 0
115 #  else
116 #   define STAT32_PERSONALITY 1
117 #  endif
118 # elif defined POWERPC64
119 struct stat32 {
120         unsigned int    st_dev;
121         unsigned int    st_ino;
122         unsigned int    st_mode;
123         unsigned short  st_nlink;
124         unsigned int    st_uid;
125         unsigned int    st_gid;
126         unsigned int    st_rdev;
127         unsigned int    st_size;
128         unsigned int    st_blksize;
129         unsigned int    st_blocks;
130         unsigned int    st_atime;
131         unsigned int    st_atime_nsec;
132         unsigned int    st_mtime;
133         unsigned int    st_mtime_nsec;
134         unsigned int    st_ctime;
135         unsigned int    st_ctime_nsec;
136         unsigned int    __unused4;
137         unsigned int    __unused5;
138 };
139 #  define STAT32_PERSONALITY 1
140 # elif defined SPARC64
141 struct stat32 {
142         unsigned short  st_dev;
143         unsigned int    st_ino;
144         unsigned short  st_mode;
145         unsigned short  st_nlink;
146         unsigned short  st_uid;
147         unsigned short  st_gid;
148         unsigned short  st_rdev;
149         unsigned int    st_size;
150         unsigned int    st_atime;
151         unsigned int    st_atime_nsec;
152         unsigned int    st_mtime;
153         unsigned int    st_mtime_nsec;
154         unsigned int    st_ctime;
155         unsigned int    st_ctime_nsec;
156         unsigned int    st_blksize;
157         unsigned int    st_blocks;
158         unsigned int    __unused4[2];
159 };
160 #  define STAT32_PERSONALITY 0
161 # elif defined SPARC
162 #  /* no 64-bit personalities */
163 # elif defined TILE
164 #  /* no 32-bit stat */
165 # else
166 #  warning FIXME: check whether struct stat32 definition is needed for this architecture!
167 # endif /* X86_64 || X32 || POWERPC64 */
168 #endif /* SUPPORTED_PERSONALITIES > 1 */
169
170 #ifdef STAT32_PERSONALITY
171 # define DO_PRINTSTAT do_printstat32
172 # define STRUCT_STAT struct stat32
173 # undef HAVE_STRUCT_STAT_ST_FLAGS
174 # undef HAVE_STRUCT_STAT_ST_FSTYPE
175 # undef HAVE_STRUCT_STAT_ST_GEN
176 # include "printstat.h"
177
178 static void
179 printstat32(struct tcb *tcp, long addr)
180 {
181         struct stat32 statbuf;
182
183         if (umove(tcp, addr, &statbuf) < 0) {
184                 tprints("{...}");
185                 return;
186         }
187
188         do_printstat32(tcp, &statbuf);
189 }
190 #endif /* STAT32_PERSONALITY */
191
192 #if defined(SPARC) || defined(SPARC64)
193
194 struct solstat {
195         unsigned        st_dev;
196         unsigned int    st_pad1[3];     /* network id */
197         unsigned        st_ino;
198         unsigned        st_mode;
199         unsigned        st_nlink;
200         unsigned        st_uid;
201         unsigned        st_gid;
202         unsigned        st_rdev;
203         unsigned int    st_pad2[2];
204         unsigned int    st_size;
205         unsigned int    st_pad3;        /* st_size, off_t expansion */
206         unsigned int    st_atime;
207         unsigned int    st_atime_nsec;
208         unsigned int    st_mtime;
209         unsigned int    st_mtime_nsec;
210         unsigned int    st_ctime;
211         unsigned int    st_ctime_nsec;
212         unsigned int    st_blksize;
213         unsigned int    st_blocks;
214         char            st_fstype[16];
215         unsigned int    st_pad4[8];     /* expansion area */
216 };
217
218 # define DO_PRINTSTAT   do_printstat_sol
219 # define STRUCT_STAT    struct solstat
220 # define STAT_MAJOR(x)  (((x) >> 18) & 0x3fff)
221 # define STAT_MINOR(x)  ((x) & 0x3ffff)
222 # undef HAVE_STRUCT_STAT_ST_FLAGS
223 # undef HAVE_STRUCT_STAT_ST_FSTYPE
224 # undef HAVE_STRUCT_STAT_ST_GEN
225 # include "printstat.h"
226
227 static void
228 printstatsol(struct tcb *tcp, long addr)
229 {
230         struct solstat statbuf;
231
232         if (umove(tcp, addr, &statbuf) < 0) {
233                 tprints("{...}");
234                 return;
235         }
236
237         do_printstat_sol(tcp, &statbuf);
238 }
239
240 #endif /* SPARC || SPARC64 */
241
242 static void
243 printstat(struct tcb *tcp, long addr)
244 {
245         struct stat statbuf;
246
247         if (!addr) {
248                 tprints("NULL");
249                 return;
250         }
251         if (syserror(tcp) || !verbose(tcp)) {
252                 tprintf("%#lx", addr);
253                 return;
254         }
255
256 #ifdef STAT32_PERSONALITY
257         if (current_personality == STAT32_PERSONALITY) {
258                 printstat32(tcp, addr);
259                 return;
260         }
261 #endif
262
263 #if defined(SPARC) || defined(SPARC64)
264         if (current_personality == 1) {
265                 printstatsol(tcp, addr);
266                 return;
267         }
268 #endif /* SPARC || SPARC64 */
269
270         if (umove(tcp, addr, &statbuf) < 0) {
271                 tprints("{...}");
272                 return;
273         }
274
275         do_printstat(tcp, &statbuf);
276 }
277
278 int
279 sys_stat(struct tcb *tcp)
280 {
281         if (entering(tcp)) {
282                 printpath(tcp, tcp->u_arg[0]);
283                 tprints(", ");
284         } else {
285                 printstat(tcp, tcp->u_arg[1]);
286         }
287         return 0;
288 }
289
290 int
291 sys_fstat(struct tcb *tcp)
292 {
293         if (entering(tcp)) {
294                 printfd(tcp, tcp->u_arg[0]);
295                 tprints(", ");
296         } else {
297                 printstat(tcp, tcp->u_arg[1]);
298         }
299         return 0;
300 }
301
302 #if defined STAT32_PERSONALITY && !defined HAVE_STRUCT_STAT64
303 # if defined AARCH64 || defined X86_64 || defined X32
304 /*
305  * Linux x86_64 and x32 have unified `struct stat' but their i386 personality
306  * needs `struct stat64'.
307  * linux/arch/x86/include/uapi/asm/stat.h defines `struct stat64' only for i386.
308  * __GNUC__ is needed for the required __attribute__ below.
309  *
310  * Similarly, aarch64 has a unified `struct stat' but its arm personality
311  * needs `struct stat64' (unlike x86, it shouldn't be packed).
312  */
313 struct stat64 {
314         unsigned long long      st_dev;
315         unsigned char   __pad0[4];
316         unsigned int    __st_ino;
317         unsigned int    st_mode;
318         unsigned int    st_nlink;
319         unsigned int    st_uid;
320         unsigned int    st_gid;
321         unsigned long long      st_rdev;
322         unsigned char   __pad3[4];
323         long long       st_size;
324         unsigned int    st_blksize;
325         unsigned long long      st_blocks;
326         unsigned int    st_atime;
327         unsigned int    st_atime_nsec;
328         unsigned int    st_mtime;
329         unsigned int    st_mtime_nsec;
330         unsigned int    st_ctime;
331         unsigned int    st_ctime_nsec;
332         unsigned long long      st_ino;
333 }
334 #  if defined X86_64 || defined X32
335   __attribute__((packed))
336 #   define STAT64_SIZE  96
337 #  else
338 #   define STAT64_SIZE  104
339 #  endif
340 ;
341 #  define HAVE_STRUCT_STAT64    1
342 # else /* !(AARCH64 || X86_64 || X32) */
343 #  warning FIXME: check whether struct stat64 definition is needed for this architecture!
344 # endif
345 #endif /* STAT32_PERSONALITY && !HAVE_STRUCT_STAT64 */
346
347 #ifdef HAVE_STRUCT_STAT64
348
349 # define DO_PRINTSTAT do_printstat64
350 # define STRUCT_STAT struct stat64
351 # undef HAVE_STRUCT_STAT_ST_FLAGS
352 # undef HAVE_STRUCT_STAT_ST_FSTYPE
353 # undef HAVE_STRUCT_STAT_ST_GEN
354 # include "printstat.h"
355
356 static void
357 printstat64(struct tcb *tcp, long addr)
358 {
359         struct stat64 statbuf;
360
361 # ifdef STAT64_SIZE
362         (void) sizeof(char[sizeof statbuf == STAT64_SIZE ? 1 : -1]);
363 # endif
364
365         if (!addr) {
366                 tprints("NULL");
367                 return;
368         }
369         if (syserror(tcp) || !verbose(tcp)) {
370                 tprintf("%#lx", addr);
371                 return;
372         }
373
374 # ifdef STAT32_PERSONALITY
375         if (current_personality != STAT32_PERSONALITY) {
376                 printstat(tcp, addr);
377                 return;
378         }
379 # endif /* STAT32_PERSONALITY */
380
381         if (umove(tcp, addr, &statbuf) < 0) {
382                 tprints("{...}");
383                 return;
384         }
385
386         do_printstat64(tcp, &statbuf);
387 }
388
389 int
390 sys_stat64(struct tcb *tcp)
391 {
392         if (entering(tcp)) {
393                 printpath(tcp, tcp->u_arg[0]);
394                 tprints(", ");
395         } else {
396                 printstat64(tcp, tcp->u_arg[1]);
397         }
398         return 0;
399 }
400
401 int
402 sys_fstat64(struct tcb *tcp)
403 {
404         if (entering(tcp)) {
405                 printfd(tcp, tcp->u_arg[0]);
406                 tprints(", ");
407         } else {
408                 printstat64(tcp, tcp->u_arg[1]);
409         }
410         return 0;
411 }
412
413 #else
414
415 int
416 sys_stat64(struct tcb *tcp)
417 {
418         return sys_stat(tcp);
419 }
420
421 int
422 sys_fstat64(struct tcb *tcp)
423 {
424         return sys_fstat(tcp);
425 }
426
427 #endif /* HAVE_STRUCT_STAT64 */
428
429 int
430 sys_newfstatat(struct tcb *tcp)
431 {
432         if (entering(tcp)) {
433                 print_dirfd(tcp, tcp->u_arg[0]);
434                 printpath(tcp, tcp->u_arg[1]);
435                 tprints(", ");
436         } else {
437 #if defined STAT32_PERSONALITY
438                 if (current_personality == STAT32_PERSONALITY)
439                         printstat64(tcp, tcp->u_arg[2]);
440                 else
441                         printstat(tcp, tcp->u_arg[2]);
442 #elif defined HAVE_STRUCT_STAT64
443                 printstat64(tcp, tcp->u_arg[2]);
444 #else
445                 printstat(tcp, tcp->u_arg[2]);
446 #endif /* STAT32_PERSONALITY || HAVE_STRUCT_STAT64 */
447                 tprints(", ");
448                 printflags(at_flags, tcp->u_arg[3], "AT_???");
449         }
450         return 0;
451 }
452
453 #if defined(HAVE_STRUCT___OLD_KERNEL_STAT)
454
455 static void
456 convertoldstat(const struct __old_kernel_stat *oldbuf, struct stat *newbuf)
457 {
458         memset(newbuf, 0, sizeof(*newbuf));
459         newbuf->st_dev = oldbuf->st_dev;
460         newbuf->st_ino = oldbuf->st_ino;
461         newbuf->st_mode = oldbuf->st_mode;
462         newbuf->st_nlink = oldbuf->st_nlink;
463         newbuf->st_uid = oldbuf->st_uid;
464         newbuf->st_gid = oldbuf->st_gid;
465         newbuf->st_rdev = oldbuf->st_rdev;
466         newbuf->st_size = oldbuf->st_size;
467         newbuf->st_atime = oldbuf->st_atime;
468         newbuf->st_mtime = oldbuf->st_mtime;
469         newbuf->st_ctime = oldbuf->st_ctime;
470 }
471
472 static void
473 printoldstat(struct tcb *tcp, long addr)
474 {
475         struct __old_kernel_stat statbuf;
476         struct stat newstatbuf;
477
478         if (!addr) {
479                 tprints("NULL");
480                 return;
481         }
482         if (syserror(tcp) || !verbose(tcp)) {
483                 tprintf("%#lx", addr);
484                 return;
485         }
486
487 # if defined(SPARC) || defined(SPARC64)
488         if (current_personality == 1) {
489                 printstatsol(tcp, addr);
490                 return;
491         }
492 # endif
493
494         if (umove(tcp, addr, &statbuf) < 0) {
495                 tprints("{...}");
496                 return;
497         }
498
499         convertoldstat(&statbuf, &newstatbuf);
500         do_printstat(tcp, &newstatbuf);
501 }
502
503 int
504 sys_oldstat(struct tcb *tcp)
505 {
506         if (entering(tcp)) {
507                 printpath(tcp, tcp->u_arg[0]);
508                 tprints(", ");
509         } else {
510                 printoldstat(tcp, tcp->u_arg[1]);
511         }
512         return 0;
513 }
514
515 int
516 sys_oldfstat(struct tcb *tcp)
517 {
518         if (entering(tcp)) {
519                 printfd(tcp, tcp->u_arg[0]);
520                 tprints(", ");
521         } else {
522                 printoldstat(tcp, tcp->u_arg[1]);
523         }
524         return 0;
525 }
526
527 #endif /* HAVE_STRUCT___OLD_KERNEL_STAT */
528
529 #if defined(SPARC) || defined(SPARC64)
530
531 int
532 sys_xstat(struct tcb *tcp)
533 {
534         if (entering(tcp)) {
535                 tprintf("%ld, ", tcp->u_arg[0]);
536                 printpath(tcp, tcp->u_arg[1]);
537                 tprints(", ");
538         } else {
539                 printstat(tcp, tcp->u_arg[2]);
540         }
541         return 0;
542 }
543
544 int
545 sys_fxstat(struct tcb *tcp)
546 {
547         if (entering(tcp)) {
548                 tprintf("%ld, ", tcp->u_arg[0]);
549                 printfd(tcp, tcp->u_arg[1]);
550                 tprints(", ");
551         } else {
552                 printstat(tcp, tcp->u_arg[2]);
553         }
554         return 0;
555 }
556
557 #endif /* SPARC || SPARC64 */