Add a keyctl function that requests a set of capability bits to find out what features are supported.
Unified · Split
| @@ -68,6 +68,7 @@ · 67 unmodified lines | |||
| 68 | #define KEYCTL_PKEY_VERIFY 28 /* Verify a public key signature */ | 68 | #define KEYCTL_PKEY_VERIFY 28 /* Verify a public key signature */ |
| 69 | #define KEYCTL_RESTRICT_KEYRING 29 /* Restrict keys allowed to link to a keyring */ | 69 | #define KEYCTL_RESTRICT_KEYRING 29 /* Restrict keys allowed to link to a keyring */ |
| 70 | #define KEYCTL_MOVE 30 /* Move keys between keyrings */ | 70 | #define KEYCTL_MOVE 30 /* Move keys between keyrings */ |
| 71 | #define KEYCTL_CAPABILITIES 31 /* Find capabilities of keyrings subsystem */ | ||
| 71 | 72 | ||
| 72 | /* keyctl structures */ | 73 | /* keyctl structures */ |
| 73 | struct keyctl_dh_params { | 74 | struct keyctl_dh_params { |
| @@ -115,4 +116,17 @@ struct keyctl_pkey_params { · 41 unmodified lines | |||
| 115 | 116 | ||
| 116 | #define KEYCTL_MOVE_EXCL 0x00000001 /* Do not displace from the to-keyring */ | 117 | #define KEYCTL_MOVE_EXCL 0x00000001 /* Do not displace from the to-keyring */ |
| 117 | 118 | ||
| 119 | /* | ||
| 120 | * Capabilities flags. The capabilities list is an array of 8-bit integers; | ||
| 121 | * each integer can carry up to 8 flags. | ||
| 122 | */ | ||
| 123 | #define KEYCTL_CAPS0_CAPABILITIES 0x01 /* KEYCTL_CAPABILITIES supported */ | ||
| 124 | #define KEYCTL_CAPS0_PERSISTENT_KEYRINGS 0x02 /* Persistent keyrings enabled */ | ||
| 125 | #define KEYCTL_CAPS0_DIFFIE_HELLMAN 0x04 /* Diffie-Hellman computation enabled */ | ||
| 126 | #define KEYCTL_CAPS0_PUBLIC_KEY 0x08 /* Public key ops enabled */ | ||
| 127 | #define KEYCTL_CAPS0_BIG_KEY 0x10 /* big_key-type enabled */ | ||
| 128 | #define KEYCTL_CAPS0_INVALIDATE 0x20 /* KEYCTL_INVALIDATE supported */ | ||
| 129 | #define KEYCTL_CAPS0_RESTRICT_KEYRING 0x40 /* KEYCTL_RESTRICT_KEYRING supported */ | ||
| 130 | #define KEYCTL_CAPS0_MOVE 0x80 /* KEYCTL_MOVE supported */ | ||
| 131 | |||
| 118 | #endif /* _LINUX_KEYCTL_H */ | 132 | #endif /* _LINUX_KEYCTL_H */ |
| @@ -162,6 +162,9 @@ COMPAT_SYSCALL_DEFINE5(keyctl, u32, option, · 161 unmodified lines | |||
| 162 | case KEYCTL_MOVE: | 162 | case KEYCTL_MOVE: |
| 163 | return keyctl_keyring_move(arg2, arg3, arg4, arg5); | 163 | return keyctl_keyring_move(arg2, arg3, arg4, arg5); |
| 164 | 164 | ||
| 165 | case KEYCTL_CAPABILITIES: | ||
| 166 | return keyctl_capabilities(compat_ptr(arg2), arg3); | ||
| 167 | |||
| 165 | default: | 168 | default: |
| 166 | return -EOPNOTSUPP; | 169 | return -EOPNOTSUPP; |
| 167 | } | 170 | } |
| @@ -329,6 +329,8 @@ static inline long keyctl_pkey_e_d_s(int op, · 328 unmodified lines | |||
| 329 | } | 329 | } |
| 330 | #endif | 330 | #endif |
| 331 | 331 | ||
| 332 | extern long keyctl_capabilities(unsigned char __user *_buffer, size_t buflen); | ||
| 333 | |||
| 332 | /* | 334 | /* |
| 333 | * Debugging key validation | 335 | * Debugging key validation |
| 334 | */ | 336 | */ |
| @@ -30,6 +30,18 @@ · 29 unmodified lines | |||
| 30 | 30 | ||
| 31 | #define KEY_MAX_DESC_SIZE 4096 | 31 | #define KEY_MAX_DESC_SIZE 4096 |
| 32 | 32 | ||
| 33 | static const unsigned char keyrings_capabilities[1] = { | ||
| 34 | [0] = (KEYCTL_CAPS0_CAPABILITIES | | ||
| 35 | (IS_ENABLED(CONFIG_PERSISTENT_KEYRINGS) ? KEYCTL_CAPS0_PERSISTENT_KEYRINGS : 0) | | ||
| 36 | (IS_ENABLED(CONFIG_KEY_DH_OPERATIONS) ? KEYCTL_CAPS0_DIFFIE_HELLMAN : 0) | | ||
| 37 | (IS_ENABLED(CONFIG_ASYMMETRIC_KEY_TYPE) ? KEYCTL_CAPS0_PUBLIC_KEY : 0) | | ||
| 38 | (IS_ENABLED(CONFIG_BIG_KEYS) ? KEYCTL_CAPS0_BIG_KEY : 0) | | ||
| 39 | KEYCTL_CAPS0_INVALIDATE | | ||
| 40 | KEYCTL_CAPS0_RESTRICT_KEYRING | | ||
| 41 | KEYCTL_CAPS0_MOVE | ||
| 42 | ), | ||
| 43 | }; | ||
| 44 | |||
| 33 | static int key_get_type_from_user(char *type, | 45 | static int key_get_type_from_user(char *type, |
| 34 | const char __user *_type, | 46 | const char __user *_type, |
| 35 | unsigned len) | 47 | unsigned len) |
| @@ -1678,6 +1690,26 @@ error: · 1642 unmodified lines | |||
| 1678 | return ret; | 1690 | return ret; |
| 1679 | } | 1691 | } |
| 1680 | 1692 | ||
| 1693 | /* | ||
| 1694 | * Get keyrings subsystem capabilities. | ||
| 1695 | */ | ||
| 1696 | long keyctl_capabilities(unsigned char __user *_buffer, size_t buflen) | ||
| 1697 | { | ||
| 1698 | size_t size = buflen; | ||
| 1699 | |||
| 1700 | if (size > 0) { | ||
| 1701 | if (size > sizeof(keyrings_capabilities)) | ||
| 1702 | size = sizeof(keyrings_capabilities); | ||
| 1703 | if (copy_to_user(_buffer, keyrings_capabilities, size) != 0) | ||
| 1704 | return -EFAULT; | ||
| 1705 | if (size < buflen && | ||
| 1706 | clear_user(_buffer + size, buflen - size) != 0) | ||
| 1707 | return -EFAULT; | ||
| 1708 | } | ||
| 1709 | |||
| 1710 | return sizeof(keyrings_capabilities); | ||
| 1711 | } | ||
| 1712 | |||
| 1681 | /* | 1713 | /* |
| 1682 | * The key control system call | 1714 | * The key control system call |
| 1683 | */ | 1715 | */ |
| @@ -1824,6 +1856,9 @@ SYSCALL_DEFINE5(keyctl, int, option, unsigned long, arg2, unsigned long, arg3, · 140 unmodified lines | |||
| 1824 | (key_serial_t)arg4, | 1856 | (key_serial_t)arg4, |
| 1825 | (unsigned int)arg5); | 1857 | (unsigned int)arg5); |
| 1826 | 1858 | ||
| 1859 | case KEYCTL_CAPABILITIES: | ||
| 1860 | return keyctl_capabilities((unsigned char __user *)arg2, (size_t)arg3); | ||
| 1861 | |||
| 1827 | default: | 1862 | default: |
| 1828 | return -EOPNOTSUPP; | 1863 | return -EOPNOTSUPP; |
| 1829 | } | 1864 | } |