x86: properly initialize temp insn buffer for paravirt patching
authorChris Wright <chrisw@sous-sol.org>
Sat, 18 Aug 2007 21:31:41 +0000 (14:31 -0700)
committerLinus Torvalds <torvalds@woody.linux-foundation.org>
Sat, 18 Aug 2007 22:15:54 +0000 (15:15 -0700)
With commit ab144f5ec64c42218a555ec1dbde6b60cf2982d6 the patching code
now collects the complete new instruction stream into a temp buffer
before finally patching in the new insns.  In some cases the paravirt
patchers will choose to leave the patch site unpatched (length mismatch,
clobbers mismatch, etc).

This causes the new patching code to copy an uninitialized temp buffer,
i.e.  garbage, to the callsite.  Simply make sure to always initialize
the buffer with the original instruction stream.  A better fix is to
audit all the patchers and return proper length so that apply_paravirt()
can skip copies when we leave the patch site untouched.

Signed-off-by: Chris Wright <chrisw@sous-sol.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
arch/i386/kernel/alternative.c

index 1b66d5c70eaf65fc88fa1146313071843a069993..9f4ac8b02de407f756bf69e7756ac5422f5cb0a7 100644 (file)
@@ -366,6 +366,8 @@ void apply_paravirt(struct paravirt_patch_site *start,
                unsigned int used;
 
                BUG_ON(p->len > MAX_PATCH_LEN);
+               /* prep the buffer with the original instructions */
+               memcpy(insnbuf, p->instr, p->len);
                used = paravirt_ops.patch(p->instrtype, p->clobbers, insnbuf,
                                          (unsigned long)p->instr, p->len);