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 | 68 | #define KEYCTL_PKEY_VERIFY 28 /* Verify a public key signature */ |
| 69 | 69 | #define KEYCTL_RESTRICT_KEYRING 29 /* Restrict keys allowed to link to a keyring */ |
| 70 | 70 | #define KEYCTL_MOVE 30 /* Move keys between keyrings */ |
| 71 | +#define KEYCTL_CAPABILITIES 31 /* Find capabilities of keyrings subsystem */ | |
| 71 | 72 | |
| 72 | 73 | /* keyctl structures */ |
| 73 | 74 | struct keyctl_dh_params { |
| @@ -115,4 +116,17 @@ struct keyctl_pkey_params { · 41 unmodified lines | ||
| 115 | 116 | |
| 116 | 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 | 132 | #endif /* _LINUX_KEYCTL_H */ |
| @@ -162,6 +162,9 @@ COMPAT_SYSCALL_DEFINE5(keyctl, u32, option, · 161 unmodified lines | ||
| 162 | 162 | case KEYCTL_MOVE: |
| 163 | 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 | 168 | default: |
| 166 | 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 | 330 | #endif |
| 331 | 331 | |
| 332 | +extern long keyctl_capabilities(unsigned char __user *_buffer, size_t buflen); | |
| 333 | + | |
| 332 | 334 | /* |
| 333 | 335 | * Debugging key validation |
| 334 | 336 | */ |
| @@ -30,6 +30,18 @@ · 29 unmodified lines | ||
| 30 | 30 | |
| 31 | 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 | 45 | static int key_get_type_from_user(char *type, |
| 34 | 46 | const char __user *_type, |
| 35 | 47 | unsigned len) |
| @@ -1678,6 +1690,26 @@ error: · 1642 unmodified lines | ||
| 1678 | 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 | 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 | 1856 | (key_serial_t)arg4, |
| 1825 | 1857 | (unsigned int)arg5); |
| 1826 | 1858 | |
| 1859 | + case KEYCTL_CAPABILITIES: | |
| 1860 | + return keyctl_capabilities((unsigned char __user *)arg2, (size_t)arg3); | |
| 1861 | + | |
| 1827 | 1862 | default: |
| 1828 | 1863 | return -EOPNOTSUPP; |
| 1829 | 1864 | } |