mvdan / sh

A shell parser, formatter, and interpreter with bash support; includes shfmt
https://pkg.go.dev/mvdan.cc/sh/v3
BSD 3-Clause "New" or "Revised" License
6.97k stars 332 forks source link

interp: bash runs scripts if kernel returns ENOEXEC #1065

Open hugelgupf opened 4 months ago

hugelgupf commented 4 months ago

make a file like such, named foo:

echo "bar"
$ chmod +x foo
$ bash -c "./foo"
hi

when I run this with strace -f bash -c ./foo I see that

execve("./testdata/foo", ["./testdata/foo"], 0x56158959fca0 /* 48 vars */) = -1 ENOEXEC (Exec format error)
...            
openat(AT_FDCWD, "./testdata/foo", O_RDONLY) = 3                                                                                                  
newfstatat(AT_FDCWD, "./testdata/foo", {st_mode=S_IFREG|0750, st_size=11, ...}, 0) = 0                                                            
read(3, "echo \"bar\"\n", 80)           = 11                                                                                                      
lseek(3, 0, SEEK_SET)                   = 0                                                                                                       
dup2(3, 255)                            = 255                                                                                                     
close(3)                                = 0                                                                                                       
read(255, "echo \"bar\"\n", 11)         = 11                                                                                                      
write(1, "bar\n", 4)                    = 4                                    

Looks to me like bash will try to execute as a script files with execute permission that get ENOEXEC from the kernel.

This looks like something that could be implemented as an ExecHandlerFunc.

mvdan commented 4 months ago

Makes sense, or we could just do this by default as part of the default exec handler. Happy to review a patch.