From: Tom Hughes Date: Wed, 7 Mar 2007 11:12:13 +0000 (+0000) Subject: Add support for linux key management system calls. X-Git-Tag: svn/VALGRIND_3_3_0~334 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=0075b20e84e398f6522114b86d19d3d96cde0050;p=thirdparty%2Fvalgrind.git Add support for linux key management system calls. Based on patch from Ezra Peisach . Fixes bug #139300. git-svn-id: svn://svn.valgrind.org/valgrind/trunk@6632 --- diff --git a/coregrind/m_syswrap/priv_syswrap-linux.h b/coregrind/m_syswrap/priv_syswrap-linux.h index 5c78554865..4ab72def8e 100644 --- a/coregrind/m_syswrap/priv_syswrap-linux.h +++ b/coregrind/m_syswrap/priv_syswrap-linux.h @@ -140,6 +140,10 @@ DECL_TEMPLATE(linux, sys_readlinkat); DECL_TEMPLATE(linux, sys_fchmodat); DECL_TEMPLATE(linux, sys_faccessat); +DECL_TEMPLATE(linux, sys_add_key); +DECL_TEMPLATE(linux, sys_request_key); +DECL_TEMPLATE(linux, sys_keyctl); + // These ones have 32-bit generic equivalents, but the 16-bit versions (they // use 16-bit gid_t and uid_t types) seem to be Linux-specific. DECL_TEMPLATE(linux, sys_getuid16); diff --git a/coregrind/m_syswrap/syswrap-amd64-linux.c b/coregrind/m_syswrap/syswrap-amd64-linux.c index 7d4daa337e..5ab3162525 100644 --- a/coregrind/m_syswrap/syswrap-amd64-linux.c +++ b/coregrind/m_syswrap/syswrap-amd64-linux.c @@ -1320,10 +1320,10 @@ const SyscallTableEntry ML_(syscall_table)[] = { LINXY(__NR_mq_getsetattr, sys_mq_getsetattr), // 245 // (__NR_kexec_load, sys_ni_syscall), // 246 LINXY(__NR_waitid, sys_waitid), // 247 -// LINX_(__NR_add_key, sys_add_key), // 248 -// LINX_(__NR_request_key, sys_request_key), // 249 + LINX_(__NR_add_key, sys_add_key), // 248 + LINX_(__NR_request_key, sys_request_key), // 249 -// LINXY(__NR_keyctl, sys_keyctl), // 250 + LINXY(__NR_keyctl, sys_keyctl), // 250 // LINX_(__NR_ioprio_set, sys_ioprio_set), // 251 // LINX_(__NR_ioprio_get, sys_ioprio_get), // 252 LINX_(__NR_inotify_init, sys_inotify_init), // 253 diff --git a/coregrind/m_syswrap/syswrap-linux.c b/coregrind/m_syswrap/syswrap-linux.c index bdf12f0177..ebc4e16f42 100644 --- a/coregrind/m_syswrap/syswrap-linux.c +++ b/coregrind/m_syswrap/syswrap-linux.c @@ -2613,9 +2613,175 @@ PRE(sys_faccessat) PRE_MEM_RASCIIZ( "faccessat(pathname)", ARG2 ); } +/* --------------------------------------------------------------------- + key retention service wrappers + ------------------------------------------------------------------ */ +PRE(sys_request_key) +{ + PRINT("sys_request_key ( %p(%s), %p(%s), %p(%s), %d )", + ARG1,ARG1,ARG2,ARG2,ARG3,ARG3,ARG4); + PRE_REG_READ4(long, "request_key", + const char *, type, const char *, description, + const char *, callout_info, vki_key_serial_t, keyring); + PRE_MEM_RASCIIZ( "request_key(type)", ARG1); + PRE_MEM_RASCIIZ( "request_key(description)", ARG2); + if (ARG3 != (UWord)NULL) + PRE_MEM_RASCIIZ( "request_key(callout_info)", ARG3); +} + +PRE(sys_add_key) +{ + PRINT("sys_add_key ( %p(%s), %p(%s), %p, %d, %d )", + ARG1,ARG1,ARG2,ARG2,ARG3,ARG4,ARG5); + PRE_REG_READ5(long, "add_key", + const char *, type, const char *, description, + const void *, payload, vki_size_t, plen, + vki_key_serial_t, keyring); + PRE_MEM_RASCIIZ( "add_key(type)", ARG1); + PRE_MEM_RASCIIZ( "add_key(description)", ARG2); + if (ARG3 != (UWord)NULL) + PRE_MEM_READ( "request_key(payload)", ARG3, ARG4); +} + +PRE(sys_keyctl) +{ + switch (ARG1 /* option */) { + case VKI_KEYCTL_GET_KEYRING_ID: + PRINT("sys_keyctl ( KEYCTL_GET_KEYRING_ID, %d, %d )", ARG2,ARG3); + PRE_REG_READ3(long, "keyctl(KEYCTL_GET_KEYRING_ID)", + int, option, vki_key_serial_t, id, int, create); + break; + case VKI_KEYCTL_JOIN_SESSION_KEYRING: + PRINT("sys_keyctl ( KEYCTL_JOIN_SESSION_KEYRING, %p(%s) )", ARG2,ARG2); + PRE_REG_READ2(long, "keyctl(KEYCTL_JOIN_SESSION_KEYRING)", + int, option, const char *, name); + if (ARG2 != (UWord)NULL) + PRE_MEM_RASCIIZ("keyctl(KEYCTL_JOIN_SESSION_KEYRING, name)", ARG2); + break; + case VKI_KEYCTL_UPDATE: + PRINT("sys_keyctl ( KEYCTL_UPDATE, %d, %p, %d )", ARG2,ARG3,ARG4); + PRE_REG_READ4(long, "keyctl(KEYCTL_UPDATE)", + int, option, vki_key_serial_t, key, + const void *, payload, vki_size_t, plen); + if (ARG3 != (UWord)NULL) + PRE_MEM_READ("keyctl(KEYCTL_UPDATE, payload)", ARG3, ARG4); + break; + case VKI_KEYCTL_REVOKE: + PRINT("sys_keyctl ( KEYCTL_REVOKE, %d )", ARG2); + PRE_REG_READ2(long, "keyctl(KEYCTL_REVOKE)", + int, option, vki_key_serial_t, id); + break; + case VKI_KEYCTL_CHOWN: + PRINT("sys_keyctl ( KEYCTL_CHOWN, %d, %d, %d )", ARG2,ARG3,ARG4); + PRE_REG_READ4(long, "keyctl(KEYCTL_CHOWN)", + int, option, vki_key_serial_t, id, + vki_uid_t, uid, vki_gid_t, gid); + break; + case VKI_KEYCTL_SETPERM: + PRINT("sys_keyctl ( KEYCTL_SETPERM, %d, %d )", ARG2,ARG3); + PRE_REG_READ3(long, "keyctl(KEYCTL_SETPERM)", + int, option, vki_key_serial_t, id, vki_key_perm_t, perm); + break; + case VKI_KEYCTL_DESCRIBE: + PRINT("sys_keyctl ( KEYCTL_DESCRIBE, %d, %p, %d )", ARG2,ARG3,ARG4); + PRE_REG_READ4(long, "keyctl(KEYCTL_DESCRIBE)", + int, option, vki_key_serial_t, id, + char *, buffer, vki_size_t, buflen); + if (ARG3 != (UWord)NULL) + PRE_MEM_WRITE("keyctl(KEYCTL_DESCRIBE, buffer)", ARG3, ARG4); + break; + case VKI_KEYCTL_CLEAR: + PRINT("sys_keyctl ( KEYCTL_CLEAR, %d )", ARG2); + PRE_REG_READ2(long, "keyctl(KEYCTL_CLEAR)", + int, option, vki_key_serial_t, keyring); + break; + case VKI_KEYCTL_LINK: + PRINT("sys_keyctl ( KEYCTL_LINK, %d, %d )", ARG2,ARG3); + PRE_REG_READ3(long, "keyctl(KEYCTL_LINK)", int, option, + vki_key_serial_t, keyring, vki_key_serial_t, key); + break; + case VKI_KEYCTL_UNLINK: + PRINT("sys_keyctl ( KEYCTL_UNLINK, %d, %d )", ARG2,ARG3); + PRE_REG_READ3(long, "keyctl(KEYCTL_UNLINK)", int, option, + vki_key_serial_t, keyring, vki_key_serial_t, key); + break; + case VKI_KEYCTL_SEARCH: + PRINT("sys_keyctl ( KEYCTL_SEARCH, %d, %p(%s), %p(%s), %d )", + ARG2,ARG3,ARG3,ARG4,ARG4,ARG5); + PRE_REG_READ5(long, "keyctl(KEYCTL_SEARCH)", + int, option, vki_key_serial_t, keyring, + const char *, type, const char *, description, + vki_key_serial_t, destring); + PRE_MEM_RASCIIZ("sys_keyctl(KEYCTL_SEARCH, type)", ARG3); + PRE_MEM_RASCIIZ("sys_keyctl(KEYCTL_SEARCH, description)", ARG4); + break; + case VKI_KEYCTL_READ: + PRINT("sys_keyctl ( KEYCTL_READ, %d, %p, %d )", ARG2,ARG3,ARG4); + PRE_REG_READ4(long, "keyctl(KEYCTL_READ)", + int, option, vki_key_serial_t, keyring, + char *, buffer, vki_size_t, buflen); + if (ARG3 != (UWord)NULL) + PRE_MEM_WRITE("keyctl(KEYCTL_READ, buffer)", ARG3, ARG4); + break; + case VKI_KEYCTL_INSTANTIATE: + PRINT("sys_keyctl ( KEYCTL_INSTANTIATE, %d, %p, %d, %d )", + ARG2,ARG3,ARG4,ARG5); + PRE_REG_READ5(long, "keyctl(KEYCTL_INSTANTIATE)", + int, option, vki_key_serial_t, key, + char *, payload, vki_size_t, plen, + vki_key_serial_t, keyring); + if (ARG3 != (UWord)NULL) + PRE_MEM_READ("keyctl(KEYCTL_INSTANTIATE, payload)", ARG3, ARG4); + break; + case VKI_KEYCTL_NEGATE: + PRINT("sys_keyctl ( KEYCTL_NEGATE, %d, %u, %d )", ARG2,ARG3,ARG4); + PRE_REG_READ4(long, "keyctl(KEYCTL_NEGATE)", + int, option, vki_key_serial_t, key, + unsigned, timeout, vki_key_serial_t, keyring); + break; + case VKI_KEYCTL_SET_REQKEY_KEYRING: + PRINT("sys_keyctl ( KEYCTL_SET_REQKEY_KEYRING, %d )", ARG2); + PRE_REG_READ2(long, "keyctl(KEYCTL_SET_REQKEY_KEYRING)", + int, option, int, reqkey_defl); + break; + case VKI_KEYCTL_SET_TIMEOUT: + PRINT("sys_keyctl ( KEYCTL_SET_TIMEOUT, %d, %d )", ARG2,ARG3); + PRE_REG_READ3(long, "keyctl(KEYCTL_SET_TIMEOUT)", + int, option, vki_key_serial_t, key, unsigned, timeout); + break; + case VKI_KEYCTL_ASSUME_AUTHORITY: + PRINT("sys_keyctl ( KEYCTL_ASSUME_AUTHORITY, %d )", ARG2); + PRE_REG_READ2(long, "keyctl(KEYCTL_ASSUME_AUTHORITY)", + int, option, vki_key_serial_t, key); + break; + default: + PRINT("sys_keyctl ( %d ) ", ARG1); + PRE_REG_READ1(long, "keyctl", int, option); + break; + } +} + +POST(sys_keyctl) +{ + vg_assert(SUCCESS); + switch (ARG1 /* option */) { + case VKI_KEYCTL_DESCRIBE: + case VKI_KEYCTL_READ: + if (RES > ARG4) + POST_MEM_WRITE(ARG3, ARG4); + else + POST_MEM_WRITE(ARG3, RES); + break; + default: + break; + } +} + #undef PRE #undef POST /*--------------------------------------------------------------------*/ /*--- end ---*/ /*--------------------------------------------------------------------*/ + + diff --git a/coregrind/m_syswrap/syswrap-ppc64-linux.c b/coregrind/m_syswrap/syswrap-ppc64-linux.c index c9b78d5ae7..02e1fd33c8 100644 --- a/coregrind/m_syswrap/syswrap-ppc64-linux.c +++ b/coregrind/m_syswrap/syswrap-ppc64-linux.c @@ -1492,10 +1492,10 @@ const SyscallTableEntry ML_(syscall_table)[] = { LINX_(__NR_mq_notify, sys_mq_notify), // 266 LINXY(__NR_mq_getsetattr, sys_mq_getsetattr), // 267 // _____(__NR_kexec_load, sys_kexec_load), // 268 -// _____(__NR_add_key, sys_add_key), // 269 + LINX_(__NR_add_key, sys_add_key), // 269 -// _____(__NR_request_key, sys_request_key), // 270 -// _____(__NR_keyctl, sys_keyctl), // 271 + LINX_(__NR_request_key, sys_request_key), // 270 + LINXY(__NR_keyctl, sys_keyctl), // 271 // _____(__NR_waitid, sys_waitid), // 272 // _____(__NR_ioprio_set, sys_ioprio_set), // 273 // _____(__NR_ioprio_get, sys_ioprio_get), // 274 diff --git a/coregrind/m_syswrap/syswrap-x86-linux.c b/coregrind/m_syswrap/syswrap-x86-linux.c index a607251587..0ac6d38e7f 100644 --- a/coregrind/m_syswrap/syswrap-x86-linux.c +++ b/coregrind/m_syswrap/syswrap-x86-linux.c @@ -2167,9 +2167,9 @@ const SyscallTableEntry ML_(syscall_table)[] = { LINXY(__NR_waitid, sys_waitid), // 284 GENX_(285, sys_ni_syscall), // 285 -// LINX_(__NR_add_key, sys_add_key), // 286 -// LINX_(__NR_request_key, sys_request_key), // 287 -// LINXY(__NR_keyctl, sys_keyctl), // 288 + LINX_(__NR_add_key, sys_add_key), // 286 + LINX_(__NR_request_key, sys_request_key), // 287 + LINXY(__NR_keyctl, sys_keyctl), // 288 // LINX_(__NR_ioprio_set, sys_ioprio_set), // 289 // LINX_(__NR_ioprio_get, sys_ioprio_get), // 290 diff --git a/include/vki/vki-linux.h b/include/vki/vki-linux.h index 86eea4fea9..1f95bd5800 100644 --- a/include/vki/vki-linux.h +++ b/include/vki/vki-linux.h @@ -173,6 +173,14 @@ typedef unsigned int vki_uint; # error Unknown platform #endif +//---------------------------------------------------------------------- +// From linux-2.6.20.1/include/linux/types.h +//---------------------------------------------------------------------- + +typedef __vki_s32 vki_int32_t; + +typedef __vki_u32 vki_uint32_t; + //---------------------------------------------------------------------- // From linux-2.6.8.1/include/linux/limits.h //---------------------------------------------------------------------- @@ -2328,6 +2336,39 @@ struct vki_usbdevfs_ioctl { #define VKI_I2C_FUNCS 0x0705 /* Get the adapter functionality */ #define VKI_I2C_PEC 0x0708 /* != 0 for SMBus PEC */ +//---------------------------------------------------------------------- +// From linux-2.6.20.1/include/linux/keyctl.h +//---------------------------------------------------------------------- + +/* keyctl commands */ +#define VKI_KEYCTL_GET_KEYRING_ID 0 /* ask for a keyring's ID */ +#define VKI_KEYCTL_JOIN_SESSION_KEYRING 1 /* join or start named session keyring */ +#define VKI_KEYCTL_UPDATE 2 /* update a key */ +#define VKI_KEYCTL_REVOKE 3 /* revoke a key */ +#define VKI_KEYCTL_CHOWN 4 /* set ownership of a key */ +#define VKI_KEYCTL_SETPERM 5 /* set perms on a key */ +#define VKI_KEYCTL_DESCRIBE 6 /* describe a key */ +#define VKI_KEYCTL_CLEAR 7 /* clear contents of a keyring */ +#define VKI_KEYCTL_LINK 8 /* link a key into a keyring */ +#define VKI_KEYCTL_UNLINK 9 /* unlink a key from a keyring */ +#define VKI_KEYCTL_SEARCH 10 /* search for a key in a keyring */ +#define VKI_KEYCTL_READ 11 /* read a key or keyring's contents */ +#define VKI_KEYCTL_INSTANTIATE 12 /* instantiate a partially constructed key */ +#define VKI_KEYCTL_NEGATE 13 /* negate a partially constructed key */ +#define VKI_KEYCTL_SET_REQKEY_KEYRING 14 /* set default request-key keyring */ +#define VKI_KEYCTL_SET_TIMEOUT 15 /* set key timeout */ +#define VKI_KEYCTL_ASSUME_AUTHORITY 16 /* assume request_key() authorisation */ + +/*--------------------------------------------------------------------*/ +// From linux-2.6.20.1/include/linux/key.h +/*--------------------------------------------------------------------*/ + +/* key handle serial number */ +typedef vki_int32_t vki_key_serial_t; + +/* key handle permissions mask */ +typedef vki_uint32_t vki_key_perm_t; + #endif // __VKI_LINUX_H /*--------------------------------------------------------------------*/