elf_test.go 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152
  1. // Copyright 2022 Google Inc. All rights reserved.
  2. //
  3. // Licensed under the Apache License, Version 2.0 (the "License");
  4. // you may not use this file except in compliance with the License.
  5. // You may obtain a copy of the License at
  6. //
  7. // http://www.apache.org/licenses/LICENSE-2.0
  8. //
  9. // Unless required by applicable law or agreed to in writing, software
  10. // distributed under the License is distributed on an "AS IS" BASIS,
  11. // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  12. // See the License for the specific language governing permissions and
  13. // limitations under the License.
  14. package main
  15. import (
  16. "bytes"
  17. "debug/elf"
  18. "encoding/binary"
  19. "reflect"
  20. "testing"
  21. )
  22. func Test_elfIdentifierFromReaderAt_BadElfFile(t *testing.T) {
  23. tests := []struct {
  24. name string
  25. contents string
  26. }{
  27. {
  28. name: "empty",
  29. contents: "",
  30. },
  31. {
  32. name: "text",
  33. contents: "#!/bin/bash\necho foobar",
  34. },
  35. {
  36. name: "empty elf",
  37. contents: emptyElfFile(),
  38. },
  39. {
  40. name: "short section header",
  41. contents: shortSectionHeaderElfFile(),
  42. },
  43. }
  44. for _, tt := range tests {
  45. t.Run(tt.name, func(t *testing.T) {
  46. buf := bytes.NewReader([]byte(tt.contents))
  47. _, err := elfIdentifierFromReaderAt(buf, "<>", false)
  48. if err == nil {
  49. t.Errorf("expected error reading bad elf file without allowMissing")
  50. }
  51. _, err = elfIdentifierFromReaderAt(buf, "<>", true)
  52. if err != nil {
  53. t.Errorf("expected no error reading bad elf file with allowMissing, got %q", err.Error())
  54. }
  55. })
  56. }
  57. }
  58. func Test_readNote(t *testing.T) {
  59. note := []byte{
  60. 0x04, 0x00, 0x00, 0x00,
  61. 0x10, 0x00, 0x00, 0x00,
  62. 0x03, 0x00, 0x00, 0x00,
  63. 0x47, 0x4e, 0x55, 0x00,
  64. 0xca, 0xaf, 0x44, 0xd2, 0x82, 0x78, 0x68, 0xfe, 0xc0, 0x90, 0xa3, 0x43, 0x85, 0x36, 0x6c, 0xc7,
  65. }
  66. descs, err := readNote(bytes.NewBuffer(note), binary.LittleEndian)
  67. if err != nil {
  68. t.Fatalf("unexpected error in readNote: %s", err)
  69. }
  70. expectedDescs := map[string][]byte{
  71. "GNU\x00": []byte{0xca, 0xaf, 0x44, 0xd2, 0x82, 0x78, 0x68, 0xfe, 0xc0, 0x90, 0xa3, 0x43, 0x85, 0x36, 0x6c, 0xc7},
  72. }
  73. if !reflect.DeepEqual(descs, expectedDescs) {
  74. t.Errorf("incorrect return, want %#v got %#v", expectedDescs, descs)
  75. }
  76. }
  77. // emptyElfFile returns an elf file header with no program headers or sections.
  78. func emptyElfFile() string {
  79. ident := [elf.EI_NIDENT]byte{}
  80. identBuf := bytes.NewBuffer(ident[0:0:elf.EI_NIDENT])
  81. binary.Write(identBuf, binary.LittleEndian, []byte("\x7fELF"))
  82. binary.Write(identBuf, binary.LittleEndian, elf.ELFCLASS64)
  83. binary.Write(identBuf, binary.LittleEndian, elf.ELFDATA2LSB)
  84. binary.Write(identBuf, binary.LittleEndian, elf.EV_CURRENT)
  85. binary.Write(identBuf, binary.LittleEndian, elf.ELFOSABI_LINUX)
  86. binary.Write(identBuf, binary.LittleEndian, make([]byte, 8))
  87. header := elf.Header64{
  88. Ident: ident,
  89. Type: uint16(elf.ET_EXEC),
  90. Machine: uint16(elf.EM_X86_64),
  91. Version: uint32(elf.EV_CURRENT),
  92. Entry: 0,
  93. Phoff: uint64(binary.Size(elf.Header64{})),
  94. Shoff: uint64(binary.Size(elf.Header64{})),
  95. Flags: 0,
  96. Ehsize: uint16(binary.Size(elf.Header64{})),
  97. Phentsize: 0x38,
  98. Phnum: 0,
  99. Shentsize: 0x40,
  100. Shnum: 0,
  101. Shstrndx: 0,
  102. }
  103. buf := &bytes.Buffer{}
  104. binary.Write(buf, binary.LittleEndian, header)
  105. return buf.String()
  106. }
  107. // shortSectionHeader returns an elf file header with a section header that extends past the end of
  108. // the file.
  109. func shortSectionHeaderElfFile() string {
  110. ident := [elf.EI_NIDENT]byte{}
  111. identBuf := bytes.NewBuffer(ident[0:0:elf.EI_NIDENT])
  112. binary.Write(identBuf, binary.LittleEndian, []byte("\x7fELF"))
  113. binary.Write(identBuf, binary.LittleEndian, elf.ELFCLASS64)
  114. binary.Write(identBuf, binary.LittleEndian, elf.ELFDATA2LSB)
  115. binary.Write(identBuf, binary.LittleEndian, elf.EV_CURRENT)
  116. binary.Write(identBuf, binary.LittleEndian, elf.ELFOSABI_LINUX)
  117. binary.Write(identBuf, binary.LittleEndian, make([]byte, 8))
  118. header := elf.Header64{
  119. Ident: ident,
  120. Type: uint16(elf.ET_EXEC),
  121. Machine: uint16(elf.EM_X86_64),
  122. Version: uint32(elf.EV_CURRENT),
  123. Entry: 0,
  124. Phoff: uint64(binary.Size(elf.Header64{})),
  125. Shoff: uint64(binary.Size(elf.Header64{})),
  126. Flags: 0,
  127. Ehsize: uint16(binary.Size(elf.Header64{})),
  128. Phentsize: 0x38,
  129. Phnum: 0,
  130. Shentsize: 0x40,
  131. Shnum: 1,
  132. Shstrndx: 0,
  133. }
  134. buf := &bytes.Buffer{}
  135. binary.Write(buf, binary.LittleEndian, header)
  136. binary.Write(buf, binary.LittleEndian, []byte{0})
  137. return buf.String()
  138. }