Straightforward, except for save_altstack_ex() stuck in those. Replace that thing with an analogue that would use unsafe_put_user() instead of put_user_ex() (called compat_save_altstack()) and be done with that.
Showing the changes to include/linux (1 of 2 files). Show all
Unified · Split
| @@ -444,12 +444,12 @@ void signals_init(void); · 443 unmodified lines | |||
| 444 | int restore_altstack(const stack_t __user *); | 444 | int restore_altstack(const stack_t __user *); |
| 445 | int __save_altstack(stack_t __user *, unsigned long); | 445 | int __save_altstack(stack_t __user *, unsigned long); |
| 446 | 446 | ||
| 447 | #define save_altstack_ex(uss, sp) do { \ | 447 | #define unsafe_save_altstack(uss, sp, label) do { \ |
| 448 | stack_t __user *__uss = uss; \ | 448 | stack_t __user *__uss = uss; \ |
| 449 | struct task_struct *t = current; \ | 449 | struct task_struct *t = current; \ |
| 450 | put_user_ex((void __user *)t->sas_ss_sp, &__uss->ss_sp); \ | 450 | unsafe_put_user((void __user *)t->sas_ss_sp, &__uss->ss_sp, label); \ |
| 451 | put_user_ex(t->sas_ss_flags, &__uss->ss_flags); \ | 451 | unsafe_put_user(t->sas_ss_flags, &__uss->ss_flags, label); \ |
| 452 | put_user_ex(t->sas_ss_size, &__uss->ss_size); \ | 452 | unsafe_put_user(t->sas_ss_size, &__uss->ss_size, label); \ |
| 453 | if (t->sas_ss_flags & SS_AUTODISARM) \ | 453 | if (t->sas_ss_flags & SS_AUTODISARM) \ |
| 454 | sas_ss_reset(t); \ | 454 | sas_ss_reset(t); \ |
| 455 | } while (0); | 455 | } while (0); |