Last active
August 8, 2024 10:30
-
-
Save legionus/e990834da836da0e5d7330876e50469e to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
diff --git a/arch/x86/coco/tdx/tdx.c b/arch/x86/coco/tdx/tdx.c | |
index 5b3421a89998..992cc3f19f52 100644 | |
--- a/arch/x86/coco/tdx/tdx.c | |
+++ b/arch/x86/coco/tdx/tdx.c | |
@@ -494,16 +494,44 @@ static int decode_insn_struct(struct insn *insn, struct pt_regs *regs) | |
char buffer[MAX_INSN_SIZE]; | |
if (user_mode(regs)) { | |
- int nr_copied = insn_fetch_from_user(regs, buffer); | |
+ int not_copied, nr_copied, size; | |
+ unsigned long ip, offset; | |
+ char *dst, __user *src; | |
+ | |
+ if (insn_get_effective_ip(regs, &ip)) | |
+ return -EFAULT; | |
+ | |
+ offset = offset_in_page(ip); | |
+ src = (char __user *)ip; | |
+ | |
+ dst = buffer; | |
+ size = MAX_INSN_SIZE; | |
+ nr_copied = 0; | |
+ | |
+ if (unlikely(offset + size > PAGE_SIZE)) { | |
+ size = PAGE_SIZE - offset; | |
+ | |
+ not_copied = copy_from_user(dst, src, size); | |
+ nr_copied = size - not_copied; | |
+ | |
+ if (nr_copied <= 0) | |
+ nr_copied = 0; | |
+ else if (insn_decode_from_regs(insn, regs, buffer, nr_copied)) | |
+ goto decoded; | |
+ | |
+ size = MAX_INSN_SIZE - nr_copied; | |
+ dst += nr_copied; | |
+ src += nr_copied; | |
+ } | |
+ | |
+ not_copied = copy_from_user(dst, src, size); | |
+ nr_copied += size - not_copied; | |
if (nr_copied <= 0) | |
return -EFAULT; | |
if (!insn_decode_from_regs(insn, regs, buffer, nr_copied)) | |
return -EINVAL; | |
- | |
- if (!insn->immediate.got) | |
- return -EINVAL; | |
} else { | |
if (copy_from_kernel_nofault(buffer, (void *)regs->ip, MAX_INSN_SIZE)) | |
return -EFAULT; | |
@@ -511,6 +539,10 @@ static int decode_insn_struct(struct insn *insn, struct pt_regs *regs) | |
if (insn_decode(insn, buffer, MAX_INSN_SIZE, INSN_MODE_64)) | |
return -EINVAL; | |
} | |
+decoded: | |
+ if (!insn->immediate.got) | |
+ return -EINVAL; | |
+ | |
return 0; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment