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