Home | History | Annotate | Download | only in strace
      1 /*
      2  * Copyright (c) 2014-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 typedef int32_t key_serial_t;
     31 
     32 #include "xlat/key_spec.h"
     33 
     34 static void
     35 print_keyring_serial_number(key_serial_t id)
     36 {
     37 	const char *str = xlookup(key_spec, id);
     38 
     39 	if (str)
     40 		tprints(str);
     41 	else
     42 		tprintf("%d", id);
     43 }
     44 
     45 SYS_FUNC(add_key)
     46 {
     47 	/* type */
     48 	printstr(tcp, tcp->u_arg[0], -1);
     49 	/* description */
     50 	tprints(", ");
     51 	printstr(tcp, tcp->u_arg[1], -1);
     52 	/* payload */
     53 	tprints(", ");
     54 	printstr(tcp, tcp->u_arg[2], tcp->u_arg[3]);
     55 	/* payload length */
     56 	tprintf(", %lu, ", tcp->u_arg[3]);
     57 	/* keyring serial number */
     58 	print_keyring_serial_number(tcp->u_arg[4]);
     59 
     60 	return RVAL_DECODED;
     61 }
     62 
     63 SYS_FUNC(request_key)
     64 {
     65 	/* type */
     66 	printstr(tcp, tcp->u_arg[0], -1);
     67 	/* description */
     68 	tprints(", ");
     69 	printstr(tcp, tcp->u_arg[1], -1);
     70 	/* callout_info */
     71 	tprints(", ");
     72 	printstr(tcp, tcp->u_arg[2], -1);
     73 	/* keyring serial number */
     74 	tprints(", ");
     75 	print_keyring_serial_number(tcp->u_arg[3]);
     76 
     77 	return RVAL_DECODED;
     78 }
     79 
     80 static void
     81 keyctl_get_keyring_id(struct tcb *tcp, key_serial_t id, int create)
     82 {
     83 	print_keyring_serial_number(id);
     84 	tprintf(", %d", create);
     85 }
     86 
     87 static void
     88 keyctl_update_key(struct tcb *tcp, key_serial_t id, long addr, long len)
     89 {
     90 	print_keyring_serial_number(id);
     91 	tprints(", ");
     92 	printstr(tcp, addr, len);
     93 	tprintf(", %lu", len);
     94 }
     95 
     96 static void
     97 keyctl_handle_key_key(struct tcb *tcp, key_serial_t id1, key_serial_t id2)
     98 {
     99 	print_keyring_serial_number(id1);
    100 	tprints(", ");
    101 	print_keyring_serial_number(id2);
    102 }
    103 
    104 static void
    105 keyctl_read_key(struct tcb *tcp, key_serial_t id, long addr, long len)
    106 {
    107 	if (entering(tcp)) {
    108 		print_keyring_serial_number(id);
    109 		tprints(", ");
    110 	} else {
    111 		if (syserror(tcp))
    112 			printaddr(addr);
    113 		else {
    114 			long rval = tcp->u_rval > len ?
    115 				    len : (tcp->u_rval ? -1 : 0);
    116 			printstr(tcp, addr, rval);
    117 		}
    118 		tprintf(", %lu", len);
    119 	}
    120 }
    121 
    122 static void
    123 keyctl_keyring_search(struct tcb *tcp, key_serial_t id1, long addr1,
    124 		      long addr2, key_serial_t id2)
    125 {
    126 	print_keyring_serial_number(id1);
    127 	tprints(", ");
    128 	printstr(tcp, addr1, -1);
    129 	tprints(", ");
    130 	printstr(tcp, addr2, -1);
    131 	tprints(", ");
    132 	print_keyring_serial_number(id2);
    133 }
    134 
    135 static void
    136 keyctl_chown_key(struct tcb *tcp, key_serial_t id, int user, int group)
    137 {
    138 	print_keyring_serial_number(id);
    139 	tprintf(", %d, %d", user, group);
    140 }
    141 
    142 static void
    143 keyctl_instantiate_key(struct tcb *tcp, key_serial_t id1, long addr,
    144 		       long len, key_serial_t id2)
    145 {
    146 	print_keyring_serial_number(id1);
    147 	tprints(", ");
    148 	printstr(tcp, addr, len);
    149 	tprintf(", %lu, ", len);
    150 	print_keyring_serial_number(id2);
    151 }
    152 
    153 static void
    154 keyctl_instantiate_key_iov(struct tcb *tcp, key_serial_t id1,
    155 			   long addr, long len, key_serial_t id2)
    156 {
    157 	print_keyring_serial_number(id1);
    158 	tprints(", ");
    159 	tprint_iov(tcp, len, addr, 1);
    160 	tprintf(", %lu, ", len);
    161 	print_keyring_serial_number(id2);
    162 }
    163 
    164 static void
    165 keyctl_negate_key(struct tcb *tcp, key_serial_t id1, unsigned timeout,
    166 		  key_serial_t id2)
    167 {
    168 	print_keyring_serial_number(id1);
    169 	tprintf(", %u, ", timeout);
    170 	print_keyring_serial_number(id2);
    171 }
    172 
    173 static void
    174 keyctl_reject_key(struct tcb *tcp, key_serial_t id1, unsigned timeout,
    175 		  unsigned error, key_serial_t id2)
    176 {
    177 	print_keyring_serial_number(id1);
    178 	tprintf(", %u, %u, ", timeout, error);
    179 	print_keyring_serial_number(id2);
    180 }
    181 
    182 static void
    183 keyctl_set_timeout(struct tcb *tcp, key_serial_t id, unsigned timeout)
    184 {
    185 	print_keyring_serial_number(id);
    186 	tprintf(", %u", timeout);
    187 }
    188 
    189 static void
    190 keyctl_get_persistent(struct tcb *tcp, int uid, key_serial_t id)
    191 {
    192 	tprintf("%d, ", uid);
    193 	print_keyring_serial_number(id);
    194 }
    195 
    196 #include "xlat/key_perms.h"
    197 
    198 static void
    199 keyctl_setperm_key(struct tcb *tcp, key_serial_t id, uint32_t perm)
    200 {
    201 	print_keyring_serial_number(id);
    202 	tprints(", ");
    203 	printflags(key_perms, perm, "KEY_???");
    204 }
    205 
    206 #include "xlat/key_reqkeys.h"
    207 #include "xlat/keyctl_commands.h"
    208 
    209 SYS_FUNC(keyctl)
    210 {
    211 	int cmd = tcp->u_arg[0];
    212 
    213 	if (entering(tcp)) {
    214 		printxval(keyctl_commands, cmd, "KEYCTL_???");
    215 		tprints(", ");
    216 	}
    217 
    218 	switch (cmd) {
    219 	case KEYCTL_GET_KEYRING_ID:
    220 		keyctl_get_keyring_id(tcp, tcp->u_arg[1], tcp->u_arg[2]);
    221 		break;
    222 
    223 	case KEYCTL_JOIN_SESSION_KEYRING:
    224 		printstr(tcp, tcp->u_arg[1], -1);
    225 		break;
    226 
    227 	case KEYCTL_UPDATE:
    228 		keyctl_update_key(tcp, tcp->u_arg[1],
    229 				  tcp->u_arg[2], tcp->u_arg[3]);
    230 		break;
    231 
    232 	case KEYCTL_REVOKE:
    233 	case KEYCTL_CLEAR:
    234 	case KEYCTL_INVALIDATE:
    235 	case KEYCTL_ASSUME_AUTHORITY:
    236 		print_keyring_serial_number(tcp->u_arg[1]);
    237 		break;
    238 
    239 	case KEYCTL_LINK:
    240 	case KEYCTL_UNLINK:
    241 		keyctl_handle_key_key(tcp, tcp->u_arg[1], tcp->u_arg[2]);
    242 		break;
    243 
    244 	case KEYCTL_DESCRIBE:
    245 	case KEYCTL_READ:
    246 	case KEYCTL_GET_SECURITY:
    247 		keyctl_read_key(tcp, tcp->u_arg[1],
    248 				tcp->u_arg[2], tcp->u_arg[3]);
    249 		return 0;
    250 
    251 	case KEYCTL_SEARCH:
    252 		keyctl_keyring_search(tcp, tcp->u_arg[1], tcp->u_arg[2],
    253 				      tcp->u_arg[3], tcp->u_arg[4]);
    254 		break;
    255 
    256 	case KEYCTL_CHOWN:
    257 		keyctl_chown_key(tcp, tcp->u_arg[1],
    258 				 tcp->u_arg[2], tcp->u_arg[3]);
    259 		break;
    260 
    261 	case KEYCTL_SETPERM:
    262 		keyctl_setperm_key(tcp, tcp->u_arg[1], tcp->u_arg[2]);
    263 		break;
    264 
    265 	case KEYCTL_INSTANTIATE:
    266 		keyctl_instantiate_key(tcp, tcp->u_arg[1], tcp->u_arg[2],
    267 				       tcp->u_arg[3], tcp->u_arg[4]);
    268 		break;
    269 
    270 	case KEYCTL_NEGATE:
    271 		keyctl_negate_key(tcp, tcp->u_arg[1],
    272 				  tcp->u_arg[2], tcp->u_arg[3]);
    273 		break;
    274 
    275 	case KEYCTL_SET_REQKEY_KEYRING:
    276 		printxval(key_reqkeys, tcp->u_arg[1], "KEY_REQKEY_DEFL_???");
    277 		break;
    278 
    279 	case KEYCTL_SET_TIMEOUT:
    280 		keyctl_set_timeout(tcp, tcp->u_arg[1], tcp->u_arg[2]);
    281 		break;
    282 
    283 	case KEYCTL_SESSION_TO_PARENT:
    284 		break;
    285 
    286 	case KEYCTL_REJECT:
    287 		keyctl_reject_key(tcp, tcp->u_arg[1], tcp->u_arg[2],
    288 				  tcp->u_arg[3], tcp->u_arg[4]);
    289 		break;
    290 
    291 	case KEYCTL_INSTANTIATE_IOV:
    292 		keyctl_instantiate_key_iov(tcp, tcp->u_arg[1],
    293 					   tcp->u_arg[2], tcp->u_arg[3],
    294 					   tcp->u_arg[4]);
    295 		break;
    296 
    297 	case KEYCTL_GET_PERSISTENT:
    298 		keyctl_get_persistent(tcp, tcp->u_arg[1], tcp->u_arg[2]);
    299 		break;
    300 
    301 	default:
    302 		tprintf("%#lx, %#lx, %#lx, %#lx",
    303 			tcp->u_arg[1], tcp->u_arg[2],
    304 			tcp->u_arg[3], tcp->u_arg[4]);
    305 		break;
    306 	}
    307 
    308 	return RVAL_DECODED;
    309 }
    310