brintos

brintos / linux-shallow public Read only

0
0
Text · 2.5 KiB · dd80278 Raw
117 lines · c
1// SPDX-License-Identifier: GPL-2.02/*3 * Copyright (C) 2017-2023 SUSE4 * Authors: Libor Pechacek <lpechacek@suse.cz>5 *          Nicolai Stange <nstange@suse.de>6 *          Marcos Paulo de Souza <mpdesouza@suse.com>7 */8 9#include <linux/module.h>10#include <linux/kernel.h>11#include <linux/sched.h>12#include <linux/slab.h>13#include <linux/livepatch.h>14 15#if defined(__x86_64__)16#define FN_PREFIX __x64_17#elif defined(__s390x__)18#define FN_PREFIX __s390x_19#elif defined(__aarch64__)20#define FN_PREFIX __arm64_21#else22/* powerpc does not select ARCH_HAS_SYSCALL_WRAPPER */23#define FN_PREFIX24#endif25 26/* Protects klp_pids */27static DEFINE_MUTEX(kpid_mutex);28 29static unsigned int npids, npids_pending;30static int klp_pids[NR_CPUS];31module_param_array(klp_pids, int, &npids_pending, 0);32MODULE_PARM_DESC(klp_pids, "Array of pids to be transitioned to livepatched state.");33 34static ssize_t npids_show(struct kobject *kobj, struct kobj_attribute *attr,35			  char *buf)36{37	return sprintf(buf, "%u\n", npids_pending);38}39 40static struct kobj_attribute klp_attr = __ATTR_RO(npids);41static struct kobject *klp_kobj;42 43static asmlinkage long lp_sys_getpid(void)44{45	int i;46 47	mutex_lock(&kpid_mutex);48	if (npids_pending > 0) {49		for (i = 0; i < npids; i++) {50			if (current->pid == klp_pids[i]) {51				klp_pids[i] = 0;52				npids_pending--;53				break;54			}55		}56	}57	mutex_unlock(&kpid_mutex);58 59	return task_tgid_vnr(current);60}61 62static struct klp_func vmlinux_funcs[] = {63	{64		.old_name = __stringify(FN_PREFIX) "sys_getpid",65		.new_func = lp_sys_getpid,66	}, {}67};68 69static struct klp_object objs[] = {70	{71		/* name being NULL means vmlinux */72		.funcs = vmlinux_funcs,73	}, {}74};75 76static struct klp_patch patch = {77	.mod = THIS_MODULE,78	.objs = objs,79};80 81static int livepatch_init(void)82{83	int ret;84 85	klp_kobj = kobject_create_and_add("test_klp_syscall", kernel_kobj);86	if (!klp_kobj)87		return -ENOMEM;88 89	ret = sysfs_create_file(klp_kobj, &klp_attr.attr);90	if (ret) {91		kobject_put(klp_kobj);92		return ret;93	}94 95	/*96	 * Save the number pids to transition to livepatched state before the97	 * number of pending pids is decremented.98	 */99	npids = npids_pending;100 101	return klp_enable_patch(&patch);102}103 104static void livepatch_exit(void)105{106	kobject_put(klp_kobj);107}108 109module_init(livepatch_init);110module_exit(livepatch_exit);111MODULE_LICENSE("GPL");112MODULE_INFO(livepatch, "Y");113MODULE_AUTHOR("Libor Pechacek <lpechacek@suse.cz>");114MODULE_AUTHOR("Nicolai Stange <nstange@suse.de>");115MODULE_AUTHOR("Marcos Paulo de Souza <mpdesouza@suse.com>");116MODULE_DESCRIPTION("Livepatch test: syscall transition");117