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

Side by Side Diff: src/runtime.cc

Issue 6286020: Better security checks when accessing named properties via Object.getOwnPropertyDescriptor. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Addressing Mads' comments Created 9 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
« no previous file with comments | « no previous file | test/cctest/test-api.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2010 the V8 project authors. All rights reserved. 1 // Copyright 2010 the V8 project authors. All rights reserved.
2 // Redistribution and use in source and binary forms, with or without 2 // Redistribution and use in source and binary forms, with or without
3 // modification, are permitted provided that the following conditions are 3 // modification, are permitted provided that the following conditions are
4 // met: 4 // met:
5 // 5 //
6 // * Redistributions of source code must retain the above copyright 6 // * Redistributions of source code must retain the above copyright
7 // notice, this list of conditions and the following disclaimer. 7 // notice, this list of conditions and the following disclaimer.
8 // * Redistributions in binary form must reproduce the above 8 // * Redistributions in binary form must reproduce the above
9 // copyright notice, this list of conditions and the following 9 // copyright notice, this list of conditions and the following
10 // disclaimer in the documentation and/or other materials provided 10 // disclaimer in the documentation and/or other materials provided
(...skipping 626 matching lines...) Expand 10 before | Expand all | Expand 10 after
637 if (!result->IsProperty()) { 637 if (!result->IsProperty()) {
638 Object* proto = obj->GetPrototype(); 638 Object* proto = obj->GetPrototype();
639 if (proto->IsJSObject() && 639 if (proto->IsJSObject() &&
640 JSObject::cast(proto)->map()->is_hidden_prototype()) 640 JSObject::cast(proto)->map()->is_hidden_prototype())
641 GetOwnPropertyImplementation(JSObject::cast(proto), 641 GetOwnPropertyImplementation(JSObject::cast(proto),
642 name, result); 642 name, result);
643 } 643 }
644 } 644 }
645 645
646 646
647 static bool CheckAccessException(LookupResult* result,
648 v8::AccessType access_type) {
649 if (result->type() == CALLBACKS) {
650 Object* callback = result->GetCallbackObject();
651 if (callback->IsAccessorInfo()) {
652 AccessorInfo* info = AccessorInfo::cast(callback);
653 bool can_access =
654 (access_type == v8::ACCESS_HAS &&
655 (info->all_can_read() || info->all_can_write())) ||
656 (access_type == v8::ACCESS_GET && info->all_can_read()) ||
657 (access_type == v8::ACCESS_SET && info->all_can_write());
658 return can_access;
659 }
660 }
661
662 return false;
663 }
664
665
666 static bool CheckAccess(JSObject* obj,
667 String* name,
668 LookupResult* result,
669 v8::AccessType access_type) {
670 ASSERT(result->IsProperty());
671
672 JSObject* holder = result->holder();
673 JSObject* current = obj;
674 while (true) {
675 if (current->IsAccessCheckNeeded() &&
676 !Top::MayNamedAccess(current, name, access_type)) {
677 // Access check callback denied the access, but some properties
678 // can have a special permissions which override callbacks descision
679 // (currently see v8::AccessControl).
680 break;
681 }
682
683 if (current == holder) {
684 return true;
685 }
686
687 current = JSObject::cast(current->GetPrototype());
688 }
689
690 // API callbacks can have per callback access exceptions.
691 switch (result->type()) {
692 case CALLBACKS: {
693 if (CheckAccessException(result, access_type)) {
694 return true;
695 }
696 break;
697 }
698 case INTERCEPTOR: {
699 // If the object has an interceptor, try real named properties.
700 // Overwrite the result to fetch the correct property later.
701 holder->LookupRealNamedProperty(name, result);
702 if (result->IsProperty()) {
703 if (CheckAccessException(result, access_type)) {
704 return true;
705 }
706 }
707 break;
708 }
709 default:
710 break;
711 }
712
713 Top::ReportFailedAccessCheck(current, access_type);
714 return false;
715 }
716
717
647 // Enumerator used as indices into the array returned from GetOwnProperty 718 // Enumerator used as indices into the array returned from GetOwnProperty
648 enum PropertyDescriptorIndices { 719 enum PropertyDescriptorIndices {
649 IS_ACCESSOR_INDEX, 720 IS_ACCESSOR_INDEX,
650 VALUE_INDEX, 721 VALUE_INDEX,
651 GETTER_INDEX, 722 GETTER_INDEX,
652 SETTER_INDEX, 723 SETTER_INDEX,
653 WRITABLE_INDEX, 724 WRITABLE_INDEX,
654 ENUMERABLE_INDEX, 725 ENUMERABLE_INDEX,
655 CONFIGURABLE_INDEX, 726 CONFIGURABLE_INDEX,
656 DESCRIPTOR_SIZE 727 DESCRIPTOR_SIZE
(...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after
739 } 810 }
740 } 811 }
741 812
742 // Use recursive implementation to also traverse hidden prototypes 813 // Use recursive implementation to also traverse hidden prototypes
743 GetOwnPropertyImplementation(*obj, *name, &result); 814 GetOwnPropertyImplementation(*obj, *name, &result);
744 815
745 if (!result.IsProperty()) { 816 if (!result.IsProperty()) {
746 return Heap::undefined_value(); 817 return Heap::undefined_value();
747 } 818 }
748 819
820 if (!CheckAccess(*obj, *name, &result, v8::ACCESS_HAS)) {
821 return Heap::undefined_value();
822 }
823
749 elms->set(ENUMERABLE_INDEX, Heap::ToBoolean(!result.IsDontEnum())); 824 elms->set(ENUMERABLE_INDEX, Heap::ToBoolean(!result.IsDontEnum()));
750 elms->set(CONFIGURABLE_INDEX, Heap::ToBoolean(!result.IsDontDelete())); 825 elms->set(CONFIGURABLE_INDEX, Heap::ToBoolean(!result.IsDontDelete()));
751 826
752 bool is_js_accessor = (result.type() == CALLBACKS) && 827 bool is_js_accessor = (result.type() == CALLBACKS) &&
753 (result.GetCallbackObject()->IsFixedArray()); 828 (result.GetCallbackObject()->IsFixedArray());
754 829
755 if (is_js_accessor) { 830 if (is_js_accessor) {
756 // __defineGetter__/__defineSetter__ callback. 831 // __defineGetter__/__defineSetter__ callback.
832 elms->set(IS_ACCESSOR_INDEX, Heap::true_value());
833
757 FixedArray* structure = FixedArray::cast(result.GetCallbackObject()); 834 FixedArray* structure = FixedArray::cast(result.GetCallbackObject());
758 elms->set(IS_ACCESSOR_INDEX, Heap::true_value()); 835 if (CheckAccess(*obj, *name, &result, v8::ACCESS_GET)) {
759 elms->set(GETTER_INDEX, structure->get(0)); 836 elms->set(GETTER_INDEX, structure->get(0));
760 elms->set(SETTER_INDEX, structure->get(1)); 837 }
838 if (CheckAccess(*obj, *name, &result, v8::ACCESS_SET)) {
839 elms->set(SETTER_INDEX, structure->get(1));
840 }
761 } else { 841 } else {
762 elms->set(IS_ACCESSOR_INDEX, Heap::false_value()); 842 elms->set(IS_ACCESSOR_INDEX, Heap::false_value());
763 elms->set(WRITABLE_INDEX, Heap::ToBoolean(!result.IsReadOnly())); 843 elms->set(WRITABLE_INDEX, Heap::ToBoolean(!result.IsReadOnly()));
764 844
765 PropertyAttributes attrs; 845 PropertyAttributes attrs;
766 Object* value; 846 Object* value;
847 // GetProperty will check access and report any violations.
767 { MaybeObject* maybe_value = obj->GetProperty(*obj, &result, *name, &attrs); 848 { MaybeObject* maybe_value = obj->GetProperty(*obj, &result, *name, &attrs);
768 if (!maybe_value->ToObject(&value)) return maybe_value; 849 if (!maybe_value->ToObject(&value)) return maybe_value;
769 } 850 }
770 elms->set(VALUE_INDEX, value); 851 elms->set(VALUE_INDEX, value);
771 } 852 }
772 853
773 return *desc; 854 return *desc;
774 } 855 }
775 856
776 857
(...skipping 10093 matching lines...) Expand 10 before | Expand all | Expand 10 after
10870 } else { 10951 } else {
10871 // Handle last resort GC and make sure to allow future allocations 10952 // Handle last resort GC and make sure to allow future allocations
10872 // to grow the heap without causing GCs (if possible). 10953 // to grow the heap without causing GCs (if possible).
10873 Counters::gc_last_resort_from_js.Increment(); 10954 Counters::gc_last_resort_from_js.Increment();
10874 Heap::CollectAllGarbage(false); 10955 Heap::CollectAllGarbage(false);
10875 } 10956 }
10876 } 10957 }
10877 10958
10878 10959
10879 } } // namespace v8::internal 10960 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « no previous file | test/cctest/test-api.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698