[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-Id: <20210423103533.30121-2-zhe.he@windriver.com>
Date: Fri, 23 Apr 2021 18:35:32 +0800
From: He Zhe <zhe.he@...driver.com>
To: oleg@...hat.com, catalin.marinas@....com, will@...nel.org,
linux-arm-kernel@...ts.infradead.org, paul@...l-moore.com,
eparis@...hat.com, linux-audit@...hat.com,
linux-kernel@...r.kernel.org, zhe.he@...driver.com
Subject: [PATCH v2 2/3] arm64: syscall.h: Add sign extension handling in syscall_get_return_value for compat
Add sign extension handling in syscall_get_return_value so that it can
handle 32-bit compatible case and can be used by for example audit, just
like what syscall_get_error does.
Suggested-by: Mark Rutland <mark.rutland@....com>
Signed-off-by: He Zhe <zhe.he@...driver.com>
---
v1 to v2: Improve error code check suggested by Mark
arch/arm64/include/asm/syscall.h | 15 ++++++++++++++-
1 file changed, 14 insertions(+), 1 deletion(-)
diff --git a/arch/arm64/include/asm/syscall.h b/arch/arm64/include/asm/syscall.h
index cfc0672013f6..c3b5fca82ff4 100644
--- a/arch/arm64/include/asm/syscall.h
+++ b/arch/arm64/include/asm/syscall.h
@@ -44,7 +44,20 @@ static inline long syscall_get_error(struct task_struct *task,
static inline long syscall_get_return_value(struct task_struct *task,
struct pt_regs *regs)
{
- return regs->regs[0];
+ long val = regs->regs[0];
+ long error = val;
+
+ if (compat_user_mode(regs))
+ error = sign_extend64(error, 31);
+
+ /*
+ * Return codes with bit 31 set may or may not be an error code.
+ * For example, mmap may return a legal 32 bit address with bit 31 set
+ * for 32 bit thread, in which case the untouched val should be
+ * returned. Otherwise, the sign-extended error should be returned if
+ * it still falls in error number range.
+ */
+ return IS_ERR_VALUE(error) ? error : val;
}
static inline void syscall_set_return_value(struct task_struct *task,
--
2.17.1
Powered by blists - more mailing lists