Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0
0002 
0003 #define _GNU_SOURCE
0004 #include <errno.h>
0005 #include <fcntl.h>
0006 #include <inttypes.h>
0007 #include <limits.h>
0008 #include <linux/types.h>
0009 #include <sched.h>
0010 #include <signal.h>
0011 #include <stdbool.h>
0012 #include <stdio.h>
0013 #include <stdlib.h>
0014 #include <string.h>
0015 #include <syscall.h>
0016 #include <sys/mount.h>
0017 #include <sys/prctl.h>
0018 #include <sys/wait.h>
0019 #include <unistd.h>
0020 
0021 #include "pidfd.h"
0022 #include "../kselftest.h"
0023 
0024 static int safe_int(const char *numstr, int *converted)
0025 {
0026     char *err = NULL;
0027     long sli;
0028 
0029     errno = 0;
0030     sli = strtol(numstr, &err, 0);
0031     if (errno == ERANGE && (sli == LONG_MAX || sli == LONG_MIN))
0032         return -ERANGE;
0033 
0034     if (errno != 0 && sli == 0)
0035         return -EINVAL;
0036 
0037     if (err == numstr || *err != '\0')
0038         return -EINVAL;
0039 
0040     if (sli > INT_MAX || sli < INT_MIN)
0041         return -ERANGE;
0042 
0043     *converted = (int)sli;
0044     return 0;
0045 }
0046 
0047 static int char_left_gc(const char *buffer, size_t len)
0048 {
0049     size_t i;
0050 
0051     for (i = 0; i < len; i++) {
0052         if (buffer[i] == ' ' ||
0053             buffer[i] == '\t')
0054             continue;
0055 
0056         return i;
0057     }
0058 
0059     return 0;
0060 }
0061 
0062 static int char_right_gc(const char *buffer, size_t len)
0063 {
0064     int i;
0065 
0066     for (i = len - 1; i >= 0; i--) {
0067         if (buffer[i] == ' '  ||
0068             buffer[i] == '\t' ||
0069             buffer[i] == '\n' ||
0070             buffer[i] == '\0')
0071             continue;
0072 
0073         return i + 1;
0074     }
0075 
0076     return 0;
0077 }
0078 
0079 static char *trim_whitespace_in_place(char *buffer)
0080 {
0081     buffer += char_left_gc(buffer, strlen(buffer));
0082     buffer[char_right_gc(buffer, strlen(buffer))] = '\0';
0083     return buffer;
0084 }
0085 
0086 static pid_t get_pid_from_fdinfo_file(int pidfd, const char *key, size_t keylen)
0087 {
0088     int ret;
0089     char path[512];
0090     FILE *f;
0091     size_t n = 0;
0092     pid_t result = -1;
0093     char *line = NULL;
0094 
0095     snprintf(path, sizeof(path), "/proc/self/fdinfo/%d", pidfd);
0096 
0097     f = fopen(path, "re");
0098     if (!f)
0099         return -1;
0100 
0101     while (getline(&line, &n, f) != -1) {
0102         char *numstr;
0103 
0104         if (strncmp(line, key, keylen))
0105             continue;
0106 
0107         numstr = trim_whitespace_in_place(line + 4);
0108         ret = safe_int(numstr, &result);
0109         if (ret < 0)
0110             goto out;
0111 
0112         break;
0113     }
0114 
0115 out:
0116     free(line);
0117     fclose(f);
0118     return result;
0119 }
0120 
0121 int main(int argc, char **argv)
0122 {
0123     int pidfd = -1, ret = 1;
0124     pid_t pid;
0125 
0126     ksft_set_plan(3);
0127 
0128     pidfd = sys_pidfd_open(-1, 0);
0129     if (pidfd >= 0) {
0130         ksft_print_msg(
0131             "%s - succeeded to open pidfd for invalid pid -1\n",
0132             strerror(errno));
0133         goto on_error;
0134     }
0135     ksft_test_result_pass("do not allow invalid pid test: passed\n");
0136 
0137     pidfd = sys_pidfd_open(getpid(), 1);
0138     if (pidfd >= 0) {
0139         ksft_print_msg(
0140             "%s - succeeded to open pidfd with invalid flag value specified\n",
0141             strerror(errno));
0142         goto on_error;
0143     }
0144     ksft_test_result_pass("do not allow invalid flag test: passed\n");
0145 
0146     pidfd = sys_pidfd_open(getpid(), 0);
0147     if (pidfd < 0) {
0148         ksft_print_msg("%s - failed to open pidfd\n", strerror(errno));
0149         goto on_error;
0150     }
0151     ksft_test_result_pass("open a new pidfd test: passed\n");
0152 
0153     pid = get_pid_from_fdinfo_file(pidfd, "Pid:", sizeof("Pid:") - 1);
0154     ksft_print_msg("pidfd %d refers to process with pid %d\n", pidfd, pid);
0155 
0156     ret = 0;
0157 
0158 on_error:
0159     if (pidfd >= 0)
0160         close(pidfd);
0161 
0162     return !ret ? ksft_exit_pass() : ksft_exit_fail();
0163 }