($INBOX_DIR/description missing)
 help / color / mirror / Atom feed
From: Cyril Hrubis <chrubis@suse.cz>
To: Li Wang <liwang@redhat.com>
Cc: ltp@lists.linux.it
Subject: Re: [LTP] [PATCH] kallsyms01: Utilize ksymbol table for unauthorized address access
Date: Mon, 29 Apr 2024 16:42:02 +0200	[thread overview]
Message-ID: <Zi-xur-p2H4kWjjQ@yuki> (raw)
In-Reply-To: <20240422053611.3581473-1-liwang@redhat.com>

Hi!
> +struct kallsym {
> +	unsigned long addr;
> +	char type;
> +	char name[128];
> +};
> +
> +struct ksymstbl {
> +	struct kallsym symbol;
> +	struct ksymstbl *next;
> +};
> +
> +static struct ksymstbl *sym_table;
> +static unsigned int nr_symbols;
> +static sigjmp_buf jmpbuf;
> +volatile sig_atomic_t segv_caught = 0;
> +
> +static void segv_handler(int sig)
> +{
> +	if (sig == SIGSEGV)
> +		segv_caught++;
> +	else
> +		tst_res(TFAIL, "Unexpected signal %s", strsignal(sig));
> +
> +	siglongjmp(jmpbuf, 1);
> +}
> +
> +static struct ksymstbl *read_kallsyms(unsigned int *nr_symbols)
> +{
> +	FILE *stream;
> +	char *line = NULL;
> +	size_t len = 0;
> +	unsigned int nr_syms = 0;
> +	struct ksymstbl *head, *item, *i;
> +
> +	item = head = calloc(1, sizeof(*head));
> +	if (head == NULL)
> +		goto out;
> +
> +	stream = SAFE_FOPEN("/proc/kallsyms", "r");
> +
> +	while (getline(&line, &len, stream) != -1) {
> +		i = item;
> +
> +		sscanf(line, "%lx %c %s",
> +				&i->symbol.addr, &i->symbol.type, i->symbol.name);
> +
> +		item = calloc(1, sizeof(*i));
> +		if (item == NULL)
> +			tst_brk(TBROK, "In calloc[]");

We should add SAFE_CALLOC() to the test library. Or maybe
SAFE_ZEROED_MALLOC() because we actually mis-use the calloc() here to
get the memory initialized to zero.

Also it may be actually faster to read the file twice, first time only
to count the addresses and allocate an array of the symbols instead.
That way we avoid all the allocation and list traversal.

static unsigned int read_kallsyms(struct ksymbtl *table, unsigned int table_size)
{
	FILE *stream = SAFE_FOPEN("/proc/kallsyms", "r");
	unsigned int nr_syms = 0;

	while (getline(&line, &len, stream) != -1) {

		if (table && nr_syms < table_size) {
			sscanf(line, "%lx %c %s",
			       &table[nr_syms].addr,
			       ...);
		}

		nr_syms++;
	}

	return nr_syms;
}


static void setup(void)
{
	unsigned int nr_syms;

	nr_syms = read_kallsyms(NULL, 0);

	sym_table = SAFE_MALLOC(sizeof(*sym_table) * nr_syms);

	if (nr_syms != read_kallsyms(sym_table, nr_syms))
		tst_res(TWARN, "/proc/kallsyms changed size!?");
}

> +		i->next = item;
> +		nr_syms += 1;
> +	}
> +
> +	*nr_symbols = nr_syms;
> +	SAFE_FCLOSE(stream);
> +out:
> +	return head;
> +}
> +
> +static void setup(void)
> +{
> +	sym_table = read_kallsyms(&nr_symbols);
> +	if (!sym_table)
> +		tst_brk(TBROK, "Failed to read kernel symbols");
> +}
> +
> +static void access_ksymbols_address(struct ksymstbl *sym_table)
> +{
> +	if (sigsetjmp(jmpbuf, 1) == 0) {
> +		*(volatile unsigned long *)sym_table->symbol.addr = 0;
> +
> +		tst_res(TFAIL, "Successfully accessed kernel addr 0x%lx (%s)",
> +			sym_table->symbol.addr, sym_table->symbol.name);
> +	}
> +
> +}
> +
> +static void test_access_kernel_address(void)
> +{
> +	struct ksymstbl *current;
> +	struct sigaction sa;
> +
> +	memset(&sa, 0, sizeof(sa));
> +	sa.sa_handler = segv_handler;
> +	sigaction(SIGSEGV, &sa, NULL);
> +
> +	current = sym_table;
> +	while (current->next != NULL) {
> +		access_ksymbols_address(current);
> +		current = current->next;
> +	}
> +
> +	if (segv_caught == (sig_atomic_t)nr_symbols)
> +		tst_res(TPASS, "Caught %d times SIGSEGV in access ksymbols addr", segv_caught);
> +}
> +
> +static void cleanup(void)
> +{
> +	while (sym_table != NULL) {
> +		struct ksymstbl *temp = sym_table;
> +		sym_table = sym_table->next;
> +		free(temp);
> +	}
> +}
> +
> +static struct tst_test test = {
> +	.needs_root = 1,
> +	.setup = setup,
> +	.cleanup = cleanup,
> +	.max_runtime = 60,
> +	.test_all = test_access_kernel_address,
> +};

-- 
Cyril Hrubis
chrubis@suse.cz

-- 
Mailing list info: https://lists.linux.it/listinfo/ltp

      reply	other threads:[~2024-04-29 14:43 UTC|newest]

Thread overview: 2+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2024-04-22  5:36 [LTP] [PATCH] kallsyms01: Utilize ksymbol table for unauthorized address access Li Wang
2024-04-29 14:42 ` Cyril Hrubis [this message]

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=Zi-xur-p2H4kWjjQ@yuki \
    --to=chrubis@suse.cz \
    --cc=liwang@redhat.com \
    --cc=ltp@lists.linux.it \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).