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

pidfd_open_test.c (3074B)


      1// SPDX-License-Identifier: GPL-2.0
      2
      3#define _GNU_SOURCE
      4#include <errno.h>
      5#include <fcntl.h>
      6#include <inttypes.h>
      7#include <limits.h>
      8#include <linux/types.h>
      9#include <sched.h>
     10#include <signal.h>
     11#include <stdbool.h>
     12#include <stdio.h>
     13#include <stdlib.h>
     14#include <string.h>
     15#include <syscall.h>
     16#include <sys/mount.h>
     17#include <sys/prctl.h>
     18#include <sys/wait.h>
     19#include <unistd.h>
     20
     21#include "pidfd.h"
     22#include "../kselftest.h"
     23
     24static int safe_int(const char *numstr, int *converted)
     25{
     26	char *err = NULL;
     27	long sli;
     28
     29	errno = 0;
     30	sli = strtol(numstr, &err, 0);
     31	if (errno == ERANGE && (sli == LONG_MAX || sli == LONG_MIN))
     32		return -ERANGE;
     33
     34	if (errno != 0 && sli == 0)
     35		return -EINVAL;
     36
     37	if (err == numstr || *err != '\0')
     38		return -EINVAL;
     39
     40	if (sli > INT_MAX || sli < INT_MIN)
     41		return -ERANGE;
     42
     43	*converted = (int)sli;
     44	return 0;
     45}
     46
     47static int char_left_gc(const char *buffer, size_t len)
     48{
     49	size_t i;
     50
     51	for (i = 0; i < len; i++) {
     52		if (buffer[i] == ' ' ||
     53		    buffer[i] == '\t')
     54			continue;
     55
     56		return i;
     57	}
     58
     59	return 0;
     60}
     61
     62static int char_right_gc(const char *buffer, size_t len)
     63{
     64	int i;
     65
     66	for (i = len - 1; i >= 0; i--) {
     67		if (buffer[i] == ' '  ||
     68		    buffer[i] == '\t' ||
     69		    buffer[i] == '\n' ||
     70		    buffer[i] == '\0')
     71			continue;
     72
     73		return i + 1;
     74	}
     75
     76	return 0;
     77}
     78
     79static char *trim_whitespace_in_place(char *buffer)
     80{
     81	buffer += char_left_gc(buffer, strlen(buffer));
     82	buffer[char_right_gc(buffer, strlen(buffer))] = '\0';
     83	return buffer;
     84}
     85
     86static pid_t get_pid_from_fdinfo_file(int pidfd, const char *key, size_t keylen)
     87{
     88	int ret;
     89	char path[512];
     90	FILE *f;
     91	size_t n = 0;
     92	pid_t result = -1;
     93	char *line = NULL;
     94
     95	snprintf(path, sizeof(path), "/proc/self/fdinfo/%d", pidfd);
     96
     97	f = fopen(path, "re");
     98	if (!f)
     99		return -1;
    100
    101	while (getline(&line, &n, f) != -1) {
    102		char *numstr;
    103
    104		if (strncmp(line, key, keylen))
    105			continue;
    106
    107		numstr = trim_whitespace_in_place(line + 4);
    108		ret = safe_int(numstr, &result);
    109		if (ret < 0)
    110			goto out;
    111
    112		break;
    113	}
    114
    115out:
    116	free(line);
    117	fclose(f);
    118	return result;
    119}
    120
    121int main(int argc, char **argv)
    122{
    123	int pidfd = -1, ret = 1;
    124	pid_t pid;
    125
    126	ksft_set_plan(3);
    127
    128	pidfd = sys_pidfd_open(-1, 0);
    129	if (pidfd >= 0) {
    130		ksft_print_msg(
    131			"%s - succeeded to open pidfd for invalid pid -1\n",
    132			strerror(errno));
    133		goto on_error;
    134	}
    135	ksft_test_result_pass("do not allow invalid pid test: passed\n");
    136
    137	pidfd = sys_pidfd_open(getpid(), 1);
    138	if (pidfd >= 0) {
    139		ksft_print_msg(
    140			"%s - succeeded to open pidfd with invalid flag value specified\n",
    141			strerror(errno));
    142		goto on_error;
    143	}
    144	ksft_test_result_pass("do not allow invalid flag test: passed\n");
    145
    146	pidfd = sys_pidfd_open(getpid(), 0);
    147	if (pidfd < 0) {
    148		ksft_print_msg("%s - failed to open pidfd\n", strerror(errno));
    149		goto on_error;
    150	}
    151	ksft_test_result_pass("open a new pidfd test: passed\n");
    152
    153	pid = get_pid_from_fdinfo_file(pidfd, "Pid:", sizeof("Pid:") - 1);
    154	ksft_print_msg("pidfd %d refers to process with pid %d\n", pidfd, pid);
    155
    156	ret = 0;
    157
    158on_error:
    159	if (pidfd >= 0)
    160		close(pidfd);
    161
    162	return !ret ? ksft_exit_pass() : ksft_exit_fail();
    163}