├── debian ├── compat ├── docs ├── manpages ├── install ├── source │ ├── format │ └── options ├── changelog ├── rules ├── control └── copyright ├── .gitignore ├── elfexec.1 ├── PKGBUILD ├── Makefile ├── elfexec.spec ├── README.md └── elfexec.c /debian/compat: -------------------------------------------------------------------------------- 1 | 7 2 | -------------------------------------------------------------------------------- /debian/docs: -------------------------------------------------------------------------------- 1 | README.md 2 | -------------------------------------------------------------------------------- /debian/manpages: -------------------------------------------------------------------------------- 1 | elfexec.1 2 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | elfexec 2 | elfexec.o 3 | -------------------------------------------------------------------------------- /debian/install: -------------------------------------------------------------------------------- 1 | elfexec /usr/bin 2 | -------------------------------------------------------------------------------- /debian/source/format: -------------------------------------------------------------------------------- 1 | 3.0 (native) 2 | -------------------------------------------------------------------------------- /debian/source/options: -------------------------------------------------------------------------------- 1 | compression = "bzip2" 2 | compression-level = 9 3 | tar-ignore = .git 4 | tar-ignore = .gitignore 5 | tar-ignore = PKGBUILD 6 | tar-ignore = elfexec.spec 7 | -------------------------------------------------------------------------------- /elfexec.1: -------------------------------------------------------------------------------- 1 | .TH elfexec 1 "Jan 4, 2019" 2 | .nh 3 | .ad left 4 | .SH NAME 5 | elfexec \- utility to execute ELF binary directly from stdin pipe. It is useful to run binary via SSH without copy or install it on remote systems. 6 | .SH SYNTAX 7 | .B elfexec 8 | .RI [ options ] 9 | .SH OPTIONS 10 | Executed binary options. 11 | .SH EXIT CODE 12 | Executed binary exit code or 1 if self failed. 13 | .SH EXAMPLE 14 | .TP 15 | $ cat build-1234 | ssh user@host 'elfexec --test=integration --env=production' 16 | -------------------------------------------------------------------------------- /debian/changelog: -------------------------------------------------------------------------------- 1 | elfexec (0.3) unstable; urgency=low 2 | 3 | * Fix compiler warnings, ANSI C compatible. 4 | 5 | -- Anton Batenev Tue, 07 Jan 2020 19:04:52 +0300 6 | 7 | elfexec (0.2) unstable; urgency=low 8 | 9 | * Small refactoring and documentaion. 10 | 11 | -- Anton Batenev Fri, 22 Feb 2019 11:22:12 +0300 12 | 13 | elfexec (0.1) unstable; urgency=low 14 | 15 | * Initial. 16 | 17 | -- Anton Batenev Fri, 04 Jan 2019 18:49:27 +0300 18 | -------------------------------------------------------------------------------- /debian/rules: -------------------------------------------------------------------------------- 1 | #!/usr/bin/make -f 2 | # -*- makefile -*- 3 | 4 | # Uncomment this to turn on verbose mode. 5 | #export DH_VERBOSE=1 6 | 7 | DPKG_EXPORT_BUILDFLAGS = 1 8 | include /usr/share/dpkg/buildflags.mk 9 | 10 | override_dh_auto_configure: 11 | /bin/true 12 | 13 | override_dh_auto_build: 14 | make USER_CFLAGS="$(shell dpkg-buildflags --get CFLAGS)" USER_CPPFLAGS="$(shell dpkg-buildflags --get CPPFLAGS)" USER_LDFLAGS="$(shell dpkg-buildflags --get LDFLAGS)" 15 | 16 | override_dh_auto_test: 17 | /bin/true 18 | 19 | override_dh_auto_install: 20 | /bin/true 21 | 22 | override_dh_strip: 23 | dh_strip --dbg-package=elfexec-dbg 24 | 25 | %: 26 | dh $@ --parallel 27 | -------------------------------------------------------------------------------- /debian/control: -------------------------------------------------------------------------------- 1 | Source: elfexec 2 | Section: utils 3 | Priority: optional 4 | Maintainer: Anton Batenev 5 | Build-Depends: debhelper (>= 7.0.50~) 6 | Standards-Version: 3.9.4 7 | Vcs-Git: https://github.com/abbat/elfexec.git 8 | Vcs-Browser: https://github.com/abbat/elfexec 9 | Homepage: https://github.com/abbat/elfexec 10 | 11 | Package: elfexec 12 | Architecture: any 13 | Depends: ${misc:Depends}, ${shlibs:Depends} 14 | Description: Utility to execute ELF binary directly from stdin pipe 15 | Utility to execute ELF binary directly from stdin pipe. 16 | 17 | Package: elfexec-dbg 18 | Section: debug 19 | Priority: extra 20 | Depends: elfexec (= ${binary:Version}), ${misc:Depends} 21 | Architecture: any 22 | Description: Debug symbols for elfexec 23 | Utility to execute ELF binary directly from stdin pipe. 24 | -------------------------------------------------------------------------------- /PKGBUILD: -------------------------------------------------------------------------------- 1 | # Maintainer: Anton Batenev 2 | 3 | pkgname=elfexec 4 | pkgver=0.3 5 | pkgrel=1 6 | pkgdesc='Utility to execute ELF binary directly from stdin pipe' 7 | arch=('i686' 'x86_64') 8 | url='https://github.com/abbat/elfexec' 9 | license=('BSD') 10 | makedepends=('git') 11 | source=("git+https://github.com/abbat/elfexec.git#tag=v${pkgver}") 12 | sha256sums=('SKIP') 13 | 14 | build() { 15 | cd "${pkgname}" 16 | make 17 | } 18 | 19 | package() { 20 | cd "${pkgname}" 21 | 22 | install -D -m755 elfexec "${pkgdir}/usr/bin/elfexec" 23 | install -D -m644 elfexec.1 "${pkgdir}/usr/share/man/man1/elfexec.1" 24 | install -D -m644 README.md "${pkgdir}/usr/share/doc/${pkgname}/README.md" 25 | install -D -m644 debian/copyright "${pkgdir}/usr/share/licenses/${pkgname}/LICENSE" 26 | } 27 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | # 2 | # http://www.gnu.org/software/make/manual/make.html 3 | # 4 | 5 | NAME := elfexec 6 | CC ?= cc 7 | SOURCES := $(NAME).c 8 | OBJECTS := $(NAME).o 9 | CFLAGS := -ansi -pedantic -pedantic-errors -Wall -Werror -Wextra -Wconversion -O2 10 | CPPFLAGS := 11 | LDFLAGS := 12 | 13 | PREFIX ?= /usr 14 | BINDIR := $(PREFIX)/bin 15 | MANDIR := $(PREFIX)/share/man 16 | 17 | CFLAGS += $(USER_CFLAGS) 18 | CPPFLAGS += $(USER_CPPFLAGS) 19 | LDFLAGS += $(USER_LDFLAGS) 20 | 21 | .PHONY: $(NAME) all clean install 22 | 23 | all: $(NAME) 24 | 25 | $(NAME): clean $(SOURCES) $(OBJECTS) 26 | $(CC) -o $(NAME) $(OBJECTS) $(LDFLAGS) 27 | 28 | clean: 29 | rm -f $(NAME) 30 | rm -f $(OBJECTS) 31 | 32 | %.o: %.c 33 | $(CC) $(CFLAGS) $(CPPFLAGS) -c -o $@ $< 34 | 35 | install: $(NAME) 36 | mkdir -p $(abspath $(DESTDIR)/$(BINDIR)) 37 | mkdir -p $(abspath $(DESTDIR)/$(MANDIR)/man1) 38 | install -m 0755 $(NAME) $(abspath $(DESTDIR)/$(BINDIR)/$(NAME)) 39 | install -m 0644 $(NAME).1 $(abspath $(DESTDIR)/$(MANDIR)/man1/$(NAME).1) 40 | -------------------------------------------------------------------------------- /elfexec.spec: -------------------------------------------------------------------------------- 1 | Name: elfexec 2 | Version: 0.3 3 | Release: 1 4 | Summary: Utility to execute ELF binary directly from stdin pipe 5 | Group: Productivity/File utilities 6 | License: BSD-2-Clause 7 | URL: https://github.com/abbat/elfexec 8 | Source0: https://build.opensuse.org/source/home:antonbatenev:elfexec/elfexec/elfexec_%{version}.tar.bz2 9 | BuildRoot: %{_tmppath}/%{name}-%{version}-build 10 | 11 | 12 | %description 13 | Utility to execute ELF binary directly from stdin pipe. 14 | 15 | 16 | %prep 17 | %setup -q -n elfexec 18 | 19 | 20 | %build 21 | make USER_CFLAGS="${RPM_OPT_FLAGS}" USER_CPPFLAGS="${RPM_OPT_FLAGS}" USER_LDFLAGS="${RPM_LD_FLAGS}" %{?_smp_mflags} 22 | 23 | 24 | %install 25 | 26 | install -d %{buildroot}%{_bindir} 27 | 28 | install -m755 elfexec %{buildroot}%{_bindir}/elfexec 29 | 30 | install -d %{buildroot}%{_mandir}/man1 31 | 32 | install -m644 elfexec.1 %{buildroot}%{_mandir}/man1/elfexec.1 33 | 34 | 35 | %clean 36 | rm -rf %{buildroot} 37 | 38 | 39 | %files 40 | %defattr(-,root,root,-) 41 | %doc README.md 42 | %doc %{_mandir}/man1/elfexec.1* 43 | 44 | %{_bindir}/elfexec 45 | 46 | 47 | %changelog 48 | * Tue Jan 07 2020 Anton Batenev 0.3-1 49 | - Initial RPM release 50 | -------------------------------------------------------------------------------- /debian/copyright: -------------------------------------------------------------------------------- 1 | Format: http://www.debian.org/doc/packaging-manuals/copyright-format/1.0/ 2 | Upstream-Name: elfexec 3 | Source: https://github.com/abbat/elfexec 4 | 5 | Files: * 6 | Copyright: 2019-2020, Anton Batenev 7 | License: BSD 8 | 9 | License: BSD 10 | Redistribution and use in source and binary forms, with or without 11 | modification, are permitted provided that the following conditions are met: 12 | . 13 | 1. Redistributions of source code must retain the above copyright notice, this 14 | list of conditions and the following disclaimer. 15 | 2. Redistributions in binary form must reproduce the above copyright notice, 16 | this list of conditions and the following disclaimer in the documentation 17 | and/or other materials provided with the distribution. 18 | . 19 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 20 | ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 21 | WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 22 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR 23 | ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 24 | (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 25 | LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 26 | ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 27 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 28 | SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 | . 30 | The views and conclusions contained in the software and documentation are those 31 | of the authors and should not be interpreted as representing official policies, 32 | either expressed or implied, of the FreeBSD Project. 33 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # elfexec 2 | 3 | Utility to execute ELF binary directly from stdin pipe. It is useful to run binary via SSH without copy or install it on remote systems. 4 | 5 | ## Examples 6 | 7 | Run binary via ssh: 8 | 9 | ``` 10 | $ cat build-1234 | ssh user@host 'elfexec --test=integration --env=production' 11 | ``` 12 | 13 | Decode base64 encoded binary and run it directly: 14 | 15 | ``` 16 | $ echo 'IyEvYmluL3NoCmVjaG8gIkhlbGxvISIK' | base64 -d | elfexec 17 | ``` 18 | 19 | Compile source code and run it without temporary files: 20 | 21 | ``` 22 | $ echo ' 23 | #include 24 | 25 | int main(int argc, char* argv[]) 26 | { 27 | write(STDOUT_FILENO, "Hello!\n", 7); 28 | return 0; 29 | } 30 | ' | cc -xc - -o /dev/stdout | elfexec 31 | ``` 32 | 33 | ## Download / Install 34 | 35 | Require Linux 3.17 or higher: 36 | 37 | * [Precompiled static binaries](https://github.com/abbat/elfexec/releases) built with system libc (glibc) and musl libc for x64 and i386 38 | * From source code: 39 | 40 | ``` 41 | $ git clone https://github.com/abbat/elfexec.git 42 | $ make && sudo make install 43 | ``` 44 | 45 | To compile with own flags use `USER_CFLAGS` and `USER_LDFLAGS` variables. For example for i386 static binary with [musl libc](https://www.musl-libc.org): 46 | 47 | ``` 48 | $ CC=musl-gcc32 USER_CFLAGS=-m32 USER_LDFLAGS='-m32 -static -Wl,-melf_i386' make 49 | ``` 50 | 51 | ## Usage 52 | 53 | ``` 54 | elfexec [options] 55 | ``` 56 | 57 | Where `options` is executed binary options. 58 | 59 | ## Exit code 60 | 61 | Executed binary exit code or `1` if self failed. 62 | 63 | ## How to help 64 | 65 | * Translate this document or [man page](https://github.com/abbat/elfexec/blob/master/elfexec.1) to your native language; 66 | * Proofreading README.md or man page with your native language; 67 | * Share, Like, RT to your friends; 68 | * Send PRs if you are developer. 69 | -------------------------------------------------------------------------------- /elfexec.c: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2019-2020 Anton Batenev 3 | * 4 | * All rights reserved. 5 | * 6 | * Redistribution and use in source and binary forms, with or without 7 | * modification, are permitted provided that the following conditions 8 | * are met: 9 | * 10 | * 1. Redistributions of source code must retain the above copyright 11 | * notice, this list of conditions and the following disclaimer. 12 | * 2. Redistributions in binary form must reproduce the above copyright 13 | * notice, this list of conditions and the following disclaimer in the 14 | * documentation and/or other materials provided with the distribution. 15 | * 16 | * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 17 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 18 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 19 | * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 20 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 21 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 22 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 23 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 24 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 25 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 26 | * SUCH DAMAGE. 27 | */ 28 | 29 | #ifndef __linux__ 30 | #error "This program is linux-only." 31 | #endif 32 | 33 | #define _GNU_SOURCE 34 | #include 35 | 36 | #include 37 | #include 38 | #include 39 | #include 40 | #include 41 | 42 | #ifndef SYS_memfd_create 43 | #error "memfd_create require Linux 3.17 or higher." 44 | #endif 45 | 46 | /** 47 | * Default chunk size for io. 48 | */ 49 | #ifndef EE_CHUNK_SIZE 50 | #define EE_CHUNK_SIZE (8 * 1024) 51 | #endif 52 | 53 | /** 54 | * Default memory mapped filename. 55 | */ 56 | #ifndef EE_MEMFD_NAME 57 | #define EE_MEMFD_NAME "elfexec" 58 | #endif 59 | 60 | int exit_failure(const char* msg) 61 | { 62 | perror(msg); 63 | return EXIT_FAILURE; 64 | } 65 | 66 | int main(int argc, char* argv[]) 67 | { 68 | int memfd; 69 | ssize_t nread; 70 | ssize_t nwrite; 71 | size_t offset; 72 | size_t length; 73 | char buf[EE_CHUNK_SIZE]; 74 | 75 | /* 76 | * memfd_create require Linux 3.17 and was added to: 77 | * - glibc 2.27 (2018-02-01) 78 | * - musl 1.1.20 (2018-09-04) 79 | * use syscall to be compatible with older releases 80 | */ 81 | memfd = (int)syscall(SYS_memfd_create, EE_MEMFD_NAME, 0); 82 | if (memfd == -1) 83 | return exit_failure("memfd_create"); 84 | 85 | do { 86 | nread = read(STDIN_FILENO, buf, EE_CHUNK_SIZE); 87 | if (nread == -1) 88 | return exit_failure("read"); 89 | 90 | offset = 0; 91 | length = (size_t)nread; 92 | while (offset < length) { 93 | nwrite = write(memfd, buf + offset, length - offset); 94 | if (nwrite == -1) 95 | return exit_failure("write"); 96 | 97 | offset += (size_t)nwrite; 98 | } 99 | } while (nread > 0); 100 | 101 | if (fexecve(memfd, argv, environ) == -1) 102 | return exit_failure("fexecve"); 103 | 104 | /* unused */ 105 | (void)argc; 106 | 107 | /* a successful call to fexecve never returns */ 108 | return EXIT_SUCCESS; 109 | } 110 | --------------------------------------------------------------------------------