Запустить elf приложение не записывая на диск
Есть бинарный "екзешник", скомпилированный go. Делаю программу - супервизор, которая его запускает (сейчас fork+execv).
Но можно ли запустить его из массива байт не записывая на диск?
Если нет, то можно ли запустить файловый дескриптор без имени? вызов tmpfile делает такой, что readlink говорит что файл удален. Можно ли запустить по номеру открытого дескриптора или inode? тут проблема возникает что файл открыт на запись, а при закрытии его не открыть потому что он будет полностью удален.
Для этого случая всё работает нормально если открыть файл через mkstemp, но через tmpfile
#include "bin.h"
#include <unistd.h>
#include <stdio.h>
// #include <fcntl.h>
#include <sys/stat.h>
#include <stdlib.h>
#include <errno.h>
#include <sys/types.h>
#include <sys/wait.h>
int main(int argc, char *argv[], char *envp[])
{
int r;
FILE *tmp = tmpfile();
int fd = fileno(tmp);
write(fd, __bin, __bin_len);
fsync(fd);
fchmod(fd, S_IRWXU);
FILE *tmp2 = fdopen(fd, "r");
fclose(tmp);
fd = fileno(tmp2);
pid_t pid;
switch (pid = fork())
{
case -1:
perror("fork");
exit(1);
case 0:
getppid();
//fclose(tmp2);
return 0;
default:
return fexecve(fd, argv, envp);
}
return 1;
}
такой стрейс
.....
openat(AT_FDCWD, "/tmp", O_RDWR|O_EXCL|O_TMPFILE, 0600) = 3
fcntl(3, F_GETFL) = 0x418002 (flags O_RDWR|O_LARGEFILE|O_TMPFILE)
getrandom("\xc1\x83\x35\x01\xbe\xec\x96\x5a", 8, GRND_NONBLOCK) = 8
brk(NULL) = 0x55c875ae0000
brk(0x55c875b01000) = 0x55c875b01000
write(3, "\177ELF\2\1\1\0\0\0\0\0\0\0\0\0\3\0>\0\1\0\0\0\360d\0\0\0\0\0\0"..., 352808) = 352808
fsync(3) = 0
fchmod(3, 0700) = 0
fcntl(3, F_GETFL) = 0x418002 (flags O_RDWR|O_LARGEFILE|O_TMPFILE)
close(3) = 0
clone(child_stack=NULL, flags=CLONE_CHILD_CLEARTID|CLONE_CHILD_SETTID|SIGCHLD, child_tidptr=0x7f6e46e76910) = 348850
execveat(3, "", ["./nano"], 0x7ffe01dcd068 /* 60 vars */, AT_EMPTY_PATH) = -1 EBADF (Неправильный дескриптор файла)
--- SIGCHLD {si_signo=SIGCHLD, si_code=CLD_EXITED, si_pid=348850, si_uid=1000, si_status=0, si_utime=0, si_stime=0} ---
exit_group(-1) = ?
+++ exited with 255 +++
п.с. "bin.h" сделан через xxd -i /bin/nano > ./bin.h
Ответы (1 шт):
Автор решения: eri
→ Ссылка
#include "bin.h"
#include <unistd.h>
#include <stdio.h>
#include <sys/stat.h>
#include <stdlib.h>
#include <errno.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <sys/mman.h>
int supervisor(){
int ppid = getppid();
return 0;
};
int main(int argc, char *argv[], char *envp[])
{
int r;
int fd = memfd_create(argv[0], 0);
write(fd, __bin, __bin_len);
fchmod(fd, S_IRWXU);
pid_t pid;
switch (pid = fork())
{
case -1:
perror("cant fork");
exit(1);
case 0:
return supervisor();
default:
return fexecve(fd, argv, envp);
}
return 1;
}