Change keyctl_session_to_parent() to use task_work_add() and move key_replace_session_keyring() logic into task_work->func(). Note that we do task_work_cancel() before task_work_add() to ensure that only one work can be pending at any time. This is important, we must not allow user-space to abuse the parent's ->task_works list. The callback, replace_session_keyring(), checks PF_EXITING. I guess this is not really needed but looks better. As a side effect, this fixes the (unlikely) race. The callers of key_replace_session_keyring() and keyctl_session_to_parent() lack the necessary barriers, the parent can miss the request. Now we can remove task_struct->replacement_session_keyring and related code.
Showing the changes to include (1 of 4 files). Show all
Unified · Split
| @@ -33,6 +33,8 @@ typedef uint32_t key_perm_t; · 32 unmodified lines | |||
| 33 | 33 | ||
| 34 | struct key; | 34 | struct key; |
| 35 | 35 | ||
| 36 | #define key_replace_session_keyring() do { } while (0) | ||
| 37 | |||
| 36 | #ifdef CONFIG_KEYS | 38 | #ifdef CONFIG_KEYS |
| 37 | 39 | ||
| 38 | #undef KEY_DEBUGGING | 40 | #undef KEY_DEBUGGING |
| @@ -308,9 +310,6 @@ static inline bool key_is_instantiated(const struct key *key) · 269 unmodified lines | |||
| 308 | #ifdef CONFIG_SYSCTL | 310 | #ifdef CONFIG_SYSCTL |
| 309 | extern ctl_table key_sysctls[]; | 311 | extern ctl_table key_sysctls[]; |
| 310 | #endif | 312 | #endif |
| 311 | |||
| 312 | extern void key_replace_session_keyring(void); | ||
| 313 | |||
| 314 | /* | 313 | /* |
| 315 | * the userspace interface | 314 | * the userspace interface |
| 316 | */ | 315 | */ |
| @@ -334,7 +333,6 @@ extern void key_init(void); · 17 unmodified lines | |||
| 334 | #define key_fsuid_changed(t) do { } while(0) | 333 | #define key_fsuid_changed(t) do { } while(0) |
| 335 | #define key_fsgid_changed(t) do { } while(0) | 334 | #define key_fsgid_changed(t) do { } while(0) |
| 336 | #define key_init() do { } while(0) | 335 | #define key_init() do { } while(0) |
| 337 | #define key_replace_session_keyring() do { } while(0) | ||
| 338 | 336 | ||
| 339 | #endif /* CONFIG_KEYS */ | 337 | #endif /* CONFIG_KEYS */ |
| 340 | #endif /* __KERNEL__ */ | 338 | #endif /* __KERNEL__ */ |