Home | History | Annotate | Download | only in strace
      1 /*
      2  * Copyright (c) 2014-2015 Dmitry V. Levin <ldv (at) altlinux.org>
      3  * Copyright (c) 2014-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 "keyctl_kdf_params.h"
     32 #include "print_fields.h"
     33 
     34 typedef int32_t key_serial_t;
     35 
     36 #include "xlat/key_spec.h"
     37 
     38 struct keyctl_dh_params {
     39 	int32_t private;
     40 	int32_t prime;
     41 	int32_t base;
     42 };
     43 
     44 static void
     45 print_keyring_serial_number(key_serial_t id)
     46 {
     47 	const char *str = xlookup(key_spec, (unsigned int) id);
     48 
     49 	if (str)
     50 		tprints(str);
     51 	else
     52 		tprintf("%d", id);
     53 }
     54 
     55 SYS_FUNC(add_key)
     56 {
     57 	/* type */
     58 	printstr(tcp, tcp->u_arg[0]);
     59 	/* description */
     60 	tprints(", ");
     61 	printstr(tcp, tcp->u_arg[1]);
     62 	/* payload */
     63 	tprints(", ");
     64 	printstrn(tcp, tcp->u_arg[2], tcp->u_arg[3]);
     65 	/* payload length */
     66 	tprintf(", %" PRI_klu ", ", tcp->u_arg[3]);
     67 	/* keyring serial number */
     68 	print_keyring_serial_number(tcp->u_arg[4]);
     69 
     70 	return RVAL_DECODED;
     71 }
     72 
     73 SYS_FUNC(request_key)
     74 {
     75 	/* type */
     76 	printstr(tcp, tcp->u_arg[0]);
     77 	/* description */
     78 	tprints(", ");
     79 	printstr(tcp, tcp->u_arg[1]);
     80 	/* callout_info */
     81 	tprints(", ");
     82 	printstr(tcp, tcp->u_arg[2]);
     83 	/* keyring serial number */
     84 	tprints(", ");
     85 	print_keyring_serial_number(tcp->u_arg[3]);
     86 
     87 	return RVAL_DECODED;
     88 }
     89 
     90 static void
     91 keyctl_get_keyring_id(struct tcb *tcp, key_serial_t id, int create)
     92 {
     93 	print_keyring_serial_number(id);
     94 	tprintf(", %d", create);
     95 }
     96 
     97 static void
     98 keyctl_update_key(struct tcb *tcp, key_serial_t id, kernel_ulong_t addr,
     99 		  kernel_ulong_t len)
    100 {
    101 	print_keyring_serial_number(id);
    102 	tprints(", ");
    103 	printstrn(tcp, addr, len);
    104 	tprintf(", %llu", zero_extend_signed_to_ull(len));
    105 }
    106 
    107 static void
    108 keyctl_handle_key_key(struct tcb *tcp, key_serial_t id1, key_serial_t id2)
    109 {
    110 	print_keyring_serial_number(id1);
    111 	tprints(", ");
    112 	print_keyring_serial_number(id2);
    113 }
    114 
    115 static void
    116 keyctl_read_key(struct tcb *tcp, key_serial_t id, kernel_ulong_t addr,
    117 		kernel_ulong_t len, bool has_nul)
    118 {
    119 	if (entering(tcp)) {
    120 		print_keyring_serial_number(id);
    121 		tprints(", ");
    122 	} else {
    123 		if (syserror(tcp))
    124 			printaddr(addr);
    125 		else {
    126 			kernel_ulong_t rval = (tcp->u_rval >= 0) &&
    127 				((kernel_ulong_t) tcp->u_rval > len) ? len :
    128 				(kernel_ulong_t) tcp->u_rval;
    129 			printstr_ex(tcp, addr, rval, has_nul ?
    130 				    QUOTE_OMIT_TRAILING_0 : 0);
    131 		}
    132 		tprintf(", %llu", zero_extend_signed_to_ull(len));
    133 	}
    134 }
    135 
    136 static void
    137 keyctl_keyring_search(struct tcb *tcp, key_serial_t id1, kernel_ulong_t addr1,
    138 		      kernel_ulong_t addr2, key_serial_t id2)
    139 {
    140 	print_keyring_serial_number(id1);
    141 	tprints(", ");
    142 	printstr(tcp, addr1);
    143 	tprints(", ");
    144 	printstr(tcp, addr2);
    145 	tprints(", ");
    146 	print_keyring_serial_number(id2);
    147 }
    148 
    149 static void
    150 keyctl_chown_key(struct tcb *tcp, key_serial_t id, unsigned user,
    151 		 unsigned group)
    152 {
    153 	print_keyring_serial_number(id);
    154 	printuid(", ", user);
    155 	printuid(", ", group);
    156 }
    157 
    158 static void
    159 keyctl_instantiate_key(struct tcb *tcp, key_serial_t id1, kernel_ulong_t addr,
    160 		       kernel_ulong_t len, key_serial_t id2)
    161 {
    162 	print_keyring_serial_number(id1);
    163 	tprints(", ");
    164 	printstrn(tcp, addr, len);
    165 	tprintf(", %llu, ", zero_extend_signed_to_ull(len));
    166 	print_keyring_serial_number(id2);
    167 }
    168 
    169 static void
    170 keyctl_instantiate_key_iov(struct tcb *tcp, key_serial_t id1,
    171 			   kernel_ulong_t addr, kernel_ulong_t len,
    172 			   key_serial_t id2)
    173 {
    174 	print_keyring_serial_number(id1);
    175 	tprints(", ");
    176 	tprint_iov(tcp, len, addr, IOV_DECODE_STR);
    177 	tprintf(", %llu, ", zero_extend_signed_to_ull(len));
    178 	print_keyring_serial_number(id2);
    179 }
    180 
    181 static void
    182 keyctl_negate_key(struct tcb *tcp, key_serial_t id1, unsigned timeout,
    183 		  key_serial_t id2)
    184 {
    185 	print_keyring_serial_number(id1);
    186 	tprintf(", %u, ", timeout);
    187 	print_keyring_serial_number(id2);
    188 }
    189 
    190 static void
    191 keyctl_reject_key(struct tcb *tcp, key_serial_t id1, unsigned timeout,
    192 		  unsigned error, key_serial_t id2)
    193 {
    194 	const char *err_str = err_name(error);
    195 
    196 	print_keyring_serial_number(id1);
    197 	tprintf(", %u, ", timeout);
    198 
    199 	if (err_str)
    200 		tprintf("%s, ", err_str);
    201 	else
    202 		tprintf("%u, ", error);
    203 
    204 	print_keyring_serial_number(id2);
    205 }
    206 
    207 static void
    208 keyctl_set_timeout(struct tcb *tcp, key_serial_t id, unsigned timeout)
    209 {
    210 	print_keyring_serial_number(id);
    211 	tprintf(", %u", timeout);
    212 }
    213 
    214 static void
    215 keyctl_get_persistent(struct tcb *tcp, unsigned uid, key_serial_t id)
    216 {
    217 	printuid("", uid);
    218 	tprints(", ");
    219 	print_keyring_serial_number(id);
    220 }
    221 
    222 #include "xlat/key_perms.h"
    223 
    224 static void
    225 keyctl_setperm_key(struct tcb *tcp, key_serial_t id, uint32_t perm)
    226 {
    227 	print_keyring_serial_number(id);
    228 	tprints(", ");
    229 	printflags(key_perms, perm, "KEY_???");
    230 }
    231 
    232 static void
    233 print_dh_params(struct tcb *tcp, kernel_ulong_t addr)
    234 {
    235 	struct keyctl_dh_params params;
    236 
    237 	if (umove_or_printaddr(tcp, addr, &params))
    238 		return;
    239 
    240 	tprints("{private=");
    241 	print_keyring_serial_number(params.private);
    242 	tprints(", prime=");
    243 	print_keyring_serial_number(params.prime);
    244 	tprints(", base=");
    245 	print_keyring_serial_number(params.base);
    246 	tprints("}");
    247 }
    248 
    249 static void
    250 keyctl_dh_compute(struct tcb *tcp, kernel_ulong_t params, kernel_ulong_t buf,
    251 		  kernel_ulong_t len, kernel_ulong_t kdf_addr)
    252 {
    253 	if (entering(tcp)) {
    254 		print_dh_params(tcp, params);
    255 		tprints(", ");
    256 	} else {
    257 		struct strace_keyctl_kdf_params kdf;
    258 
    259 		if (syserror(tcp)) {
    260 			printaddr(buf);
    261 		} else {
    262 			kernel_ulong_t rval = (tcp->u_rval >= 0) &&
    263 				((kernel_ulong_t) tcp->u_rval > len) ? len :
    264 				(kernel_ulong_t) tcp->u_rval;
    265 			printstrn(tcp, buf, rval);
    266 		}
    267 		tprintf(", %llu, ", zero_extend_signed_to_ull(len));
    268 
    269 		if (fetch_keyctl_kdf_params(tcp, kdf_addr, &kdf)) {
    270 			printaddr(kdf_addr);
    271 		} else {
    272 			size_t i;
    273 
    274 			PRINT_FIELD_STR("{", kdf, hashname, tcp);
    275 
    276 			/*
    277 			 * Kernel doesn't touch otherinfo
    278 			 * if otherinfolen is zero.
    279 			 */
    280 			if (kdf.otherinfolen)
    281 				PRINT_FIELD_STRN(", ", kdf, otherinfo,
    282 						 kdf.otherinfolen, tcp);
    283 			else
    284 				PRINT_FIELD_PTR(", ", kdf, otherinfo);
    285 
    286 			PRINT_FIELD_U(", ", kdf, otherinfolen);
    287 
    288 			/* Some future-proofing */
    289 			for (i = 0; i < ARRAY_SIZE(kdf.__spare); i++) {
    290 				if (kdf.__spare[i])
    291 					break;
    292 			}
    293 
    294 			if (i < ARRAY_SIZE(kdf.__spare)) {
    295 				tprints(", __spare=[");
    296 
    297 				for (i = 0; i < ARRAY_SIZE(kdf.__spare); i++) {
    298 					if (i)
    299 						tprints(", ");
    300 
    301 					tprintf("%#x", kdf.__spare[i]);
    302 				}
    303 
    304 				tprints("]");
    305 			}
    306 
    307 			tprints("}");
    308 		}
    309 	}
    310 }
    311 
    312 static void
    313 keyctl_restrict_keyring(struct tcb *const tcp,
    314 			const key_serial_t id,
    315 			const kernel_ulong_t addr1,
    316 			const kernel_ulong_t addr2)
    317 {
    318 	print_keyring_serial_number(id);
    319 	tprints(", ");
    320 	printstr(tcp, addr1);
    321 	tprints(", ");
    322 	printstr(tcp, addr2);
    323 }
    324 
    325 #include "xlat/key_reqkeys.h"
    326 #include "xlat/keyctl_commands.h"
    327 
    328 SYS_FUNC(keyctl)
    329 {
    330 	int cmd = tcp->u_arg[0];
    331 	kernel_ulong_t arg2 = tcp->u_arg[1];
    332 	kernel_ulong_t arg3 = tcp->u_arg[2];
    333 	kernel_ulong_t arg4 = tcp->u_arg[3];
    334 	kernel_ulong_t arg5 = tcp->u_arg[4];
    335 
    336 	if (entering(tcp)) {
    337 		printxval(keyctl_commands, cmd, "KEYCTL_???");
    338 
    339 		/*
    340 		 * For now, KEYCTL_SESSION_TO_PARENT is the only cmd without
    341 		 * arguments.
    342 		 */
    343 		if (cmd != KEYCTL_SESSION_TO_PARENT)
    344 			tprints(", ");
    345 	}
    346 
    347 	switch (cmd) {
    348 	case KEYCTL_GET_KEYRING_ID:
    349 		keyctl_get_keyring_id(tcp, arg2, arg3);
    350 		break;
    351 
    352 	case KEYCTL_JOIN_SESSION_KEYRING:
    353 		printstr(tcp, arg2);
    354 		break;
    355 
    356 	case KEYCTL_UPDATE:
    357 		keyctl_update_key(tcp, arg2, arg3, arg4);
    358 		break;
    359 
    360 	case KEYCTL_REVOKE:
    361 	case KEYCTL_CLEAR:
    362 	case KEYCTL_INVALIDATE:
    363 	case KEYCTL_ASSUME_AUTHORITY:
    364 		print_keyring_serial_number(arg2);
    365 		break;
    366 
    367 	case KEYCTL_LINK:
    368 	case KEYCTL_UNLINK:
    369 		keyctl_handle_key_key(tcp, arg2, arg3);
    370 		break;
    371 
    372 	case KEYCTL_DESCRIBE:
    373 	case KEYCTL_READ:
    374 	case KEYCTL_GET_SECURITY:
    375 		keyctl_read_key(tcp, arg2, arg3, arg4, cmd != KEYCTL_READ);
    376 		return 0;
    377 
    378 	case KEYCTL_SEARCH:
    379 		keyctl_keyring_search(tcp, arg2, arg3, arg4, arg5);
    380 		break;
    381 
    382 	case KEYCTL_CHOWN:
    383 		keyctl_chown_key(tcp, arg2, arg3, arg4);
    384 		break;
    385 
    386 	case KEYCTL_SETPERM:
    387 		keyctl_setperm_key(tcp, arg2, arg3);
    388 		break;
    389 
    390 	case KEYCTL_INSTANTIATE:
    391 		keyctl_instantiate_key(tcp, arg2, arg3, arg4, arg5);
    392 		break;
    393 
    394 	case KEYCTL_NEGATE:
    395 		keyctl_negate_key(tcp, arg2, arg3, arg4);
    396 		break;
    397 
    398 	case KEYCTL_SET_REQKEY_KEYRING:
    399 		printxval(key_reqkeys, arg2, "KEY_REQKEY_DEFL_???");
    400 		break;
    401 
    402 	case KEYCTL_SET_TIMEOUT:
    403 		keyctl_set_timeout(tcp, arg2, arg3);
    404 		break;
    405 
    406 	case KEYCTL_SESSION_TO_PARENT:
    407 		break;
    408 
    409 	case KEYCTL_REJECT:
    410 		keyctl_reject_key(tcp, arg2, arg3, arg4, arg5);
    411 		break;
    412 
    413 	case KEYCTL_INSTANTIATE_IOV:
    414 		keyctl_instantiate_key_iov(tcp, arg2, arg3, arg4, arg5);
    415 		break;
    416 
    417 	case KEYCTL_GET_PERSISTENT:
    418 		keyctl_get_persistent(tcp, arg2, arg3);
    419 		break;
    420 
    421 	case KEYCTL_DH_COMPUTE:
    422 		keyctl_dh_compute(tcp, arg2, arg3, arg4, arg5);
    423 		return 0;
    424 
    425 	case KEYCTL_RESTRICT_KEYRING:
    426 		keyctl_restrict_keyring(tcp, arg2, arg3, arg4);
    427 		break;
    428 
    429 	default:
    430 		tprintf("%#" PRI_klx ", %#" PRI_klx
    431 			", %#" PRI_klx ", %#" PRI_klx,
    432 			arg2, arg3, arg4, arg5);
    433 		break;
    434 	}
    435 
    436 	return RVAL_DECODED;
    437 }
    438