I will need to modify and harden the Squeak VM to run untrusted bytecodes.
The changes are:
Open question: can the state of the stack be predicted by a verifier? The verifier would need to trace through the code.
The following situation could leave an unknown number of items on the stack:
1 push something.
2 send a message to compare two things
3 pop and jump if true to 5.
4 jump to 1
5 ...continue
A code tracer would need to analyse instructions 2 and 3 to determine how many times the loop would iterate. This bears a resemblence to the halting problem.
Perhaps the above code would never be generated by a compiler? TODO: are pushes and pops able to be generated in a loop by the compiler? Does the compiler guarantee that a loop will do as many pops as it does pushes?
These will all need checking to make sure that they write or read existant locations. This can be checked by a code verifier.
The size of the stack needs to be checked after the method completes to make sure no entries are left. This may be achievable by a code verifier doing a... data flow analysis? Alternatively, the execution stack could consist of frames, and each frame could have its own stack which these instructions manipulate (?). A lower bounds check would need to be implemented in either case. An upper bounds check would be needed for resource control.
The VM must check to make sure the stack isn't empty. I suspect it doesn't check for this.
...unless the compiler never generates a stack pop or push in a loop?
These are benign except for items left on the stack at completion.
The return message needs investigating. How does it know where to return to; is the calling context also pushed onto the stack? If that is the case, then it must not be accessable by other stack operations.
Knowing Squeak, these won't be unused. Invalid bytecodes will need to be looked into.
Refers to the top of the stack.
Should be okay if superclass is valid. If a DNU occurs, then don't halt the VM!
We need to make sure that a method doesn't pop stuff off the stack that doesn't belong to it.
Ditto - when returning, we need to make sure only the return value is sitting on the stack. Perhaps we could make a special stack just for a method's invocation?
We don't want untrusted code seeing the active context, right? Better to push a proxy to it, or have the active context check who the sender is.
These are probably used in Squeak.
These two are only a problem if they occur near the beginning or the end of a method. They can be checked for by a verifier.
All jump instructions have the destination hard-coded, meaning that they can be verified easily by a verifier before the method is executed.
This really needs bounds checking, but only if it occurs near the end (or the beginning?) of the method. This case can be checked for by a code sanity checker.
The last two are also stack operations which need to be checked to make sure the stack is sane.
If these use the stack, then the stack has to be left in a sane state. Also, objects popped from the stack must be valid object references and not SmallIntegers.
The literal selectors must have their bounds checked.
Most of the operations affect the stack; sanity will need checking. I assume these would all be invoked using the send bytecod
1 SmallInteger +
2 SmallInteger -
3 SmallInteger <
4 SmallInteger >
5* SmallInteger <=
6* SmallInteger >=
7 SmallInteger =
8* SmallInteger ~=
9 SmallInteger *
10* SmallInteger /
11* SmallInteger \\
12* SmallInteger //
13 SmallInteger quo:
14 SmallInteger bitAnd:
15 SmallInteger bitOr:
16 SmallInteger bitXor:
17 SmallInteger bitShift:
18* Number @
19
20
21* Integer +, LargePositiveInteger +
22* Integer - , LargePositiveInteger -
23* Integer < , LargePositiveInteger <
24* Integer > , LargePositiveInteger >
25* Integer <= , LargePositiveInteger <=
26 Integer >= , LargePositiveInteger >=
27* Integer = ,LargePositiveInteger =
28* Integer ~= , LargePositiveInteger ~=
29* Integer * , LargePositiveInteger *
30* Integer / , LargePositiveInteger /
31* Integer \\ , LargePositiveInteger \\
32* Integer // , LargePositiveInteger //
33* Integer quo: , LargePositiveInteger quo:
34* Integer bitAnd:, LargePositiveInteger bitAnd:
35* Integer bitOr: , LargePositiveInteger bitOr:
36* Integer bitXor: , LargePositiveInteger bitXor:
37* Integer bitShift: , LargePositiveInteger bitShift:
The operations above all pop two elements off the stack and push the result. Stack sanity would need checking.
38
39
40 SmallInteger asFloat
This pops a SmallInteger and pushes a float; stack bounds need checking.
41 Float +
42 Float -
43 Float <
44 Float >
45* Float <=
46* Float >=
47 Float =
48* Float ~=
49 Float *
50 Float /
51 Float truncated
52* Float fractionPart
53* Float exponent
54* Float timesTwoPower:
Ditto for stack manipulations.
55
56
57
58
59
60 LargeNegativeInteger digitAt:, LargePositiveInteger digitAt:, Object at:, Object basicAt:
61 LargeNegativeInteger digitAt:put:, LargePositiveInteger digitAt:put:, Object basicAt:put:, Object at:put:
Obviously these should be moved out and into a separate class which keeps these primitives safely locked away as capabilities.
62 ArrayedCollection size, LargeNegativeInteger digitLength, LargePositiveInteger digitLength, Object basicSize, Object size, String size
63 String at:, String basicAt:
64 String basicAt:put:, String at:put:
Assuming that Strings are mutable. These should not be applyable to Symbols.
65* ReadStream next, ReadWriteStream next
66* WriteStream nextPut:
67* PositionableStream atEnd
68 CompiledMethod objectAt:
69 CompiledMethod objectAt:put:
These two should be safe provided that untrusted code does not have access to compiled methods. It would be good to be consistent with other at:put: implementations and put this functionality in a capability.
70 Behavior basicNew, Behavior new, Interval class new
71 Behavior new:, Behavior basicNew:
These will be subject to dominion constraints.
72 Object become:
73 Object instVarAt:
74 Object instVarAt:put:
Move these to a capability.
75 Object asOop, Object hash, Symbol hash
76 SmallInteger asObject, SmallInteger asObjectNoFail
Object asOop could be a security concern if there is an unnoticed security hole elsewhere; asOop could be used to forge a reference if a hole is found elsewhere.
77 Behavior someInstance
78 Object nextInstance
Move these to a capability.
79 CompiledMethod class newMethod:header:
See CompiledMethod methods further above.
80* ContextPart blockCopy:
81 BlockContext value:value:value:, BlockContext value, BlockContext value:, BlockContext value:value:
82 BlockContext valueWithArguments:
Benign? More thought needed.
83* Object perform:with:with:with:, Object perform:with:, Object perform:with:with:, Object perform:
84 Object perform:withArguments:
These are required and equivalent to normal message sends.
85 Semaphore signal
86 Semaphore wait
87 Process resume
88 Process suspend
These are okay.
89 Behavior flushCache
Could this be perhaps used to deny service?
90* InputSensor primMousePt, InputState primMousePt
91 InputState primCursorLocPut: ,InputState primCursorLocPutAgain:
92 Cursor class cursorLink:
93 InputState primInputSemaphore:
94 InputState primSampleInterval:
95 InputState primInputWord
TODO?
96 BitBlt copyBitsAgain, BitBlt copyBits
Subject to dominion constraints.
97 SystemDictionary snapshotPrimitive
Should be a capability, or access to SystemDictionary is denied.
98 Time class secondClockInto:
99 Time class millisecondClockInto:
100 ProcessorScheduler signal:atMilliseconds:
101 Cursor beCursor
102 DisplayScreen beDisplay
103* CharacterScanner scanCharactersFrom:to:in:rightX:stopConditions:displaying:
104* BitBlt drawLoopX:Y:
105* ByteArray primReplaceFrom:to:with:startingAt:, ByteArray replaceFrom:to:withString:startingAt:, String replaceFrom:to:withByteArray:startingAt:, String primReplaceFrom:to:with;startingAt:
Assuming ByteArrays and Strings are mutable.
106
107
108
109
110 Character =, Object ==
111 Object class
"Object class" has proven problematic when implementing message proxies.
112 SystemDictionary coreLeft
113 SystemDictionary quitPrimitive
114 SystemDictionary exitToDebugger
115 SystemDictionary oopsLeft
116 SystemDictionary signal:atOopsLeft:wordsLeft:
These are okay provided that access to SystemDictionary is denied.
http://java.sun.com/docs/books/jvms/second_edition/html/ClassFile.doc.html#88597
Page Information
|
Wiki Information |
Recent PBwiki Blog Posts |