Home | History | Annotate | Download | only in strace
      1 /*
      2  * Copyright (c) 2015 Dmitry V. Levin <ldv (at) altlinux.org>
      3  * Copyright (c) 2015-2017 The strace developers.
      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 "xlat/name_to_handle_at_flags.h"
     32 
     33 #ifndef MAX_HANDLE_SZ
     34 # define MAX_HANDLE_SZ 128
     35 #endif
     36 
     37 typedef struct {
     38 	unsigned int handle_bytes;
     39 	int handle_type;
     40 } file_handle_header;
     41 
     42 SYS_FUNC(name_to_handle_at)
     43 {
     44 	file_handle_header h;
     45 	const kernel_ulong_t addr = tcp->u_arg[2];
     46 
     47 	if (entering(tcp)) {
     48 		/* dirfd */
     49 		print_dirfd(tcp, tcp->u_arg[0]);
     50 
     51 		/* pathname */
     52 		printpath(tcp, tcp->u_arg[1]);
     53 		tprints(", ");
     54 
     55 		/* handle */
     56 		if (umove_or_printaddr(tcp, addr, &h)) {
     57 			tprints(", ");
     58 
     59 			/* mount_id */
     60 			printaddr(tcp->u_arg[3]);
     61 			tprints(", ");
     62 
     63 			/* flags */
     64 			printflags(name_to_handle_at_flags, tcp->u_arg[4],
     65 				   "AT_???");
     66 
     67 			return RVAL_DECODED;
     68 		}
     69 		tprintf("{handle_bytes=%u", h.handle_bytes);
     70 
     71 		set_tcb_priv_ulong(tcp, h.handle_bytes);
     72 
     73 		return 0;
     74 	} else {
     75 		unsigned int i = get_tcb_priv_ulong(tcp);
     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 
     97 		/* mount_id */
     98 		printnum_int(tcp, tcp->u_arg[3], "%d");
     99 		tprints(", ");
    100 
    101 		/* flags */
    102 		printflags(name_to_handle_at_flags, tcp->u_arg[4], "AT_???");
    103 	}
    104 	return 0;
    105 }
    106 
    107 SYS_FUNC(open_by_handle_at)
    108 {
    109 	file_handle_header h;
    110 	const kernel_ulong_t addr = tcp->u_arg[1];
    111 
    112 	/* mount_fd */
    113 	printfd(tcp, tcp->u_arg[0]);
    114 	tprints(", ");
    115 
    116 	/* handle */
    117 	if (!umove_or_printaddr(tcp, addr, &h)) {
    118 		unsigned char f_handle[MAX_HANDLE_SZ];
    119 
    120 		tprintf("{handle_bytes=%u, handle_type=%d",
    121 			h.handle_bytes, h.handle_type);
    122 		if (h.handle_bytes > MAX_HANDLE_SZ)
    123 			h.handle_bytes = MAX_HANDLE_SZ;
    124 		if (!umoven(tcp, addr + sizeof(h), h.handle_bytes, &f_handle)) {
    125 			unsigned int i;
    126 
    127 			tprints(", f_handle=0x");
    128 			for (i = 0; i < h.handle_bytes; ++i)
    129 				tprintf("%02x", f_handle[i]);
    130 		}
    131 		tprints("}");
    132 	}
    133 	tprints(", ");
    134 
    135 	/* flags */
    136 	tprint_open_modes(tcp->u_arg[2]);
    137 
    138 	return RVAL_DECODED;
    139 }
    140