Sign Up
Log In
Log In
or
Sign Up
Places
All Projects
Status Monitor
Collapse sidebar
SUSE:SLE-12:GA
kgraft-patch
kgraft-patch.c
Overview
Repositories
Revisions
Requests
Users
Attributes
Meta
File kgraft-patch.c of Package kgraft-patch
/* * kgraft_patch -- initial SLE Live Patching patch * * Patch uname to show kGraft in version string * * Copyright (c) 2014 SUSE * Author: Libor Pechacek */ #include <linux/module.h> #include <linux/kernel.h> #include <linux/init.h> #include <linux/kgraft.h> #include <linux/syscalls.h> #include <linux/personality.h> #include <linux/utsname.h> #include <generated/utsrelease.h> #include <linux/version.h> #include <linux/ctype.h> #include <linux/string.h> #include <asm/uaccess.h> #ifdef COMPAT_UTS_MACHINE #define override_architecture(name) \ (personality(current->personality) == PER_LINUX32 && \ copy_to_user(name->machine, COMPAT_UTS_MACHINE, \ sizeof(COMPAT_UTS_MACHINE))) #else #define override_architecture(name) 0 #endif /* * 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 */ static int override_release(char __user *release, size_t len) { int ret = 0; if (current->personality & UNAME26) { const char *rest = UTS_RELEASE; char buf[65] = { 0 }; int ndots = 0; unsigned v; size_t copy; while (*rest) { if (*rest == '.' && ++ndots >= 3) break; if (!isdigit(*rest) && *rest != '.') break; rest++; } v = ((LINUX_VERSION_CODE >> 8) & 0xff) + 40; copy = clamp_t(size_t, len, 1, sizeof(buf)); copy = scnprintf(buf, copy, "2.6.%u%s", v, rest); ret = copy_to_user(release, buf, copy + 1); } return ret; } #define KGR_TAG "/kGraft" struct rw_semaphore *kgr_uts_sem; asmlinkage long kgr_sys_newuname(struct new_utsname __user *name) { int errno = 0; char *right_brace; down_read(kgr_uts_sem); if (copy_to_user(name, utsname(), sizeof *name)) errno = -EFAULT; up_read(kgr_uts_sem); /* add "/kGraft" to the git commit id */ if (errno) goto override; if (strlen(name->version) + strlen(KGR_TAG) >= sizeof(name->version)) { WARN_ONCE(1, "kgraft-patch: not enough space for utsname.version extension"); goto override; } right_brace = strchr(name->version, ')'); if (!right_brace) { WARN_ONCE(1, "kgraft-patch: did not find the commit id"); goto override; } memmove(right_brace + strlen(KGR_TAG), right_brace, strlen(right_brace) + 1); memcpy(right_brace, KGR_TAG, strlen(KGR_TAG)); override: if (!errno && override_release(name->release, sizeof(name->release))) errno = -EFAULT; if (!errno && override_architecture(name)) errno = -EFAULT; return errno; } static struct kgr_patch patch = { .name = "initial_patch", .owner = THIS_MODULE, .patches = { KGR_PATCH(SyS_newuname, kgr_sys_newuname, true), KGR_PATCH_END } }; static int __init kgr_patcher_init(void) { unsigned long addr; pr_info("kgraft-patch: initializing\n"); addr = kallsyms_lookup_name("uts_sem"); if (!addr) { pr_err("kgraft-patch: symbol uts_sem not resolved\n"); return -EFAULT; } kgr_uts_sem = (struct rw_semaphore *) addr; return kgr_patch_kernel(&patch); } static void __exit kgr_patcher_cleanup(void) { pr_info("kgraft-patch: removed\n"); kgr_patch_remove(&patch); } module_init(kgr_patcher_init); module_exit(kgr_patcher_cleanup); MODULE_LICENSE("GPL");
Locations
Projects
Search
Status Monitor
Help
OpenBuildService.org
Documentation
API Documentation
Code of Conduct
Contact
Support
@OBShq
Terms
openSUSE Build Service is sponsored by
The Open Build Service is an
openSUSE project
.
Sign Up
Log In
Places
Places
All Projects
Status Monitor