1 /* 2 * Copyright (c) 2015 Dmitry V. Levin <ldv (at) altlinux.org> 3 * All rights reserved. 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 30 #ifndef MAX_HANDLE_SZ 31 # define MAX_HANDLE_SZ 128 32 #endif 33 34 typedef struct { 35 unsigned int handle_bytes; 36 int handle_type; 37 } file_handle_header; 38 39 SYS_FUNC(name_to_handle_at) 40 { 41 file_handle_header h; 42 const long addr = tcp->u_arg[2]; 43 44 if (entering(tcp)) { 45 /* dirfd */ 46 print_dirfd(tcp, tcp->u_arg[0]); 47 48 /* pathname */ 49 printpath(tcp, tcp->u_arg[1]); 50 tprints(", "); 51 52 /* handle */ 53 if (umove_or_printaddr(tcp, addr, &h)) { 54 tprints(", "); 55 56 /* mount_id */ 57 printaddr(tcp->u_arg[3]); 58 tprints(", "); 59 60 /* flags */ 61 printflags(at_flags, tcp->u_arg[4], "AT_???"); 62 63 return RVAL_DECODED; 64 } 65 tprintf("{handle_bytes=%u", h.handle_bytes); 66 67 /* 68 * Abusing tcp->auxstr as a temporary storage. 69 * Will be used and cleared on syscall exit. 70 */ 71 tcp->auxstr = (void *) (unsigned long) h.handle_bytes; 72 73 return 0; 74 } else { 75 unsigned int i = (unsigned long) tcp->auxstr; 76 77 if ((!syserror(tcp) || EOVERFLOW == tcp->u_error) 78 && !umove(tcp, addr, &h)) { 79 unsigned char f_handle[MAX_HANDLE_SZ]; 80 81 if (i != h.handle_bytes) 82 tprintf(" => %u", h.handle_bytes); 83 if (!syserror(tcp)) { 84 tprintf(", handle_type=%d", h.handle_type); 85 if (h.handle_bytes > MAX_HANDLE_SZ) 86 h.handle_bytes = MAX_HANDLE_SZ; 87 if (!umoven(tcp, addr + sizeof(h), h.handle_bytes, 88 f_handle)) { 89 tprints(", f_handle=0x"); 90 for (i = 0; i < h.handle_bytes; ++i) 91 tprintf("%02x", f_handle[i]); 92 } 93 } 94 } 95 tprints("}, "); 96 tcp->auxstr = NULL; 97 98 /* mount_id */ 99 printnum_int(tcp, tcp->u_arg[3], "%d"); 100 tprints(", "); 101 102 /* flags */ 103 printflags(at_flags, tcp->u_arg[4], "AT_???"); 104 } 105 return 0; 106 } 107 108 SYS_FUNC(open_by_handle_at) 109 { 110 file_handle_header h; 111 const long addr = tcp->u_arg[1]; 112 113 /* mount_fd */ 114 printfd(tcp, tcp->u_arg[0]); 115 tprints(", "); 116 117 /* handle */ 118 if (!umove_or_printaddr(tcp, addr, &h)) { 119 unsigned char f_handle[MAX_HANDLE_SZ]; 120 121 tprintf("{handle_bytes=%u, handle_type=%d", 122 h.handle_bytes, h.handle_type); 123 if (h.handle_bytes > MAX_HANDLE_SZ) 124 h.handle_bytes = MAX_HANDLE_SZ; 125 if (!umoven(tcp, addr + sizeof(h), h.handle_bytes, &f_handle)) { 126 unsigned int i; 127 128 tprints(", f_handle=0x"); 129 for (i = 0; i < h.handle_bytes; ++i) 130 tprintf("%02x", f_handle[i]); 131 } 132 tprints("}"); 133 } 134 tprints(", "); 135 136 /* flags */ 137 tprint_open_modes(tcp->u_arg[2]); 138 139 return RVAL_DECODED; 140 } 141