1 /* 2 * Copyright (c) 1991, 1992 Paul Kranenburg <pk (at) cs.few.eur.nl> 3 * Copyright (c) 1993 Branko Lankester <branko (at) hacktic.nl> 4 * Copyright (c) 1993, 1994, 1995, 1996 Rick Sladkey <jrs (at) world.std.com> 5 * Copyright (c) 1996-1999 Wichert Akkerman <wichert (at) cistron.nl> 6 * Copyright (c) 2005-2007 Roland McGrath <roland (at) redhat.com> 7 * Copyright (c) 2006-2007 Ulrich Drepper <drepper (at) redhat.com> 8 * Copyright (c) 2009-2013 Denys Vlasenko <dvlasenk (at) redhat.com> 9 * Copyright (c) 2005-2015 Dmitry V. Levin <ldv (at) altlinux.org> 10 * Copyright (c) 2014-2018 The strace developers. 11 * All rights reserved. 12 * 13 * Redistribution and use in source and binary forms, with or without 14 * modification, are permitted provided that the following conditions 15 * are met: 16 * 1. Redistributions of source code must retain the above copyright 17 * notice, this list of conditions and the following disclaimer. 18 * 2. Redistributions in binary form must reproduce the above copyright 19 * notice, this list of conditions and the following disclaimer in the 20 * documentation and/or other materials provided with the distribution. 21 * 3. The name of the author may not be used to endorse or promote products 22 * derived from this software without specific prior written permission. 23 * 24 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 25 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 26 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 27 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 28 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 29 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 30 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 31 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 32 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 33 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 34 */ 35 36 #include "defs.h" 37 #include "xstring.h" 38 39 #include <asm/fcntl.h> 40 41 /* some libcs are guilty of messing up with O_ACCMODE */ 42 #undef O_ACCMODE 43 #define O_ACCMODE 03 44 45 #ifdef O_LARGEFILE 46 # if O_LARGEFILE == 0 /* biarch platforms in 64-bit mode */ 47 # undef O_LARGEFILE 48 # endif 49 #endif 50 51 #include "xlat/open_access_modes.h" 52 #include "xlat/open_mode_flags.h" 53 54 #ifndef AT_FDCWD 55 # define AT_FDCWD -100 56 #endif 57 58 /* The fd is an "int", so when decoding x86 on x86_64, we need to force sign 59 * extension to get the right value. We do this by declaring fd as int here. 60 */ 61 void 62 print_dirfd(struct tcb *tcp, int fd) 63 { 64 if (fd == AT_FDCWD) 65 tprints("AT_FDCWD, "); 66 else { 67 printfd(tcp, fd); 68 tprints(", "); 69 } 70 } 71 72 /* 73 * low bits of the open(2) flags define access mode, 74 * other bits are real flags. 75 */ 76 const char * 77 sprint_open_modes(unsigned int flags) 78 { 79 static char outstr[(1 + ARRAY_SIZE(open_mode_flags)) * sizeof("O_LARGEFILE")]; 80 char *p; 81 char sep; 82 const char *str; 83 const struct xlat *x; 84 85 sep = ' '; 86 p = stpcpy(outstr, "flags"); 87 str = xlookup(open_access_modes, flags & 3); 88 if (str) { 89 *p++ = sep; 90 p = stpcpy(p, str); 91 flags &= ~3; 92 if (!flags) 93 return outstr; 94 sep = '|'; 95 } 96 97 for (x = open_mode_flags; x->str; x++) { 98 if ((flags & x->val) == x->val) { 99 *p++ = sep; 100 p = stpcpy(p, x->str); 101 flags &= ~x->val; 102 if (!flags) 103 return outstr; 104 sep = '|'; 105 } 106 } 107 /* flags is still nonzero */ 108 *p++ = sep; 109 p = xappendstr(outstr, p, "%#x", flags); 110 return outstr; 111 } 112 113 void 114 tprint_open_modes(unsigned int flags) 115 { 116 tprints(sprint_open_modes(flags) + sizeof("flags")); 117 } 118 119 #ifdef O_TMPFILE 120 /* The kernel & C libraries often inline O_DIRECTORY. */ 121 # define STRACE_O_TMPFILE (O_TMPFILE & ~O_DIRECTORY) 122 #else /* !O_TMPFILE */ 123 # define STRACE_O_TMPFILE 0 124 #endif 125 126 static int 127 decode_open(struct tcb *tcp, int offset) 128 { 129 printpath(tcp, tcp->u_arg[offset]); 130 tprints(", "); 131 /* flags */ 132 tprint_open_modes(tcp->u_arg[offset + 1]); 133 if (tcp->u_arg[offset + 1] & (O_CREAT | STRACE_O_TMPFILE)) { 134 /* mode */ 135 tprints(", "); 136 print_numeric_umode_t(tcp->u_arg[offset + 2]); 137 } 138 139 return RVAL_DECODED | RVAL_FD; 140 } 141 142 SYS_FUNC(open) 143 { 144 return decode_open(tcp, 0); 145 } 146 147 SYS_FUNC(openat) 148 { 149 print_dirfd(tcp, tcp->u_arg[0]); 150 return decode_open(tcp, 1); 151 } 152 153 SYS_FUNC(creat) 154 { 155 printpath(tcp, tcp->u_arg[0]); 156 tprints(", "); 157 print_numeric_umode_t(tcp->u_arg[1]); 158 159 return RVAL_DECODED | RVAL_FD; 160 } 161