From 7ac9a160907484c5517b985ecd33f249ec2d0a02 Mon Sep 17 00:00:00 2001 From: Christian Prochaska Date: Fri, 23 Feb 2018 13:29:32 +0100 Subject: [PATCH] Noux: check ELF signature on 'execve()' Issue #2687 --- repos/ports/include/noux_session/sysio.h | 4 +++- repos/ports/src/lib/libc_noux/plugin.cc | 1 + repos/ports/src/noux/syscall.cc | 12 ++++++++++++ 3 files changed, 16 insertions(+), 1 deletion(-) diff --git a/repos/ports/include/noux_session/sysio.h b/repos/ports/include/noux_session/sysio.h index b6e32819be..2e71c30504 100644 --- a/repos/ports/include/noux_session/sysio.h +++ b/repos/ports/include/noux_session/sysio.h @@ -319,7 +319,9 @@ struct Noux::Sysio SYMLINK_ERR_NO_SPACE, SYMLINK_ERR_NO_PERM, SYMLINK_ERR_NAME_TOO_LONG }; - enum Execve_error { EXECVE_NONEXISTENT = Vfs::Directory_service::NUM_GENERAL_ERRORS, EXECVE_NOMEM }; + enum Execve_error { EXECVE_NONEXISTENT = Vfs::Directory_service::NUM_GENERAL_ERRORS, + EXECVE_NOMEM, + EXECVE_NOEXEC }; enum Fork_error { FORK_NOMEM = Vfs::Directory_service::NUM_GENERAL_ERRORS }; enum Select_error { SELECT_ERR_INTERRUPT }; diff --git a/repos/ports/src/lib/libc_noux/plugin.cc b/repos/ports/src/lib/libc_noux/plugin.cc index 17c499bba5..1dd7ba02f5 100644 --- a/repos/ports/src/lib/libc_noux/plugin.cc +++ b/repos/ports/src/lib/libc_noux/plugin.cc @@ -1101,6 +1101,7 @@ namespace { switch (sysio()->error.execve) { case Noux::Sysio::EXECVE_NONEXISTENT: errno = ENOENT; break; case Noux::Sysio::EXECVE_NOMEM: errno = ENOMEM; break; + case Noux::Sysio::EXECVE_NOEXEC: errno = ENOEXEC; break; } return -1; } diff --git a/repos/ports/src/noux/syscall.cc b/repos/ports/src/noux/syscall.cc index f81272b22c..562bfe5ccc 100644 --- a/repos/ports/src/noux/syscall.cc +++ b/repos/ports/src/noux/syscall.cc @@ -296,6 +296,18 @@ bool Noux::Child::syscall(Noux::Session::Syscall sc) break; } + { + Attached_dataspace attached_binary_ds(_env.rm(), binary_ds->ds); + char const *binary_addr = attached_binary_ds.local_addr(); + if ((binary_addr[0] != 0x7f) || + (binary_addr[1] != 'E') || + (binary_addr[2] != 'L') || + (binary_addr[3] != 'F')) { + _sysio.error.execve = Sysio::EXECVE_NOEXEC; + break; + } + } + binary_ds.destruct(); try {