mirror of
https://github.com/taigrr/gopher-os
synced 2025-01-18 04:43:13 -08:00
acpi: fix bugs discovered by fuzzing
This commit is contained in:
parent
ddbddd2ea2
commit
f57aa9433d
@ -284,7 +284,7 @@ func (tree *ObjectTree) Find(scopeIndex uint32, expr []byte) uint32 {
|
|||||||
// The expression consists of multiple name segments joined together (e.g. FOOFBAR0)
|
// The expression consists of multiple name segments joined together (e.g. FOOFBAR0)
|
||||||
// In this case we need to apply relative lookup rules for FOOF.BAR0
|
// In this case we need to apply relative lookup rules for FOOF.BAR0
|
||||||
return tree.findRelative(scopeIndex, expr)
|
return tree.findRelative(scopeIndex, expr)
|
||||||
default:
|
case exprLen == amlNameLen:
|
||||||
// expr is a simple name. According to the spec, we need to
|
// expr is a simple name. According to the spec, we need to
|
||||||
// search for it in this scope and all its parent scopes till
|
// search for it in this scope and all its parent scopes till
|
||||||
// we reach the root.
|
// we reach the root.
|
||||||
@ -320,7 +320,8 @@ nextSegment:
|
|||||||
// case skip over them.
|
// case skip over them.
|
||||||
for ; segIndex < exprLen && expr[segIndex] != '_' && (expr[segIndex] < 'A' || expr[segIndex] > 'Z'); segIndex++ {
|
for ; segIndex < exprLen && expr[segIndex] != '_' && (expr[segIndex] < 'A' || expr[segIndex] > 'Z'); segIndex++ {
|
||||||
}
|
}
|
||||||
if segIndex >= exprLen {
|
|
||||||
|
if exprLen-segIndex < amlNameLen {
|
||||||
return InvalidIndex
|
return InvalidIndex
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -41,6 +41,7 @@ type Parser struct {
|
|||||||
objTree *ObjectTree
|
objTree *ObjectTree
|
||||||
scopeStack []uint32
|
scopeStack []uint32
|
||||||
pkgEndStack []uint32
|
pkgEndStack []uint32
|
||||||
|
streamEnd uint32
|
||||||
|
|
||||||
resolvePasses uint32
|
resolvePasses uint32
|
||||||
mergedScopes uint32
|
mergedScopes uint32
|
||||||
@ -157,6 +158,8 @@ func (p *Parser) init(tableHandle uint8, tableName string, header *table.SDTHead
|
|||||||
uint32(unsafe.Sizeof(table.SDTHeader{})),
|
uint32(unsafe.Sizeof(table.SDTHeader{})),
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// Keep track of the stream end for parsing deferred objects
|
||||||
|
p.streamEnd = header.Length
|
||||||
_ = p.pushPkgEnd(header.Length)
|
_ = p.pushPkgEnd(header.Length)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -431,6 +434,7 @@ func (p *Parser) parseStrictTermArg(curObj *Object) (*Object, parseResult) {
|
|||||||
|
|
||||||
if !pOpIsType2(nextOp) && !pOpIsDataObject(nextOp) && !pOpIsArg(nextOp) {
|
if !pOpIsType2(nextOp) && !pOpIsDataObject(nextOp) && !pOpIsArg(nextOp) {
|
||||||
kfmt.Fprintf(p.errWriter, "[table: %s, offset: 0x%x] encountered unexpected opcode %s while parsing termArg\n", p.tableName, p.r.Offset(), pOpcodeName(nextOp))
|
kfmt.Fprintf(p.errWriter, "[table: %s, offset: 0x%x] encountered unexpected opcode %s while parsing termArg\n", p.tableName, p.r.Offset(), pOpcodeName(nextOp))
|
||||||
|
return nil, parseResultFailed
|
||||||
}
|
}
|
||||||
|
|
||||||
_, _ = p.nextOpcode()
|
_, _ = p.nextOpcode()
|
||||||
@ -985,8 +989,13 @@ func (p *Parser) pushPkgEnd(pkgEnd uint32) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (p *Parser) popPkgEnd() {
|
func (p *Parser) popPkgEnd() {
|
||||||
p.pkgEndStack = p.pkgEndStack[:len(p.pkgEndStack)-1]
|
// Pop pkg end if one exists
|
||||||
if len(p.pkgEndStack) != 0 {
|
if len(p.pkgEndStack) != 0 {
|
||||||
|
p.pkgEndStack = p.pkgEndStack[:len(p.pkgEndStack)-1]
|
||||||
|
}
|
||||||
|
|
||||||
|
// If the stack is not empty restore the last pushed pkgEnd
|
||||||
|
if len(p.pkgEndStack) != 0 && len(p.pkgEndStack) != 0 {
|
||||||
_ = p.r.SetPkgEnd(p.pkgEndStack[len(p.pkgEndStack)-1])
|
_ = p.r.SetPkgEnd(p.pkgEndStack[len(p.pkgEndStack)-1])
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1024,8 +1033,10 @@ func (p *Parser) connectNamedObjArgs(objIndex uint32) parseResult {
|
|||||||
return parseResultFailed
|
return parseResultFailed
|
||||||
}
|
}
|
||||||
|
|
||||||
// The last amlNameLen contain the name for this object
|
// The last amlNameLen part of the namepath contains the name for this object
|
||||||
nameIndex = len(namepath) - amlNameLen
|
if nameIndex = len(namepath) - amlNameLen; nameIndex < 0 {
|
||||||
|
return parseResultFailed
|
||||||
|
}
|
||||||
for i := 0; i < amlNameLen; i++ {
|
for i := 0; i < amlNameLen; i++ {
|
||||||
argObj.name[i] = namepath[nameIndex+i]
|
argObj.name[i] = namepath[nameIndex+i]
|
||||||
}
|
}
|
||||||
@ -1239,6 +1250,7 @@ func (p *Parser) parseDeferredBlocks(objIndex uint32) parseResult {
|
|||||||
p.mode = parseModeAllBlocks
|
p.mode = parseModeAllBlocks
|
||||||
|
|
||||||
// Set stream offset to the first arg
|
// Set stream offset to the first arg
|
||||||
|
p.r.SetPkgEnd(p.streamEnd)
|
||||||
p.r.SetOffset(obj.amlOffset + 1)
|
p.r.SetOffset(obj.amlOffset + 1)
|
||||||
if obj.opcode > 0xff { // opcode length = 2
|
if obj.opcode > 0xff { // opcode length = 2
|
||||||
_, _ = p.r.ReadByte()
|
_, _ = p.r.ReadByte()
|
||||||
|
@ -200,7 +200,7 @@ func TestParseAMLErrors(t *testing.T) {
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
t.Run("connectNonNamedObjArgs failed", func(t *testing.T) {
|
t.Run("connectNonNamedObjArgs failed", func(t *testing.T) {
|
||||||
p, resolver := parserForMockPayload(t, []byte{})
|
p, resolver := parserForMockPayload(t, []byte{})
|
||||||
|
|
||||||
// Use a named object whose args contain a TermArg
|
// Use a named object whose args contain a TermArg
|
||||||
@ -727,6 +727,24 @@ func TestConnectNamedObjectsErrors(t *testing.T) {
|
|||||||
t.Fatalf("expected to get parseResultFailed(%d); got %d", parseResultFailed, res)
|
t.Fatalf("expected to get parseResultFailed(%d); got %d", parseResultFailed, res)
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
|
t.Run("incomplete namepath", func(t *testing.T) {
|
||||||
|
tree := NewObjectTree()
|
||||||
|
tree.CreateDefaultScopes(0)
|
||||||
|
|
||||||
|
// Use a named object whose args contain a TermArg
|
||||||
|
namedObj := tree.newNamedObject(pOpBankField, 0, [amlNameLen]byte{'F', 'O', 'O', 'F'})
|
||||||
|
namepathObj := tree.newObject(pOpIntNamePath, 0)
|
||||||
|
namepathObj.value = []byte{'F', 'O'} // namepath len < amlNameLen
|
||||||
|
tree.append(namedObj, namepathObj)
|
||||||
|
tree.append(tree.ObjectAt(0), namedObj)
|
||||||
|
|
||||||
|
p := NewParser(ioutil.Discard, tree)
|
||||||
|
if res := p.connectNamedObjArgs(0); res != parseResultFailed {
|
||||||
|
t.Fatalf("expected to get parseResultFailed(%d); got %d", parseResultFailed, res)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestMergeScopeDirectivesErrors(t *testing.T) {
|
func TestMergeScopeDirectivesErrors(t *testing.T) {
|
||||||
|
@ -29,12 +29,13 @@ func (r *amlStreamReader) Init(dataAddr uintptr, dataLen, initialOffset uint32)
|
|||||||
Data: dataAddr,
|
Data: dataAddr,
|
||||||
}))
|
}))
|
||||||
|
|
||||||
|
r.SetPkgEnd(dataLen)
|
||||||
r.SetOffset(initialOffset)
|
r.SetOffset(initialOffset)
|
||||||
}
|
}
|
||||||
|
|
||||||
// EOF returns true if the end of the pkg has been reached.
|
// EOF returns true if the end of the pkg has been reached.
|
||||||
func (r *amlStreamReader) EOF() bool {
|
func (r *amlStreamReader) EOF() bool {
|
||||||
return r.offset == r.pkgEnd
|
return r.offset >= r.pkgEnd
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *amlStreamReader) SetPkgEnd(pkgEnd uint32) error {
|
func (r *amlStreamReader) SetPkgEnd(pkgEnd uint32) error {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user