Pull key handling fixes from James Morris: "This includes a fix for the capabilities code from Colin King, and a set of further fixes for the keys subsystem. From David: - Fix a bunch of places where kernel drivers may access revoked user-type keys and don't do it correctly. - Fix some ecryptfs bits. - Fix big_key to require CONFIG_CRYPTO. - Fix a couple of bugs in the asymmetric key type. - Fix a race between updating and finding negative keys. - Prevent add_key() from updating uninstantiated keys. - Make loading of key flags and expiry time atomic when not holding locks" * 'fixes-v4.14-rc5' of git://git.kernel.org/pub/scm/linux/kernel/git/jmorris/linux-security: commoncap: move assignment of fs_ns to avoid null pointer dereference pkcs7: Prevent NULL pointer dereference, since sinfo is not always set. KEYS: load key flags and expiry time atomically in proc_keys_show() KEYS: Load key expiry time atomically in keyring_search_iterator() KEYS: load key flags and expiry time atomically in key_validate() KEYS: don't let add_key() update an uninstantiated key KEYS: Fix race between updating and finding a negative key KEYS: checking the input id parameters before finding asymmetric key KEYS: Fix the wrong index when checking the existence of second id security/keys: BIG_KEY requires CONFIG_CRYPTO ecryptfs: fix dereference of NULL user_key_payload fscrypt: fix dereference of NULL user_key_payload lib/digsig: fix dereference of NULL user_key_payload FS-Cache: fix dereference of NULL user_key_payload KEYS: encrypted: fix dereference of NULL user_key_payload
Showing the changes to include/linux (1 of 24 files). Show all
Unified · Split
| @@ -138,6 +138,11 @@ struct key_restriction { · 137 unmodified lines | ||
| 138 | 138 | struct key_type *keytype; |
| 139 | 139 | }; |
| 140 | 140 | |
| 141 | +enum key_state { | |
| 142 | + KEY_IS_UNINSTANTIATED, | |
| 143 | + KEY_IS_POSITIVE, /* Positively instantiated */ | |
| 144 | +}; | |
| 145 | + | |
| 141 | 146 | /*****************************************************************************/ |
| 142 | 147 | /* |
| 143 | 148 | * authentication token / access credential / keyring |
| @@ -169,6 +174,7 @@ struct key { · 25 unmodified lines | ||
| 169 | 174 | * - may not match RCU dereferenced payload |
| 170 | 175 | * - payload should contain own length |
| 171 | 176 | */ |
| 177 | + short state; /* Key state (+) or rejection error (-) */ | |
| 172 | 178 | |
| 173 | 179 | #ifdef KEY_DEBUGGING |
| 174 | 180 | unsigned magic; |
| @@ -176,18 +182,16 @@ struct key { · 1 unmodified line | ||
| 176 | 182 | #endif |
| 177 | 183 | |
| 178 | 184 | unsigned long flags; /* status flags (change with bitops) */ |
| 179 | −#define KEY_FLAG_INSTANTIATED 0 /* set if key has been instantiated */ | |
| 180 | −#define KEY_FLAG_DEAD 1 /* set if key type has been deleted */ | |
| 181 | −#define KEY_FLAG_REVOKED 2 /* set if key had been revoked */ | |
| 182 | −#define KEY_FLAG_IN_QUOTA 3 /* set if key consumes quota */ | |
| 183 | −#define KEY_FLAG_USER_CONSTRUCT 4 /* set if key is being constructed in userspace */ | |
| 184 | −#define KEY_FLAG_NEGATIVE 5 /* set if key is negative */ | |
| 185 | −#define KEY_FLAG_ROOT_CAN_CLEAR 6 /* set if key can be cleared by root without permission */ | |
| 186 | −#define KEY_FLAG_INVALIDATED 7 /* set if key has been invalidated */ | |
| 187 | −#define KEY_FLAG_BUILTIN 8 /* set if key is built in to the kernel */ | |
| 188 | −#define KEY_FLAG_ROOT_CAN_INVAL 9 /* set if key can be invalidated by root without permission */ | |
| 189 | −#define KEY_FLAG_KEEP 10 /* set if key should not be removed */ | |
| 190 | −#define KEY_FLAG_UID_KEYRING 11 /* set if key is a user or user session keyring */ | |
| 185 | +#define KEY_FLAG_DEAD 0 /* set if key type has been deleted */ | |
| 186 | +#define KEY_FLAG_REVOKED 1 /* set if key had been revoked */ | |
| 187 | +#define KEY_FLAG_IN_QUOTA 2 /* set if key consumes quota */ | |
| 188 | +#define KEY_FLAG_USER_CONSTRUCT 3 /* set if key is being constructed in userspace */ | |
| 189 | +#define KEY_FLAG_ROOT_CAN_CLEAR 4 /* set if key can be cleared by root without permission */ | |
| 190 | +#define KEY_FLAG_INVALIDATED 5 /* set if key has been invalidated */ | |
| 191 | +#define KEY_FLAG_BUILTIN 6 /* set if key is built in to the kernel */ | |
| 192 | +#define KEY_FLAG_ROOT_CAN_INVAL 7 /* set if key can be invalidated by root without permission */ | |
| 193 | +#define KEY_FLAG_KEEP 8 /* set if key should not be removed */ | |
| 194 | +#define KEY_FLAG_UID_KEYRING 9 /* set if key is a user or user session keyring */ | |
| 191 | 195 | |
| 192 | 196 | /* the key type and key description string |
| 193 | 197 | * - the desc is used to match a key against search criteria |
| @@ -213,7 +217,6 @@ struct key { · 19 unmodified lines | ||
| 213 | 217 | struct list_head name_link; |
| 214 | 218 | struct assoc_array keys; |
| 215 | 219 | }; |
| 216 | − int reject_error; | |
| 217 | 220 | }; |
| 218 | 221 | |
| 219 | 222 | /* This is set on a keyring to restrict the addition of a link to a key |
| @@ -353,17 +356,27 @@ extern void key_set_timeout(struct key *, unsigned); · 133 unmodified lines | ||
| 353 | 356 | #define KEY_NEED_SETATTR 0x20 /* Require permission to change attributes */ |
| 354 | 357 | #define KEY_NEED_ALL 0x3f /* All the above permissions */ |
| 355 | 358 | |
| 359 | +static inline short key_read_state(const struct key *key) | |
| 360 | +{ | |
| 361 | + /* Barrier versus mark_key_instantiated(). */ | |
| 362 | + return smp_load_acquire(&key->state); | |
| 363 | +} | |
| 364 | + | |
| 356 | 365 | /** |
| 357 | − * key_is_instantiated - Determine if a key has been positively instantiated | |
| 366 | + * key_is_positive - Determine if a key has been positively instantiated | |
| 358 | 367 | * @key: The key to check. |
| 359 | 368 | * |
| 360 | 369 | * Return true if the specified key has been positively instantiated, false |
| 361 | 370 | * otherwise. |
| 362 | 371 | */ |
| 363 | −static inline bool key_is_instantiated(const struct key *key) | |
| 372 | +static inline bool key_is_positive(const struct key *key) | |
| 373 | +{ | |
| 374 | + return key_read_state(key) == KEY_IS_POSITIVE; | |
| 375 | +} | |
| 376 | + | |
| 377 | +static inline bool key_is_negative(const struct key *key) | |
| 364 | 378 | { |
| 365 | − return test_bit(KEY_FLAG_INSTANTIATED, &key->flags) && | |
| 366 | − !test_bit(KEY_FLAG_NEGATIVE, &key->flags); | |
| 379 | + return key_read_state(key) < 0; | |
| 367 | 380 | } |
| 368 | 381 | |
| 369 | 382 | #define dereference_key_rcu(KEY) \ |