]> git.ipfire.org Git - thirdparty/linux.git/commitdiff
selftests/seccomp: Refactor get_proc_stat to split out file reading code
authorSargun Dhillon <sargun@sargun.me>
Tue, 3 May 2022 08:09:57 +0000 (01:09 -0700)
committerKees Cook <keescook@chromium.org>
Tue, 3 May 2022 21:20:49 +0000 (14:20 -0700)
This splits up the get_proc_stat function to make it so we can use it as a
generic helper to read the nth field from multiple different files, versus
replicating the logic in multiple places.

Signed-off-by: Sargun Dhillon <sargun@sargun.me>
Cc: linux-kselftest@vger.kernel.org
Signed-off-by: Kees Cook <keescook@chromium.org>
Link: https://lore.kernel.org/r/20220503080958.20220-3-sargun@sargun.me
tools/testing/selftests/seccomp/seccomp_bpf.c

index 6001e9ecfaf5ea5ef145f0e0047501963617aa34..e282f521f8d7013feaed631afb84a67871572e8a 100644 (file)
@@ -4297,32 +4297,54 @@ TEST_F(O_SUSPEND_SECCOMP, seize)
        ASSERT_EQ(EPERM, errno);
 }
 
-static char get_proc_stat(int pid)
+/*
+ * get_nth - Get the nth, space separated entry in a file.
+ *
+ * Returns the length of the read field.
+ * Throws error if field is zero-lengthed.
+ */
+static ssize_t get_nth(struct __test_metadata *_metadata, const char *path,
+                    const unsigned int position, char **entry)
 {
-       char proc_path[100] = {0};
        char *line = NULL;
-       size_t len = 0;
+       unsigned int i;
        ssize_t nread;
-       char status;
+       size_t len = 0;
        FILE *f;
-       int i;
 
-       snprintf(proc_path, sizeof(proc_path), "/proc/%d/stat", pid);
-       f = fopen(proc_path, "r");
-       if (f == NULL)
-               ksft_exit_fail_msg("%s - Could not open %s\n",
-                                  strerror(errno), proc_path);
+       f = fopen(path, "r");
+       ASSERT_NE(f, NULL) {
+               TH_LOG("Coud not open %s: %s", path, strerror(errno));
+       }
 
-       for (i = 0; i < 3; i++) {
+       for (i = 0; i < position; i++) {
                nread = getdelim(&line, &len, ' ', f);
-               if (nread <= 0)
-                       ksft_exit_fail_msg("Failed to read status: %s\n",
-                                          strerror(errno));
+               ASSERT_GE(nread, 0) {
+                       TH_LOG("Failed to read %d entry in file %s", i, path);
+               }
        }
+       fclose(f);
+
+       ASSERT_GT(nread, 0) {
+               TH_LOG("Entry in file %s had zero length", path);
+       }
+
+       *entry = line;
+       return nread - 1;
+}
+
+/* For a given PID, get the task state (D, R, etc...) */
+static char get_proc_stat(struct __test_metadata *_metadata, pid_t pid)
+{
+       char proc_path[100] = {0};
+       char status;
+       char *line;
+
+       snprintf(proc_path, sizeof(proc_path), "/proc/%d/stat", pid);
+       ASSERT_EQ(get_nth(_metadata, proc_path, 3, &line), 1);
 
        status = *line;
        free(line);
-       fclose(f);
 
        return status;
 }
@@ -4383,7 +4405,7 @@ TEST(user_notification_fifo)
        /* This spins until all of the children are sleeping */
 restart_wait:
        for (i = 0; i < ARRAY_SIZE(pids); i++) {
-               if (get_proc_stat(pids[i]) != 'S') {
+               if (get_proc_stat(_metadata, pids[i]) != 'S') {
                        nanosleep(&delay, NULL);
                        goto restart_wait;
                }