Skip to content

Commit

Permalink
Add symlinks tree for compatibity with older firmware
Browse files Browse the repository at this point in the history
A lot of firmware binaries use non-standard paths like `/lib`. Add
the tree of symlinks for compatibility.

Closes #45
Closes #104
  • Loading branch information
anatol committed Sep 23, 2021
1 parent 9047c94 commit 9527452
Show file tree
Hide file tree
Showing 2 changed files with 64 additions and 28 deletions.
29 changes: 29 additions & 0 deletions generator/generator.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import (
"strings"
"time"

"github.com/cavaliercoder/go-cpio"
"gopkg.in/yaml.v3"
)

Expand Down Expand Up @@ -93,6 +94,10 @@ func generateInitRamfs(conf *generatorConfig) error {
}
defer img.Cleanup()

if err := appendCompatibilitySymlinks(img); err != nil {
return err
}

if err := img.appendInitBinary(conf.initBinary); err != nil {
return err
}
Expand Down Expand Up @@ -163,6 +168,30 @@ func generateInitRamfs(conf *generatorConfig) error {
return img.Close()
}

// appendCompatibilitySymlinks appends symlinks for compatibility with older firmware that loads extra files from non-standard locations
func appendCompatibilitySymlinks(img *Image) error {
symlinks := []struct{ src, target string }{
{"/lib", "/usr/lib"},
{"/usr/local/lib", "/usr/lib"},
{"/usr/sbin", "/usr/bin"},
{"/bin", "/usr/bin"},
{"/sbin", "/usr/bin"},
{"/usr/local/bin", "/usr/bin"},
{"/usr/local/sbin", "/usr/bin"},
{"/var/run", "/run"},
{"/usr/lib64", "/usr/lib"},
{"/lib64", "/usr/lib"},
}

for _, l := range symlinks {
mode := cpio.FileMode(0777) | cpio.ModeSymlink
if err := img.AppendEntry(l.src, mode, []byte(l.target)); err != nil {
return err
}
}
return nil
}

func (img *Image) appendInitBinary(initBinary string) error {
content, err := os.ReadFile(initBinary)
if err != nil {
Expand Down
63 changes: 35 additions & 28 deletions generator/image.go
Original file line number Diff line number Diff line change
Expand Up @@ -150,7 +150,7 @@ func stripElf(name string, in []byte, stripAll bool) ([]byte, error) {
return os.ReadFile(t.Name())
}

func (img *Image) AppendContent(content []byte, mode os.FileMode, dest string) error {
func (img *Image) AppendContent(content []byte, osMode os.FileMode, dest string) error {
img.m.Lock()
if img.contains[dest] {
img.m.Unlock()
Expand Down Expand Up @@ -197,19 +197,8 @@ func (img *Image) AppendContent(content []byte, mode os.FileMode, dest string) e
}
}

hdr := &cpio.Header{
Name: strings.TrimPrefix(dest, "/"),
Mode: cpio.FileMode(mode) | cpio.ModeRegular,
Size: int64(len(content)),
}
img.m.Lock()
if err := img.out.WriteHeader(hdr); err != nil {
img.m.Unlock()
return err
}
_, err := img.out.Write(content)
img.m.Unlock()
return err
mode := cpio.FileMode(osMode) | cpio.ModeRegular
return img.AppendEntry(dest, mode, content)
}

// AppendFile appends the file + its dependencies to the ramfs file
Expand Down Expand Up @@ -248,22 +237,10 @@ func (img *Image) AppendFile(fn string) error {
return err
}

hdr := &cpio.Header{
Name: strings.TrimPrefix(fn, "/"),
Mode: cpio.FileMode(fi.Mode().Perm()) | cpio.ModeSymlink,
Size: int64(len(linkTarget)),
}

img.m.Lock()
if err := img.out.WriteHeader(hdr); err != nil {
img.m.Unlock()
return err
}
if _, err := img.out.Write([]byte(linkTarget)); err != nil {
img.m.Unlock()
mode := cpio.FileMode(fi.Mode().Perm()) | cpio.ModeSymlink
if err := img.AppendEntry(fn, mode, []byte(linkTarget)); err != nil {
return err
}
img.m.Unlock()

// now add the link target as well
if !filepath.IsAbs(linkTarget) {
Expand Down Expand Up @@ -301,6 +278,36 @@ func (img *Image) AppendFile(fn string) error {
return nil
}

// AppendEntry appends an entry to the archive
func (img *Image) AppendEntry(dest string, fileMode cpio.FileMode, content []byte) error {
img.m.Lock()
img.contains[dest] = true
img.m.Unlock()

if err := img.AppendDirEntry(path.Dir(dest)); err != nil {
return err
}

hdr := &cpio.Header{
Name: strings.TrimPrefix(dest, "/"),
Mode: fileMode,
Size: int64(len(content)),
}

img.m.Lock()
if err := img.out.WriteHeader(hdr); err != nil {
img.m.Unlock()
return err
}
if _, err := img.out.Write(content); err != nil {
img.m.Unlock()
return err
}
img.m.Unlock()

return nil
}

func elfSectionContent(s *elf.Section) (string, error) {
b, err := s.Data()
if err != nil {
Expand Down

0 comments on commit 9527452

Please sign in to comment.