Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add a patch for compat input in 64 bit apps #71

Merged
merged 3 commits into from
Oct 8, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
name: Build aarch64 kernel
name: Cross-build aarch64 kernel
on: [pull_request, create]

jobs:
build:
if: github.event_name == 'pull_request'
name: Build aarch64 kernel
name: Cross-build aarch64 kernel
runs-on: ubuntu-latest
steps:
- name: Code checkout
Expand Down
4 changes: 2 additions & 2 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,8 @@ KERNEL_PATCHES = $(shell find patches/ -name "0*.patch" | sort)
KERNEL_C_BUNDLE = kernel.c

ABI_VERSION = 4
FULL_VERSION = 4.4.1
TIMESTAMP = "Thu Sep 26 16:00:58 CEST 2024"
FULL_VERSION = 4.4.2
TIMESTAMP = "Tue Oct 8 13:02:33 CEST 2024"

KERNEL_FLAGS = KBUILD_BUILD_TIMESTAMP=$(TIMESTAMP)
KERNEL_FLAGS += KBUILD_BUILD_USER=root
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,124 @@
From 897560fd00e1add63a9973c31fc437b006855680 Mon Sep 17 00:00:00 2001
From: Sergio Lopez <[email protected]>
Date: Tue, 8 Oct 2024 11:24:25 +0200
Subject: [PATCH] Enable 64 bit processes to use compat input syscalls

The compat variant of input syscalls is only enabled for 32 bit
tasks, but in some cases, such as userspace emulation, it's useful to
enable that variant for 64 bit processes.

Here we introduce the PR_[GET|SET]_COMPAT_INPUT prctl to allow 64 bit
tasks to opt-in for compat input syscalls.

Signed-off-by: Sergio Lopez <[email protected]>
---
drivers/input/input-compat.c | 6 +++---
drivers/input/input-compat.h | 2 +-
include/linux/sched.h | 5 +++++
include/uapi/linux/prctl.h | 5 +++++
kernel/sys.c | 15 +++++++++++++++
5 files changed, 29 insertions(+), 4 deletions(-)

diff --git a/drivers/input/input-compat.c b/drivers/input/input-compat.c
index 2ccd3eedbd67..abb8cfb99d6c 100644
--- a/drivers/input/input-compat.c
+++ b/drivers/input/input-compat.c
@@ -14,7 +14,7 @@
int input_event_from_user(const char __user *buffer,
struct input_event *event)
{
- if (in_compat_syscall() && !COMPAT_USE_64BIT_TIME) {
+ if (current->compat_input || (in_compat_syscall() && !COMPAT_USE_64BIT_TIME)) {
struct input_event_compat compat_event;

if (copy_from_user(&compat_event, buffer,
@@ -38,7 +38,7 @@ int input_event_from_user(const char __user *buffer,
int input_event_to_user(char __user *buffer,
const struct input_event *event)
{
- if (in_compat_syscall() && !COMPAT_USE_64BIT_TIME) {
+ if (current->compat_input || (in_compat_syscall() && !COMPAT_USE_64BIT_TIME)) {
struct input_event_compat compat_event;

compat_event.sec = event->input_event_sec;
@@ -62,7 +62,7 @@ int input_event_to_user(char __user *buffer,
int input_ff_effect_from_user(const char __user *buffer, size_t size,
struct ff_effect *effect)
{
- if (in_compat_syscall()) {
+ if (current->compat_input || (in_compat_syscall() && !COMPAT_USE_64BIT_TIME)) {
struct ff_effect_compat *compat_effect;

if (size != sizeof(struct ff_effect_compat))
diff --git a/drivers/input/input-compat.h b/drivers/input/input-compat.h
index 3b7bb12b023b..e78c0492ce0d 100644
--- a/drivers/input/input-compat.h
+++ b/drivers/input/input-compat.h
@@ -53,7 +53,7 @@ struct ff_effect_compat {

static inline size_t input_event_size(void)
{
- return (in_compat_syscall() && !COMPAT_USE_64BIT_TIME) ?
+ return (current->compat_input || (in_compat_syscall() && !COMPAT_USE_64BIT_TIME)) ?
sizeof(struct input_event_compat) : sizeof(struct input_event);
}

diff --git a/include/linux/sched.h b/include/linux/sched.h
index 77f01ac385f7..01125573065e 100644
--- a/include/linux/sched.h
+++ b/include/linux/sched.h
@@ -1535,6 +1535,11 @@ struct task_struct {
#ifdef CONFIG_USER_EVENTS
struct user_event_mm *user_event_mm;
#endif
+ /*
+ * Whether the task wants to use compat input syscalls even if it's
+ * a 64-bit process.
+ */
+ bool compat_input;

/*
* New fields for task_struct should be added above here, so that
diff --git a/include/uapi/linux/prctl.h b/include/uapi/linux/prctl.h
index 961216093f11..86fca7d168cc 100644
--- a/include/uapi/linux/prctl.h
+++ b/include/uapi/linux/prctl.h
@@ -311,4 +311,9 @@ struct prctl_mm_map {
# define PR_SET_MEM_MODEL_DEFAULT 0
# define PR_SET_MEM_MODEL_TSO 1

+#define PR_GET_COMPAT_INPUT 0x63494e50
+#define PR_SET_COMPAT_INPUT 0x43494e50
+# define PR_SET_COMPAT_INPUT_DISABLE 0
+# define PR_SET_COMPAT_INPUT_ENABLE 1
+
#endif /* _LINUX_PRCTL_H */
diff --git a/kernel/sys.c b/kernel/sys.c
index 2db751ce25a2..1be74620b0b6 100644
--- a/kernel/sys.c
+++ b/kernel/sys.c
@@ -2768,6 +2768,21 @@ SYSCALL_DEFINE5(prctl, int, option, unsigned long, arg2, unsigned long, arg3,
return -EINVAL;
error = arch_prctl_mem_model_set(me, arg2);
break;
+ case PR_GET_COMPAT_INPUT:
+ if (arg2 || arg3 || arg4 || arg5)
+ return -EINVAL;
+ error = current->compat_input;
+ break;
+ case PR_SET_COMPAT_INPUT:
+ if (arg3 || arg4 || arg5)
+ return -EINVAL;
+ if (arg2 == PR_SET_COMPAT_INPUT_DISABLE)
+ current->compat_input = false;
+ else if (arg2 == PR_SET_COMPAT_INPUT_ENABLE)
+ current->compat_input = true;
+ else
+ return -EINVAL;
+ break;
default:
error = -EINVAL;
break;
--
2.46.0

Loading