diff options
author | Itamar <itamar8910@gmail.com> | 2020-04-10 17:34:31 +0300 |
---|---|---|
committer | Andreas Kling <kling@serenityos.org> | 2020-04-13 00:53:22 +0200 |
commit | 50fd2cabff79e2faefda55030b44836288709075 (patch) | |
tree | fc22578ec22909c39190634cef883619f22d4345 /Libraries/LibC/sys | |
parent | aae3f7b91477a802fcdcd68958aab4ba3527eae3 (diff) | |
download | serenity-50fd2cabff79e2faefda55030b44836288709075.zip |
ptrace: Report error in PT_PEEK via errno
The syscall wrapper for ptrace needs to return the peeked value when
using PT_PEEK.
Because of this, the user has to check errno to detect an error in
PT_PEEK.
This commit changes the actual syscall's interface (only for PT_PEEK) to
allow the syscall wrapper to detect an error and change errno.
Diffstat (limited to 'Libraries/LibC/sys')
-rw-r--r-- | Libraries/LibC/sys/ptrace.cpp | 25 |
1 files changed, 25 insertions, 0 deletions
diff --git a/Libraries/LibC/sys/ptrace.cpp b/Libraries/LibC/sys/ptrace.cpp index b9c0c16234..f991b077bc 100644 --- a/Libraries/LibC/sys/ptrace.cpp +++ b/Libraries/LibC/sys/ptrace.cpp @@ -24,6 +24,7 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ +#include <AK/LogStream.h> #include <Kernel/Syscall.h> #include <errno.h> #include <sys/ptrace.h> @@ -32,6 +33,20 @@ extern "C" { int ptrace(int request, pid_t pid, void* addr, int data) { + + // PT_PEEK needs special handling since the syscall wrapper + // returns the peeked value as an int, which can be negative because of the cast. + // When using PT_PEEK, the user can check if an error occured + // by looking at errno rather than the return value. + + u32 out_data; + Syscall::SC_ptrace_peek_params peek_params; + if (request == PT_PEEK) { + peek_params.address = reinterpret_cast<u32*>(addr); + peek_params.out_data = &out_data; + addr = &peek_params; + } + Syscall::SC_ptrace_params params { request, pid, @@ -39,6 +54,16 @@ int ptrace(int request, pid_t pid, void* addr, int data) data }; int rc = syscall(SC_ptrace, ¶ms); + + if (request == PT_PEEK) { + if (rc < 0) { + errno = -rc; + return -1; + } + errno = 0; + return static_cast<int>(out_data); + } + __RETURN_WITH_ERRNO(rc, rc, -1); } } |