The following commit has been merged into the x86/shstk branch of tip: Commit-ID: 11c95c77eef6d56c1ef9f55d8afd83ceb6d99996 Gitweb: https://git.kernel.org/tip/11c95c77eef6d56c1ef9f55d8afd83ceb6d99996 Author: Rick Edgecombe <rick.p.edgecombe@xxxxxxxxx> AuthorDate: Sat, 25 Mar 2023 12:33:49 -07:00 Committer: Dave Hansen <dave.hansen@xxxxxxxxxxxxxxx> CommitterDate: Mon, 27 Mar 2023 17:55:51 -07:00 x86/shstk: Enforce only whole copies for ssp_set() The regset set interface takes pos and count arguments to allow for partial copies. No callers use a non-zero pos, but ptrace allows for the count to be specified. It limits count to be a multiple of regset size, so this still allows for a zero size to be passed to ssp_set(). In ssp_set(), user_regset_copyin() returns success for copying zero bytes, which means user_ssp can later be accessed uninitialized. So add enforcement for this case. The other regset's also enforce pos == 0, so do that as well even though there is no caller today. In the case of partial copies, some regsets return -EINVAL and some return -EFAULT. -EINVAL seems more appropriate, so use that error code. Fixes: d84e6ee122e5 ("x86: Add PTRACE interface for shadow stack") Reported-by: Dan Carpenter <error27@xxxxxxxxx> Signed-off-by: Rick Edgecombe <rick.p.edgecombe@xxxxxxxxx> Signed-off-by: Dave Hansen <dave.hansen@xxxxxxxxxxxxxxx> Link: https://lore.kernel.org/all/90af27cc-6c9d-4fb9-be3b-fc4ef378766d@kili.mountain/ Link: https://lore.kernel.org/all/20230325193349.31893-1-rick.p.edgecombe%40intel.com --- arch/x86/kernel/fpu/regset.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/arch/x86/kernel/fpu/regset.c b/arch/x86/kernel/fpu/regset.c index f0a8eaf..6bc1eb2 100644 --- a/arch/x86/kernel/fpu/regset.c +++ b/arch/x86/kernel/fpu/regset.c @@ -223,6 +223,9 @@ int ssp_set(struct task_struct *target, const struct user_regset *regset, !ssp_active(target, regset)) return -ENODEV; + if (pos != 0 || count != sizeof(user_ssp)) + return -EINVAL; + r = user_regset_copyin(&pos, &count, &kbuf, &ubuf, &user_ssp, 0, -1); if (r) return r;