cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

bootconfig.c (2021B)


      1// SPDX-License-Identifier: GPL-2.0
      2/*
      3 * /proc/bootconfig - Extra boot configuration
      4 */
      5#include <linux/fs.h>
      6#include <linux/init.h>
      7#include <linux/printk.h>
      8#include <linux/proc_fs.h>
      9#include <linux/seq_file.h>
     10#include <linux/bootconfig.h>
     11#include <linux/slab.h>
     12
     13static char *saved_boot_config;
     14
     15static int boot_config_proc_show(struct seq_file *m, void *v)
     16{
     17	if (saved_boot_config)
     18		seq_puts(m, saved_boot_config);
     19	return 0;
     20}
     21
     22/* Rest size of buffer */
     23#define rest(dst, end) ((end) > (dst) ? (end) - (dst) : 0)
     24
     25/* Return the needed total length if @size is 0 */
     26static int __init copy_xbc_key_value_list(char *dst, size_t size)
     27{
     28	struct xbc_node *leaf, *vnode;
     29	char *key, *end = dst + size;
     30	const char *val;
     31	char q;
     32	int ret = 0;
     33
     34	key = kzalloc(XBC_KEYLEN_MAX, GFP_KERNEL);
     35	if (!key)
     36		return -ENOMEM;
     37
     38	xbc_for_each_key_value(leaf, val) {
     39		ret = xbc_node_compose_key(leaf, key, XBC_KEYLEN_MAX);
     40		if (ret < 0)
     41			break;
     42		ret = snprintf(dst, rest(dst, end), "%s = ", key);
     43		if (ret < 0)
     44			break;
     45		dst += ret;
     46		vnode = xbc_node_get_child(leaf);
     47		if (vnode) {
     48			xbc_array_for_each_value(vnode, val) {
     49				if (strchr(val, '"'))
     50					q = '\'';
     51				else
     52					q = '"';
     53				ret = snprintf(dst, rest(dst, end), "%c%s%c%s",
     54					q, val, q, xbc_node_is_array(vnode) ? ", " : "\n");
     55				if (ret < 0)
     56					goto out;
     57				dst += ret;
     58			}
     59		} else {
     60			ret = snprintf(dst, rest(dst, end), "\"\"\n");
     61			if (ret < 0)
     62				break;
     63			dst += ret;
     64		}
     65	}
     66out:
     67	kfree(key);
     68
     69	return ret < 0 ? ret : dst - (end - size);
     70}
     71
     72static int __init proc_boot_config_init(void)
     73{
     74	int len;
     75
     76	len = copy_xbc_key_value_list(NULL, 0);
     77	if (len < 0)
     78		return len;
     79
     80	if (len > 0) {
     81		saved_boot_config = kzalloc(len + 1, GFP_KERNEL);
     82		if (!saved_boot_config)
     83			return -ENOMEM;
     84
     85		len = copy_xbc_key_value_list(saved_boot_config, len + 1);
     86		if (len < 0) {
     87			kfree(saved_boot_config);
     88			return len;
     89		}
     90	}
     91
     92	proc_create_single("bootconfig", 0, NULL, boot_config_proc_show);
     93
     94	return 0;
     95}
     96fs_initcall(proc_boot_config_init);