(root)/
strace-6.5/
src/
keyctl.c
       1  /*
       2   * Copyright (c) 2014-2015 Dmitry V. Levin <ldv@strace.io>
       3   * Copyright (c) 2014-2021 The strace developers.
       4   * All rights reserved.
       5   *
       6   * SPDX-License-Identifier: LGPL-2.1-or-later
       7   */
       8  
       9  #include "defs.h"
      10  
      11  #include "keyctl_kdf_params.h"
      12  
      13  #include "xlat/key_perms.h"
      14  #include "xlat/key_reqkeys.h"
      15  #include "xlat/key_spec.h"
      16  #include "xlat/keyctl_caps0.h"
      17  #include "xlat/keyctl_caps1.h"
      18  #include "xlat/keyctl_commands.h"
      19  #include "xlat/keyctl_move_flags.h"
      20  #include "xlat/keyctl_pkey_ops.h"
      21  
      22  typedef int32_t key_serial_t;
      23  
      24  static void
      25  print_keyring_serial_number(key_serial_t id)
      26  {
      27  	printxval_d(key_spec, id, NULL);
      28  }
      29  
      30  SYS_FUNC(add_key)
      31  {
      32  	/* type */
      33  	printstr(tcp, tcp->u_arg[0]);
      34  	tprint_arg_next();
      35  
      36  	/* description */
      37  	printstr(tcp, tcp->u_arg[1]);
      38  	tprint_arg_next();
      39  
      40  	/* payload */
      41  	printstrn(tcp, tcp->u_arg[2], tcp->u_arg[3]);
      42  	tprint_arg_next();
      43  
      44  	/* payload length */
      45  	PRINT_VAL_U(tcp->u_arg[3]);
      46  	tprint_arg_next();
      47  
      48  	/* keyring serial number */
      49  	print_keyring_serial_number(tcp->u_arg[4]);
      50  
      51  	return RVAL_DECODED;
      52  }
      53  
      54  SYS_FUNC(request_key)
      55  {
      56  	/* type */
      57  	printstr(tcp, tcp->u_arg[0]);
      58  	tprint_arg_next();
      59  
      60  	/* description */
      61  	printstr(tcp, tcp->u_arg[1]);
      62  	tprint_arg_next();
      63  
      64  	/* callout_info */
      65  	printstr(tcp, tcp->u_arg[2]);
      66  	tprint_arg_next();
      67  
      68  	/* keyring serial number */
      69  	print_keyring_serial_number(tcp->u_arg[3]);
      70  
      71  	return RVAL_DECODED;
      72  }
      73  
      74  static void
      75  keyctl_get_keyring_id(struct tcb *tcp, key_serial_t id, int create)
      76  {
      77  	print_keyring_serial_number(id);
      78  	tprint_arg_next();
      79  
      80  	PRINT_VAL_D(create);
      81  }
      82  
      83  static void
      84  keyctl_update_key(struct tcb *tcp, key_serial_t id, kernel_ulong_t addr,
      85  		  kernel_ulong_t len)
      86  {
      87  	print_keyring_serial_number(id);
      88  	tprint_arg_next();
      89  
      90  	printstrn(tcp, addr, len);
      91  	tprint_arg_next();
      92  
      93  	PRINT_VAL_U(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  	tprint_arg_next();
     101  
     102  	print_keyring_serial_number(id2);
     103  }
     104  
     105  static void
     106  keyctl_read_key(struct tcb *tcp, key_serial_t id, kernel_ulong_t addr,
     107  		kernel_ulong_t len, bool has_nul)
     108  {
     109  	if (entering(tcp)) {
     110  		print_keyring_serial_number(id);
     111  		tprint_arg_next();
     112  	} else {
     113  		if (syserror(tcp))
     114  			printaddr(addr);
     115  		else {
     116  			kernel_ulong_t rval = (tcp->u_rval >= 0) &&
     117  				((kernel_ulong_t) tcp->u_rval > len) ? len :
     118  				(kernel_ulong_t) tcp->u_rval;
     119  			printstr_ex(tcp, addr, rval, has_nul ?
     120  				    QUOTE_OMIT_TRAILING_0 : 0);
     121  		}
     122  		tprint_arg_next();
     123  
     124  		PRINT_VAL_U(len);
     125  	}
     126  }
     127  
     128  static void
     129  keyctl_keyring_search(struct tcb *tcp, key_serial_t id1, kernel_ulong_t addr1,
     130  		      kernel_ulong_t addr2, key_serial_t id2)
     131  {
     132  	print_keyring_serial_number(id1);
     133  	tprint_arg_next();
     134  
     135  	printstr(tcp, addr1);
     136  	tprint_arg_next();
     137  
     138  	printstr(tcp, addr2);
     139  	tprint_arg_next();
     140  
     141  	print_keyring_serial_number(id2);
     142  }
     143  
     144  static void
     145  keyctl_chown_key(struct tcb *tcp, key_serial_t id, unsigned user,
     146  		 unsigned group)
     147  {
     148  	print_keyring_serial_number(id);
     149  	tprint_arg_next();
     150  
     151  	printuid(user);
     152  	tprint_arg_next();
     153  
     154  	printuid(group);
     155  }
     156  
     157  static void
     158  keyctl_instantiate_key(struct tcb *tcp, key_serial_t id1, kernel_ulong_t addr,
     159  		       kernel_ulong_t len, key_serial_t id2)
     160  {
     161  	print_keyring_serial_number(id1);
     162  	tprint_arg_next();
     163  
     164  	printstrn(tcp, addr, len);
     165  	tprint_arg_next();
     166  
     167  	PRINT_VAL_U(len);
     168  	tprint_arg_next();
     169  
     170  	print_keyring_serial_number(id2);
     171  }
     172  
     173  static void
     174  keyctl_instantiate_key_iov(struct tcb *tcp, key_serial_t id1,
     175  			   kernel_ulong_t addr, kernel_ulong_t len,
     176  			   key_serial_t id2)
     177  {
     178  	print_keyring_serial_number(id1);
     179  	tprint_arg_next();
     180  
     181  	tprint_iov(tcp, len, addr, iov_decode_str);
     182  	tprint_arg_next();
     183  
     184  	PRINT_VAL_U(len);
     185  	tprint_arg_next();
     186  
     187  	print_keyring_serial_number(id2);
     188  }
     189  
     190  static void
     191  keyctl_negate_key(struct tcb *tcp, key_serial_t id1, unsigned timeout,
     192  		  key_serial_t id2)
     193  {
     194  	print_keyring_serial_number(id1);
     195  	tprint_arg_next();
     196  
     197  	PRINT_VAL_U(timeout);
     198  	tprint_arg_next();
     199  
     200  	print_keyring_serial_number(id2);
     201  }
     202  
     203  static void
     204  keyctl_reject_key(struct tcb *tcp, key_serial_t id1, unsigned timeout,
     205  		  unsigned error, key_serial_t id2)
     206  {
     207  	print_keyring_serial_number(id1);
     208  	tprint_arg_next();
     209  
     210  	PRINT_VAL_U(timeout);
     211  	tprint_arg_next();
     212  
     213  	print_err(error, false);
     214  	tprint_arg_next();
     215  
     216  	print_keyring_serial_number(id2);
     217  }
     218  
     219  static void
     220  keyctl_set_timeout(struct tcb *tcp, key_serial_t id, unsigned timeout)
     221  {
     222  	print_keyring_serial_number(id);
     223  	tprint_arg_next();
     224  
     225  	PRINT_VAL_U(timeout);
     226  }
     227  
     228  static void
     229  keyctl_get_persistent(struct tcb *tcp, unsigned uid, key_serial_t id)
     230  {
     231  	printuid(uid);
     232  	tprint_arg_next();
     233  
     234  	print_keyring_serial_number(id);
     235  }
     236  
     237  static void
     238  keyctl_setperm_key(struct tcb *tcp, key_serial_t id, uint32_t perm)
     239  {
     240  	print_keyring_serial_number(id);
     241  	tprint_arg_next();
     242  
     243  	printflags(key_perms, perm, "KEY_???");
     244  }
     245  
     246  static void
     247  print_dh_params(struct tcb *tcp, kernel_ulong_t addr)
     248  {
     249  	struct keyctl_dh_params params;
     250  
     251  	if (umove_or_printaddr(tcp, addr, &params))
     252  		return;
     253  
     254  	tprint_struct_begin();
     255  	PRINT_FIELD_OBJ_VAL(params, private, print_keyring_serial_number);
     256  	tprint_struct_next();
     257  	PRINT_FIELD_OBJ_VAL(params, prime, print_keyring_serial_number);
     258  	tprint_struct_next();
     259  	PRINT_FIELD_OBJ_VAL(params, base, print_keyring_serial_number);
     260  	tprint_struct_end();
     261  }
     262  
     263  static void
     264  keyctl_dh_compute(struct tcb *tcp, kernel_ulong_t params, kernel_ulong_t buf,
     265  		  kernel_ulong_t len, kernel_ulong_t kdf_addr)
     266  {
     267  	if (entering(tcp)) {
     268  		print_dh_params(tcp, params);
     269  		tprint_arg_next();
     270  	} else {
     271  		struct strace_keyctl_kdf_params kdf;
     272  
     273  		if (syserror(tcp)) {
     274  			printaddr(buf);
     275  		} else {
     276  			kernel_ulong_t rval = (tcp->u_rval >= 0) &&
     277  				((kernel_ulong_t) tcp->u_rval > len) ? len :
     278  				(kernel_ulong_t) tcp->u_rval;
     279  			printstrn(tcp, buf, rval);
     280  		}
     281  		tprint_arg_next();
     282  
     283  		PRINT_VAL_U(len);
     284  		tprint_arg_next();
     285  
     286  		if (fetch_keyctl_kdf_params(tcp, kdf_addr, &kdf)) {
     287  			printaddr(kdf_addr);
     288  		} else {
     289  			tprint_struct_begin();
     290  			PRINT_FIELD_OBJ_TCB_VAL(kdf, hashname, tcp,
     291  						printstr);
     292  
     293  			/*
     294  			 * Kernel doesn't touch otherinfo
     295  			 * if otherinfolen is zero.
     296  			 */
     297  			if (kdf.otherinfolen) {
     298  				tprint_struct_next();
     299  				PRINT_FIELD_OBJ_TCB_VAL(kdf, otherinfo,
     300  					tcp, printstrn, kdf.otherinfolen);
     301  			} else {
     302  				tprint_struct_next();
     303  				PRINT_FIELD_PTR(kdf, otherinfo);
     304  			}
     305  
     306  			tprint_struct_next();
     307  			PRINT_FIELD_U(kdf, otherinfolen);
     308  
     309  			if (!IS_ARRAY_ZERO(kdf.__spare)) {
     310  				tprint_struct_next();
     311  				PRINT_FIELD_ARRAY(kdf, __spare, tcp,
     312  						  print_xint_array_member);
     313  			}
     314  
     315  			tprint_struct_end();
     316  		}
     317  	}
     318  }
     319  
     320  static void
     321  print_pkey_query(struct tcb *tcp, kernel_ulong_t addr)
     322  {
     323  	struct keyctl_pkey_query query;
     324  
     325  	if (umove_or_printaddr(tcp, addr, &query))
     326  		return;
     327  
     328  	tprint_struct_begin();
     329  	PRINT_FIELD_FLAGS(query, supported_ops, keyctl_pkey_ops,
     330  			  "KEYCTL_SUPPORTS_???");
     331  	tprint_struct_next();
     332  	PRINT_FIELD_U(query, key_size);
     333  	tprint_struct_next();
     334  	PRINT_FIELD_U(query, max_data_size);
     335  	tprint_struct_next();
     336  	PRINT_FIELD_U(query, max_sig_size);
     337  	tprint_struct_next();
     338  	PRINT_FIELD_U(query, max_enc_size);
     339  	tprint_struct_next();
     340  	PRINT_FIELD_U(query, max_dec_size);
     341  
     342  	if (!IS_ARRAY_ZERO(query.__spare)) {
     343  		tprint_struct_next();
     344  		PRINT_FIELD_ARRAY(query, __spare, tcp,
     345  				  print_xint_array_member);
     346  	}
     347  
     348  	tprint_struct_end();
     349  }
     350  
     351  static void
     352  keyctl_pkey_query(struct tcb *const tcp,
     353  		  const key_serial_t id,
     354  		  const kernel_ulong_t reserved,
     355  		  const kernel_ulong_t /* char * */ info,
     356  		  const kernel_ulong_t /* keyctl_pkey_query * */ res)
     357  {
     358  	if (entering(tcp)) {
     359  		print_keyring_serial_number(id);
     360  		tprint_arg_next();
     361  
     362  		PRINT_VAL_X(reserved);
     363  		tprint_arg_next();
     364  
     365  		printstr(tcp, info);
     366  		tprint_arg_next();
     367  	} else {
     368  		print_pkey_query(tcp, res);
     369  	}
     370  }
     371  
     372  static bool
     373  fetch_print_pkey_params(struct tcb *tcp, kernel_ulong_t addr,
     374  			struct keyctl_pkey_params *params, bool out)
     375  {
     376  	if (umove_or_printaddr(tcp, addr, params))
     377  		return false;
     378  
     379  	tprint_struct_begin();
     380  	PRINT_FIELD_OBJ_VAL(*params, key_id, print_keyring_serial_number);
     381  	tprint_struct_next();
     382  	PRINT_FIELD_U(*params, in_len);
     383  
     384  	if (out) {
     385  		tprint_struct_next();
     386  		PRINT_FIELD_U(*params, out_len);
     387  	} else {
     388  		tprint_struct_next();
     389  		PRINT_FIELD_U(*params, in2_len);
     390  	}
     391  
     392  	if (!IS_ARRAY_ZERO(params->__spare)) {
     393  		tprint_struct_next();
     394  		PRINT_FIELD_ARRAY(*params, __spare, tcp,
     395  				  print_xint_array_member);
     396  	}
     397  
     398  	tprint_struct_end();
     399  
     400  	return true;
     401  }
     402  
     403  static int
     404  keyctl_pkey_op(struct tcb *const tcp,
     405  	       const kernel_ulong_t /* keyctl_pkey_params * */ params_addr,
     406  	       const kernel_ulong_t /* char * */ info,
     407  	       const kernel_ulong_t /* void * */ op1,
     408  	       const kernel_ulong_t /* void * */ op2,
     409  	       bool out)
     410  {
     411  	if (entering(tcp)) {
     412  		struct keyctl_pkey_params params;
     413  		bool ret;
     414  
     415  		ret = fetch_print_pkey_params(tcp, params_addr, &params, out);
     416  		if (ret && out)
     417  			set_tcb_priv_ulong(tcp, params.out_len);
     418  
     419  		tprint_arg_next();
     420  		printstr(tcp, info);
     421  		tprint_arg_next();
     422  
     423  		if (ret)
     424  			printstrn(tcp, op1, params.in_len);
     425  		else
     426  			printaddr(op1);
     427  		tprint_arg_next();
     428  
     429  		if (!out || !ret) {
     430  			if (ret)
     431  				printstrn(tcp, op2, params.in2_len);
     432  			else
     433  				printaddr(op2);
     434  		}
     435  
     436  		return ret && out ? 0 : RVAL_DECODED;
     437  	} else {
     438  		unsigned long out_len = get_tcb_priv_ulong(tcp);
     439  
     440  		if (syserror(tcp))
     441  			printaddr(op2);
     442  		else
     443  			printstrn(tcp, op2, out_len);
     444  	}
     445  
     446  	return 0;
     447  }
     448  
     449  static void
     450  keyctl_restrict_keyring(struct tcb *const tcp,
     451  			const key_serial_t id,
     452  			const kernel_ulong_t addr1,
     453  			const kernel_ulong_t addr2)
     454  {
     455  	print_keyring_serial_number(id);
     456  	tprint_arg_next();
     457  
     458  	printstr(tcp, addr1);
     459  	tprint_arg_next();
     460  
     461  	printstr(tcp, addr2);
     462  }
     463  
     464  static void
     465  keyctl_move(struct tcb *const tcp,
     466  	    const key_serial_t id,
     467  	    const key_serial_t from,
     468  	    const key_serial_t to,
     469  	    const unsigned int flags)
     470  {
     471  	print_keyring_serial_number(id);
     472  	tprint_arg_next();
     473  
     474  	print_keyring_serial_number(from);
     475  	tprint_arg_next();
     476  
     477  	print_keyring_serial_number(to);
     478  	tprint_arg_next();
     479  
     480  	printflags(keyctl_move_flags, flags, "KEYCTL_MOVE_???");
     481  }
     482  
     483  static bool
     484  print_keyctl_caps(struct tcb *tcp, void *elem_buf, size_t elem_size, void *data)
     485  {
     486  	static const struct {
     487  		const struct xlat *xlat;
     488  		const char *dflt;
     489  	} caps[] = {
     490  		{ keyctl_caps0, "KEYCTL_CAPS0_???" },
     491  		{ keyctl_caps1, "KEYCTL_CAPS1_???" },
     492  	};
     493  
     494  	kernel_ulong_t *pos = data;
     495  	unsigned char *elem = elem_buf;
     496  
     497  	if (*pos < ARRAY_SIZE(caps))
     498  		printflags(caps[*pos].xlat, *elem, caps[*pos].dflt);
     499  	else
     500  		PRINT_VAL_X(*elem);
     501  
     502  	(*pos)++;
     503  
     504  	return true;
     505  }
     506  
     507  static void
     508  keyctl_capabilities(struct tcb *const tcp,
     509  		    const kernel_ulong_t /* char * */ buf,
     510  		    const kernel_ulong_t buflen)
     511  {
     512  	kernel_ulong_t pos = 0;
     513  	unsigned char elem;
     514  
     515  	if (entering(tcp))
     516  		return;
     517  
     518  	if (syserror(tcp)) {
     519  		printaddr(buf);
     520  	} else {
     521  		print_array(tcp, buf, MIN(buflen, (kernel_ulong_t) tcp->u_rval),
     522  			    &elem, sizeof(elem),
     523  			    tfetch_mem, print_keyctl_caps, &pos);
     524  	}
     525  	tprint_arg_next();
     526  
     527  	PRINT_VAL_U(buflen);
     528  }
     529  
     530  SYS_FUNC(keyctl)
     531  {
     532  	int cmd = tcp->u_arg[0];
     533  	kernel_ulong_t arg2 = tcp->u_arg[1];
     534  	kernel_ulong_t arg3 = tcp->u_arg[2];
     535  	kernel_ulong_t arg4 = tcp->u_arg[3];
     536  	kernel_ulong_t arg5 = tcp->u_arg[4];
     537  
     538  	if (entering(tcp)) {
     539  		printxval(keyctl_commands, cmd, "KEYCTL_???");
     540  
     541  		/*
     542  		 * For now, KEYCTL_SESSION_TO_PARENT is the only cmd without
     543  		 * arguments.
     544  		 */
     545  		if (cmd != KEYCTL_SESSION_TO_PARENT)
     546  			tprint_arg_next();
     547  	}
     548  
     549  	switch (cmd) {
     550  	case KEYCTL_GET_KEYRING_ID:
     551  		keyctl_get_keyring_id(tcp, arg2, arg3);
     552  		break;
     553  
     554  	case KEYCTL_JOIN_SESSION_KEYRING:
     555  		printstr(tcp, arg2);
     556  		break;
     557  
     558  	case KEYCTL_UPDATE:
     559  		keyctl_update_key(tcp, arg2, arg3, arg4);
     560  		break;
     561  
     562  	case KEYCTL_REVOKE:
     563  	case KEYCTL_CLEAR:
     564  	case KEYCTL_INVALIDATE:
     565  	case KEYCTL_ASSUME_AUTHORITY:
     566  		print_keyring_serial_number(arg2);
     567  		break;
     568  
     569  	case KEYCTL_LINK:
     570  	case KEYCTL_UNLINK:
     571  		keyctl_handle_key_key(tcp, arg2, arg3);
     572  		break;
     573  
     574  	case KEYCTL_DESCRIBE:
     575  	case KEYCTL_READ:
     576  	case KEYCTL_GET_SECURITY:
     577  		keyctl_read_key(tcp, arg2, arg3, arg4, cmd != KEYCTL_READ);
     578  		return 0;
     579  
     580  	case KEYCTL_SEARCH:
     581  		keyctl_keyring_search(tcp, arg2, arg3, arg4, arg5);
     582  		break;
     583  
     584  	case KEYCTL_CHOWN:
     585  		keyctl_chown_key(tcp, arg2, arg3, arg4);
     586  		break;
     587  
     588  	case KEYCTL_SETPERM:
     589  		keyctl_setperm_key(tcp, arg2, arg3);
     590  		break;
     591  
     592  	case KEYCTL_INSTANTIATE:
     593  		keyctl_instantiate_key(tcp, arg2, arg3, arg4, arg5);
     594  		break;
     595  
     596  	case KEYCTL_NEGATE:
     597  		keyctl_negate_key(tcp, arg2, arg3, arg4);
     598  		break;
     599  
     600  	case KEYCTL_SET_REQKEY_KEYRING:
     601  		printxvals_ex((int) arg2, "KEY_REQKEY_DEFL_???",
     602  			      XLAT_STYLE_FMT_D, key_reqkeys, NULL);
     603  		break;
     604  
     605  	case KEYCTL_SET_TIMEOUT:
     606  		keyctl_set_timeout(tcp, arg2, arg3);
     607  		break;
     608  
     609  	case KEYCTL_SESSION_TO_PARENT:
     610  		break;
     611  
     612  	case KEYCTL_REJECT:
     613  		keyctl_reject_key(tcp, arg2, arg3, arg4, arg5);
     614  		break;
     615  
     616  	case KEYCTL_INSTANTIATE_IOV:
     617  		keyctl_instantiate_key_iov(tcp, arg2, arg3, arg4, arg5);
     618  		break;
     619  
     620  	case KEYCTL_GET_PERSISTENT:
     621  		keyctl_get_persistent(tcp, arg2, arg3);
     622  		break;
     623  
     624  	case KEYCTL_DH_COMPUTE:
     625  		keyctl_dh_compute(tcp, arg2, arg3, arg4, arg5);
     626  		return 0;
     627  
     628  	case KEYCTL_PKEY_QUERY:
     629  		keyctl_pkey_query(tcp, arg2, arg3, arg4, arg5);
     630  		return 0;
     631  
     632  	case KEYCTL_PKEY_ENCRYPT:
     633  	case KEYCTL_PKEY_DECRYPT:
     634  	case KEYCTL_PKEY_SIGN:
     635  		return keyctl_pkey_op(tcp, arg2, arg3, arg4, arg5, true);
     636  
     637  	case KEYCTL_PKEY_VERIFY:
     638  		keyctl_pkey_op(tcp, arg2, arg3, arg4, arg5, false);
     639  		break;
     640  
     641  	case KEYCTL_RESTRICT_KEYRING:
     642  		keyctl_restrict_keyring(tcp, arg2, arg3, arg4);
     643  		break;
     644  
     645  	case KEYCTL_MOVE:
     646  		keyctl_move(tcp, arg2, arg3, arg4, arg5);
     647  		break;
     648  
     649  	case KEYCTL_CAPABILITIES:
     650  		keyctl_capabilities(tcp, arg2, arg3);
     651  		return 0;
     652  
     653  	default:
     654  		PRINT_VAL_X(arg2);
     655  		tprint_arg_next();
     656  
     657  		PRINT_VAL_X(arg3);
     658  		tprint_arg_next();
     659  
     660  		PRINT_VAL_X(arg4);
     661  		tprint_arg_next();
     662  
     663  		PRINT_VAL_X(arg5);
     664  		break;
     665  	}
     666  
     667  	return RVAL_DECODED;
     668  }