Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1)

Side by Side Diff: src/trusted/validator/x86/ncval_seg_sfi/ncvalidate.c

Issue 9328024: Merge 7712 - Ensure super instructions are marked during dynamic code modification. (Closed) Base URL: svn://svn.chromium.org/native_client/branches/963/src/native_client/
Patch Set: '' Created 8 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 /* 1 /*
2 * Copyright (c) 2011 The Native Client Authors. All rights reserved. 2 * Copyright (c) 2011 The Native Client Authors. All rights reserved.
3 * Use of this source code is governed by a BSD-style license that can be 3 * Use of this source code is governed by a BSD-style license that can be
4 * found in the LICENSE file. 4 * found in the LICENSE file.
5 */ 5 */
6 6
7 /* 7 /*
8 * ncvalidate.c 8 * ncvalidate.c
9 * Validate x86 instructions for Native Client 9 * Validate x86 instructions for Native Client
10 * 10 *
(...skipping 387 matching lines...) Expand 10 before | Expand all | Expand 10 after
398 vprint(vstate, (reporter, 398 vprint(vstate, (reporter,
399 "RememberIP: Saw inst at %"NACL_PRIxNaClPcAddressAll 399 "RememberIP: Saw inst at %"NACL_PRIxNaClPcAddressAll
400 " twice\n", ip)); 400 " twice\n", ip));
401 NCStatsInternalError(vstate); 401 NCStatsInternalError(vstate);
402 return; 402 return;
403 } 403 }
404 NCStatsInst(vstate); 404 NCStatsInst(vstate);
405 NCSetAdrTable(ioffset, vstate->vttable); 405 NCSetAdrTable(ioffset, vstate->vttable);
406 } 406 }
407 407
408 static void RememberTP(const NaClPcAddress src, NaClPcAddress target, 408 static void RememberTP(const NCDecoderInst *dinst, const NaClPcAddress src,
409 struct NCValidatorState *vstate) { 409 NaClPcAddress target, struct NCValidatorState *vstate) {
410 const NaClMemorySize ioffset = target - vstate->iadrbase; 410 const NaClMemorySize ioffset = target - vstate->iadrbase;
411 411
412 if (NCAddressInMemoryRange(target, vstate)) { 412 if (NCAddressInMemoryRange(target, vstate)) {
413 NCSetAdrTable(ioffset, vstate->kttable); 413 NCSetAdrTable(ioffset, vstate->kttable);
414 } 414 }
415 else if ((target & vstate->alignmask) == 0) { 415 else if ((target & vstate->alignmask) == 0) {
416 /* Allow bundle-aligned jumps. */ 416 /* Allow bundle-aligned jumps. */
417 } 417 } else if (dinst->unchanged) {
418 else { 418 /* If we are replacing this instruction during dynamic code modification
419 * and it has not changed, the jump target must be valid because the
420 * instruction has been previously validated. However, we may be only
421 * replacing a subsection of the code segment and therefore may not have
422 * information about instruction boundries outside of the code being
423 * replaced. Therefore, we allow unaligned direct jumps outside of the code
424 * being validated if and only if the instruction is unchanged.
425 * If dynamic code replacement is not being performed, inst->unchanged
426 * should always be false.
427 */
428 } else {
419 ValidatePrintError(src, "JUMP TARGET out of range", vstate); 429 ValidatePrintError(src, "JUMP TARGET out of range", vstate);
420 NCStatsBadTarget(vstate); 430 NCStatsBadTarget(vstate);
421 } 431 }
422 } 432 }
423 433
424 static void ForgetIP(const NaClPcAddress ip, 434 static void ForgetIP(const NaClPcAddress ip,
425 struct NCValidatorState *vstate) { 435 struct NCValidatorState *vstate) {
426 NaClMemorySize ioffset = ip - vstate->iadrbase; 436 NaClMemorySize ioffset = ip - vstate->iadrbase;
427 if (!NCAddressInMemoryRange(ip, vstate)) { 437 if (!NCAddressInMemoryRange(ip, vstate)) {
428 ValidatePrintError(ip, "JUMP TARGET out of range in ForgetIP", vstate); 438 ValidatePrintError(ip, "JUMP TARGET out of range in ForgetIP", vstate);
(...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after
503 } 513 }
504 } 514 }
505 515
506 static void ValidateJmp8(const NCDecoderInst *dinst) { 516 static void ValidateJmp8(const NCDecoderInst *dinst) {
507 int8_t offset = NCInstBytesByteInline(&dinst->inst_bytes, 517 int8_t offset = NCInstBytesByteInline(&dinst->inst_bytes,
508 dinst->inst.prefixbytes+1); 518 dinst->inst.prefixbytes+1);
509 struct NCValidatorState* vstate = NCVALIDATOR_STATE_DOWNCAST(dinst->dstate); 519 struct NCValidatorState* vstate = NCVALIDATOR_STATE_DOWNCAST(dinst->dstate);
510 NaClPcAddress target = 520 NaClPcAddress target =
511 dinst->vpc + dinst->inst.bytes.length + offset; 521 dinst->vpc + dinst->inst.bytes.length + offset;
512 NCStatsCheckTarget(vstate); 522 NCStatsCheckTarget(vstate);
513 RememberTP(dinst->vpc, target, vstate); 523 RememberTP(dinst, dinst->vpc, target, vstate);
514 } 524 }
515 525
516 static void ValidateJmpz(const NCDecoderInst *dinst) { 526 static void ValidateJmpz(const NCDecoderInst *dinst) {
517 NCInstBytesPtr opcode; 527 NCInstBytesPtr opcode;
518 uint8_t opcode0; 528 uint8_t opcode0;
519 int32_t offset; 529 int32_t offset;
520 NaClPcAddress target; 530 NaClPcAddress target;
521 NCValidatorState* vstate = NCVALIDATOR_STATE_DOWNCAST(dinst->dstate); 531 NCValidatorState* vstate = NCVALIDATOR_STATE_DOWNCAST(dinst->dstate);
522 NCInstBytesPtrInitInc(&opcode, &dinst->inst_bytes, 532 NCInstBytesPtrInitInc(&opcode, &dinst->inst_bytes,
523 dinst->inst.prefixbytes); 533 dinst->inst.prefixbytes);
(...skipping 11 matching lines...) Expand all
535 * E8: call $Jz 545 * E8: call $Jz
536 * E9: jmp $Jx 546 * E9: jmp $Jx
537 */ 547 */
538 NCInstBytesPtr opcode_1; 548 NCInstBytesPtr opcode_1;
539 NCInstBytesPtrInitInc(&opcode_1, &opcode, 1); 549 NCInstBytesPtrInitInc(&opcode_1, &opcode, 1);
540 offset = NCInstBytesInt32(&opcode_1); 550 offset = NCInstBytesInt32(&opcode_1);
541 /* as a courtesy, check call alignment correctness */ 551 /* as a courtesy, check call alignment correctness */
542 if (opcode0 == 0xe8) ValidateCallAlignment(dinst); 552 if (opcode0 == 0xe8) ValidateCallAlignment(dinst);
543 } 553 }
544 target = dinst->vpc + dinst->inst.bytes.length + offset; 554 target = dinst->vpc + dinst->inst.bytes.length + offset;
545 RememberTP(dinst->vpc, target, vstate); 555 RememberTP(dinst, dinst->vpc, target, vstate);
546 } 556 }
547 557
548 /* 558 /*
549 * The NaCl five-byte safe indirect calling sequence looks like this: 559 * The NaCl five-byte safe indirect calling sequence looks like this:
550 * 83 e0 e0 and $0xe0,%eax 560 * 83 e0 e0 and $0xe0,%eax
551 * ff d0 call *%eax 561 * ff d0 call *%eax
552 * The call may be replaced with a ff e0 jmp. Any register may 562 * The call may be replaced with a ff e0 jmp. Any register may
553 * be used, not just eax. The validator requires exactly this 563 * be used, not just eax. The validator requires exactly this
554 * sequence. 564 * sequence.
555 * Note: The code above assumes 32-bit alignment. Change e0 as appropriate 565 * Note: The code above assumes 32-bit alignment. Change e0 as appropriate
(...skipping 332 matching lines...) Expand 10 before | Expand all | Expand 10 after
888 NCStatsUnsafeIndirect(NCVALIDATOR_STATE_DOWNCAST(dinst_new->dstate)); 898 NCStatsUnsafeIndirect(NCVALIDATOR_STATE_DOWNCAST(dinst_new->dstate));
889 } 899 }
890 900
891 /* 901 /*
892 * Check that mstate_new is a valid replacement instruction for mstate_old. 902 * Check that mstate_new is a valid replacement instruction for mstate_old.
893 * Note that mstate_old was validated when it was inserted originally. 903 * Note that mstate_old was validated when it was inserted originally.
894 */ 904 */
895 static Bool ValidateInstReplacement(NCDecoderStatePair* tthis, 905 static Bool ValidateInstReplacement(NCDecoderStatePair* tthis,
896 NCDecoderInst *dinst_old, 906 NCDecoderInst *dinst_old,
897 NCDecoderInst *dinst_new) { 907 NCDecoderInst *dinst_new) {
908
909
898 /* Only validate individual instructions that have changed. */ 910 /* Only validate individual instructions that have changed. */
899 if (memcmp(dinst_old->inst.bytes.byte, 911 dinst_new->unchanged = memcmp(dinst_old->inst.bytes.byte,
900 dinst_new->inst.bytes.byte, 912 dinst_new->inst.bytes.byte,
901 dinst_new->inst.bytes.length)) { 913 dinst_new->inst.bytes.length) == 0;
902 /* Call single instruction validator first, will call ValidateIndirect5() */ 914 ValidateInst(dinst_new);
903 ValidateInst(dinst_new);
904 } else {
905 /* Still need to record there is an intruction here for NCValidateFinish()
906 * to verify basic block alignment.
907 */
908 RememberIP(dinst_new->vpc, NCVALIDATOR_STATE_DOWNCAST(dinst_new->dstate));
909 }
910 915
911 if (dinst_old->opinfo->insttype == NACLi_INDIRECT 916 if (dinst_old->opinfo->insttype == NACLi_INDIRECT
912 || dinst_new->opinfo->insttype == NACLi_INDIRECT) { 917 || dinst_new->opinfo->insttype == NACLi_INDIRECT) {
913 /* Verify that nacljmps never change */ 918 /* Verify that nacljmps never change */
914 ValidateIndirect5Replacement(dinst_old, dinst_new); 919 ValidateIndirect5Replacement(dinst_old, dinst_new);
915 } 920 }
916 return TRUE; 921 return TRUE;
917 } 922 }
918 923
919 /* Create the decoder state for the validator state, using the 924 /* Create the decoder state for the validator state, using the
(...skipping 106 matching lines...) Expand 10 before | Expand all | Expand 10 after
1026 /* check basic block boundaries */ 1031 /* check basic block boundaries */
1027 for (offset = 0; offset < vstate->iadrlimit - vstate->iadrbase; 1032 for (offset = 0; offset < vstate->iadrlimit - vstate->iadrbase;
1028 offset += vstate->alignment) { 1033 offset += vstate->alignment) {
1029 if (!NCGetAdrTable(offset, vstate->vttable)) { 1034 if (!NCGetAdrTable(offset, vstate->vttable)) {
1030 ValidatePrintError(vstate->iadrbase + offset, 1035 ValidatePrintError(vstate->iadrbase + offset,
1031 "Bad basic block alignment", vstate); 1036 "Bad basic block alignment", vstate);
1032 NCStatsBadAlignment(vstate); 1037 NCStatsBadAlignment(vstate);
1033 } 1038 }
1034 } 1039 }
1035 } 1040 }
OLDNEW
« no previous file with comments | « src/trusted/validator/x86/ncval_seg_sfi/ncdecode.c ('k') | tests/dynamic_code_loading/dynamic_modify_test.c » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698