kernel/sys.c: implement custom uname override

The uname system-call will return CONFIG_UNAME_OVERRIDE_STRING on struct
new_utsname->release when a process with CONFIG_UNAME_OVERRIDE_TARGET
included in its cmdline calls it.

Signed-off-by: Juhyung Park <qkrwngud825@gmail.com>
This commit is contained in:
Juhyung Park 2024-02-01 16:31:53 +08:00 committed by Ksawlii
parent d9e7f45cc4
commit 8c11745023
2 changed files with 36 additions and 0 deletions

View file

@ -198,6 +198,22 @@ config LOCALVERSION_AUTO
which is done within the script "scripts/setlocalversion".) which is done within the script "scripts/setlocalversion".)
menuconfig UNAME_OVERRIDE
bool "Override uname output for specific processes"
help
This will modify struct new_utsname->release string's return value
to another string on a specified process.
if UNAME_OVERRIDE
config UNAME_OVERRIDE_TARGET
string "Target process' cmdline for uname override"
config UNAME_OVERRIDE_STRING
string "New uname's release string for uname override"
endif
config BUILD_SALT config BUILD_SALT
string "Build ID Salt" string "Build ID Salt"
default "" default ""

View file

@ -44,6 +44,7 @@
#include <linux/ctype.h> #include <linux/ctype.h>
#include <linux/mm.h> #include <linux/mm.h>
#include <linux/mempolicy.h> #include <linux/mempolicy.h>
#include <linux/string_helpers.h>
#include <linux/compat.h> #include <linux/compat.h>
#include <linux/syscalls.h> #include <linux/syscalls.h>
@ -1239,6 +1240,24 @@ DECLARE_RWSEM(uts_sem);
#define override_architecture(name) 0 #define override_architecture(name) 0
#endif #endif
static void override_custom_release(char __user *release, size_t len)
{
#ifdef CONFIG_UNAME_OVERRIDE
char *buf;
buf = kstrdup_quotable_cmdline(current, GFP_KERNEL);
if (buf == NULL)
return;
if (strstr(buf, CONFIG_UNAME_OVERRIDE_TARGET)) {
copy_to_user(release, CONFIG_UNAME_OVERRIDE_STRING,
strlen(CONFIG_UNAME_OVERRIDE_STRING) + 1);
}
kfree(buf);
#endif
}
/* /*
* Work around broken programs that cannot handle "Linux 3.0". * Work around broken programs that cannot handle "Linux 3.0".
* Instead we map 3.x to 2.6.40+x, so e.g. 3.0 would be 2.6.40 * Instead we map 3.x to 2.6.40+x, so e.g. 3.0 would be 2.6.40
@ -1303,6 +1322,7 @@ SYSCALL_DEFINE1(newuname, struct new_utsname __user *, name)
if (copy_to_user(name, &tmp, sizeof(tmp))) if (copy_to_user(name, &tmp, sizeof(tmp)))
return -EFAULT; return -EFAULT;
override_custom_release(name->release, sizeof(name->release));
if (override_release(name->release, sizeof(name->release))) if (override_release(name->release, sizeof(name->release)))
return -EFAULT; return -EFAULT;
if (override_architecture(name)) if (override_architecture(name))