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

futex_wait_uninitialized_heap.c (2629B)


      1// SPDX-License-Identifier: GPL-2.0-or-later
      2/******************************************************************************
      3 *
      4 * Copyright FUJITSU LIMITED 2010
      5 * Copyright KOSAKI Motohiro <kosaki.motohiro@jp.fujitsu.com>
      6 *
      7 * DESCRIPTION
      8 *      Wait on uninitialized heap. It shold be zero and FUTEX_WAIT should
      9 *      return immediately. This test is intent to test zero page handling in
     10 *      futex.
     11 *
     12 * AUTHOR
     13 *      KOSAKI Motohiro <kosaki.motohiro@jp.fujitsu.com>
     14 *
     15 * HISTORY
     16 *      2010-Jan-6: Initial version by KOSAKI Motohiro <kosaki.motohiro@jp.fujitsu.com>
     17 *
     18 *****************************************************************************/
     19
     20#include <pthread.h>
     21#include <stdio.h>
     22#include <stdlib.h>
     23#include <sys/mman.h>
     24#include <syscall.h>
     25#include <sys/types.h>
     26#include <sys/stat.h>
     27#include <unistd.h>
     28#include <errno.h>
     29#include <linux/futex.h>
     30#include <libgen.h>
     31
     32#include "logging.h"
     33#include "futextest.h"
     34
     35#define TEST_NAME "futex-wait-uninitialized-heap"
     36#define WAIT_US 5000000
     37
     38static int child_blocked = 1;
     39static int child_ret;
     40void *buf;
     41
     42void usage(char *prog)
     43{
     44	printf("Usage: %s\n", prog);
     45	printf("  -c	Use color\n");
     46	printf("  -h	Display this help message\n");
     47	printf("  -v L	Verbosity level: %d=QUIET %d=CRITICAL %d=INFO\n",
     48	       VQUIET, VCRITICAL, VINFO);
     49}
     50
     51void *wait_thread(void *arg)
     52{
     53	int res;
     54
     55	child_ret = RET_PASS;
     56	res = futex_wait(buf, 1, NULL, 0);
     57	child_blocked = 0;
     58
     59	if (res != 0 && errno != EWOULDBLOCK) {
     60		error("futex failure\n", errno);
     61		child_ret = RET_ERROR;
     62	}
     63	pthread_exit(NULL);
     64}
     65
     66int main(int argc, char **argv)
     67{
     68	int c, ret = RET_PASS;
     69	long page_size;
     70	pthread_t thr;
     71
     72	while ((c = getopt(argc, argv, "chv:")) != -1) {
     73		switch (c) {
     74		case 'c':
     75			log_color(1);
     76			break;
     77		case 'h':
     78			usage(basename(argv[0]));
     79			exit(0);
     80		case 'v':
     81			log_verbosity(atoi(optarg));
     82			break;
     83		default:
     84			usage(basename(argv[0]));
     85			exit(1);
     86		}
     87	}
     88
     89	page_size = sysconf(_SC_PAGESIZE);
     90
     91	buf = mmap(NULL, page_size, PROT_READ|PROT_WRITE,
     92		   MAP_PRIVATE|MAP_ANONYMOUS, 0, 0);
     93	if (buf == (void *)-1) {
     94		error("mmap\n", errno);
     95		exit(1);
     96	}
     97
     98	ksft_print_header();
     99	ksft_set_plan(1);
    100	ksft_print_msg("%s: Test the uninitialized futex value in FUTEX_WAIT\n",
    101	       basename(argv[0]));
    102
    103
    104	ret = pthread_create(&thr, NULL, wait_thread, NULL);
    105	if (ret) {
    106		error("pthread_create\n", errno);
    107		ret = RET_ERROR;
    108		goto out;
    109	}
    110
    111	info("waiting %dus for child to return\n", WAIT_US);
    112	usleep(WAIT_US);
    113
    114	ret = child_ret;
    115	if (child_blocked) {
    116		fail("child blocked in kernel\n");
    117		ret = RET_FAIL;
    118	}
    119
    120 out:
    121	print_result(TEST_NAME, ret);
    122	return ret;
    123}