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