]> granicus.if.org Git - strace/blobdiff - keyctl.c
print_array: enhance printing of unfetchable object addresses
[strace] / keyctl.c
index c270221ffa24f2fae02ecfe4c1641a770d81ecf1..4f98ec29b93c7ced064a78de22cbb46d1ae38b49 100644 (file)
--- a/keyctl.c
+++ b/keyctl.c
@@ -1,5 +1,6 @@
 /*
  * Copyright (c) 2014-2015 Dmitry V. Levin <ldv@altlinux.org>
+ * Copyright (c) 2014-2017 The strace developers.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -27,6 +28,9 @@
 
 #include "defs.h"
 
+#include "keyctl_kdf_params.h"
+#include "print_fields.h"
+
 typedef int32_t key_serial_t;
 
 #include "xlat/key_spec.h"
@@ -40,12 +44,7 @@ struct keyctl_dh_params {
 static void
 print_keyring_serial_number(key_serial_t id)
 {
-       const char *str = xlookup(key_spec, (unsigned int) id);
-
-       if (str)
-               tprints(str);
-       else
-               tprintf("%d", id);
+       printxval_d(key_spec, id, NULL);
 }
 
 SYS_FUNC(add_key)
@@ -191,12 +190,8 @@ keyctl_reject_key(struct tcb *tcp, key_serial_t id1, unsigned timeout,
 
        print_keyring_serial_number(id1);
        tprintf(", %u, ", timeout);
-
-       if (err_str)
-               tprintf("%s, ", err_str);
-       else
-               tprintf("%u, ", error);
-
+       print_xlat_ex(error, err_str, XLAT_STYLE_FMT_U);
+       tprints(", ");
        print_keyring_serial_number(id2);
 }
 
@@ -244,12 +239,14 @@ print_dh_params(struct tcb *tcp, kernel_ulong_t addr)
 
 static void
 keyctl_dh_compute(struct tcb *tcp, kernel_ulong_t params, kernel_ulong_t buf,
-                 kernel_ulong_t len)
+                 kernel_ulong_t len, kernel_ulong_t kdf_addr)
 {
        if (entering(tcp)) {
                print_dh_params(tcp, params);
                tprints(", ");
        } else {
+               struct strace_keyctl_kdf_params kdf;
+
                if (syserror(tcp)) {
                        printaddr(buf);
                } else {
@@ -258,10 +255,64 @@ keyctl_dh_compute(struct tcb *tcp, kernel_ulong_t params, kernel_ulong_t buf,
                                (kernel_ulong_t) tcp->u_rval;
                        printstrn(tcp, buf, rval);
                }
-               tprintf(", %llu", zero_extend_signed_to_ull(len));
+               tprintf(", %llu, ", zero_extend_signed_to_ull(len));
+
+               if (fetch_keyctl_kdf_params(tcp, kdf_addr, &kdf)) {
+                       printaddr(kdf_addr);
+               } else {
+                       size_t i;
+
+                       PRINT_FIELD_STR("{", kdf, hashname, tcp);
+
+                       /*
+                        * Kernel doesn't touch otherinfo
+                        * if otherinfolen is zero.
+                        */
+                       if (kdf.otherinfolen)
+                               PRINT_FIELD_STRN(", ", kdf, otherinfo,
+                                                kdf.otherinfolen, tcp);
+                       else
+                               PRINT_FIELD_PTR(", ", kdf, otherinfo);
+
+                       PRINT_FIELD_U(", ", kdf, otherinfolen);
+
+                       /* Some future-proofing */
+                       for (i = 0; i < ARRAY_SIZE(kdf.__spare); i++) {
+                               if (kdf.__spare[i])
+                                       break;
+                       }
+
+                       if (i < ARRAY_SIZE(kdf.__spare)) {
+                               tprints(", __spare=[");
+
+                               for (i = 0; i < ARRAY_SIZE(kdf.__spare); i++) {
+                                       if (i)
+                                               tprints(", ");
+
+                                       tprintf("%#x", kdf.__spare[i]);
+                               }
+
+                               tprints("]");
+                       }
+
+                       tprints("}");
+               }
        }
 }
 
+static void
+keyctl_restrict_keyring(struct tcb *const tcp,
+                       const key_serial_t id,
+                       const kernel_ulong_t addr1,
+                       const kernel_ulong_t addr2)
+{
+       print_keyring_serial_number(id);
+       tprints(", ");
+       printstr(tcp, addr1);
+       tprints(", ");
+       printstr(tcp, addr2);
+}
+
 #include "xlat/key_reqkeys.h"
 #include "xlat/keyctl_commands.h"
 
@@ -336,7 +387,8 @@ SYS_FUNC(keyctl)
                break;
 
        case KEYCTL_SET_REQKEY_KEYRING:
-               printxval(key_reqkeys, arg2, "KEY_REQKEY_DEFL_???");
+               printxvals_ex((int) arg2, "KEY_REQKEY_DEFL_???",
+                             XLAT_STYLE_FMT_D, key_reqkeys, NULL);
                break;
 
        case KEYCTL_SET_TIMEOUT:
@@ -359,9 +411,13 @@ SYS_FUNC(keyctl)
                break;
 
        case KEYCTL_DH_COMPUTE:
-               keyctl_dh_compute(tcp, arg2, arg3, arg4);
+               keyctl_dh_compute(tcp, arg2, arg3, arg4, arg5);
                return 0;
 
+       case KEYCTL_RESTRICT_KEYRING:
+               keyctl_restrict_keyring(tcp, arg2, arg3, arg4);
+               break;
+
        default:
                tprintf("%#" PRI_klx ", %#" PRI_klx
                        ", %#" PRI_klx ", %#" PRI_klx,