~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

TOMOYO Linux Cross Reference
Linux/tools/testing/selftests/powerpc/dexcr/dexcr_test.c

Version: ~ [ linux-6.11.5 ] ~ [ linux-6.10.14 ] ~ [ linux-6.9.12 ] ~ [ linux-6.8.12 ] ~ [ linux-6.7.12 ] ~ [ linux-6.6.58 ] ~ [ linux-6.5.13 ] ~ [ linux-6.4.16 ] ~ [ linux-6.3.13 ] ~ [ linux-6.2.16 ] ~ [ linux-6.1.114 ] ~ [ linux-6.0.19 ] ~ [ linux-5.19.17 ] ~ [ linux-5.18.19 ] ~ [ linux-5.17.15 ] ~ [ linux-5.16.20 ] ~ [ linux-5.15.169 ] ~ [ linux-5.14.21 ] ~ [ linux-5.13.19 ] ~ [ linux-5.12.19 ] ~ [ linux-5.11.22 ] ~ [ linux-5.10.228 ] ~ [ linux-5.9.16 ] ~ [ linux-5.8.18 ] ~ [ linux-5.7.19 ] ~ [ linux-5.6.19 ] ~ [ linux-5.5.19 ] ~ [ linux-5.4.284 ] ~ [ linux-5.3.18 ] ~ [ linux-5.2.21 ] ~ [ linux-5.1.21 ] ~ [ linux-5.0.21 ] ~ [ linux-4.20.17 ] ~ [ linux-4.19.322 ] ~ [ linux-4.18.20 ] ~ [ linux-4.17.19 ] ~ [ linux-4.16.18 ] ~ [ linux-4.15.18 ] ~ [ linux-4.14.336 ] ~ [ linux-4.13.16 ] ~ [ linux-4.12.14 ] ~ [ linux-4.11.12 ] ~ [ linux-4.10.17 ] ~ [ linux-4.9.337 ] ~ [ linux-4.4.302 ] ~ [ linux-3.10.108 ] ~ [ linux-2.6.32.71 ] ~ [ linux-2.6.0 ] ~ [ linux-2.4.37.11 ] ~ [ unix-v6-master ] ~ [ ccs-tools-1.8.9 ] ~ [ policy-sample ] ~
Architecture: ~ [ i386 ] ~ [ alpha ] ~ [ m68k ] ~ [ mips ] ~ [ ppc ] ~ [ sparc ] ~ [ sparc64 ] ~

  1 // SPDX-License-Identifier: GPL-2.0-or-later
  2 
  3 #include <errno.h>
  4 #include <fcntl.h>
  5 #include <stdlib.h>
  6 #include <string.h>
  7 #include <sys/prctl.h>
  8 #include <unistd.h>
  9 
 10 #include "dexcr.h"
 11 #include "utils.h"
 12 
 13 /*
 14  * Helper function for testing the behaviour of a newly exec-ed process
 15  */
 16 static int dexcr_prctl_onexec_test_child(unsigned long which, const char *status)
 17 {
 18         unsigned long dexcr = mfspr(SPRN_DEXCR_RO);
 19         unsigned long aspect = pr_which_to_aspect(which);
 20         int ctrl = pr_get_dexcr(which);
 21 
 22         if (!strcmp(status, "set")) {
 23                 FAIL_IF_EXIT_MSG(!(ctrl & PR_PPC_DEXCR_CTRL_SET),
 24                                  "setting aspect across exec not applied");
 25 
 26                 FAIL_IF_EXIT_MSG(!(ctrl & PR_PPC_DEXCR_CTRL_SET_ONEXEC),
 27                                  "setting aspect across exec not inherited");
 28 
 29                 FAIL_IF_EXIT_MSG(!(aspect & dexcr), "setting aspect across exec did not take effect");
 30         } else if (!strcmp(status, "clear")) {
 31                 FAIL_IF_EXIT_MSG(!(ctrl & PR_PPC_DEXCR_CTRL_CLEAR),
 32                                  "clearing aspect across exec not applied");
 33 
 34                 FAIL_IF_EXIT_MSG(!(ctrl & PR_PPC_DEXCR_CTRL_CLEAR_ONEXEC),
 35                                  "clearing aspect across exec not inherited");
 36 
 37                 FAIL_IF_EXIT_MSG(aspect & dexcr, "clearing aspect across exec did not take effect");
 38         } else {
 39                 FAIL_IF_EXIT_MSG(true, "unknown expected status");
 40         }
 41 
 42         return 0;
 43 }
 44 
 45 /*
 46  * Test that the given prctl value can be manipulated freely
 47  */
 48 static int dexcr_prctl_aspect_test(unsigned long which)
 49 {
 50         unsigned long aspect = pr_which_to_aspect(which);
 51         pid_t pid;
 52         int ctrl;
 53         int err;
 54         int errno_save;
 55 
 56         SKIP_IF_MSG(!dexcr_exists(), "DEXCR not supported");
 57         SKIP_IF_MSG(!pr_dexcr_aspect_supported(which), "DEXCR aspect not supported");
 58         SKIP_IF_MSG(!pr_dexcr_aspect_editable(which), "DEXCR aspect not editable with prctl");
 59 
 60         /* We reject invalid combinations of arguments */
 61         err = pr_set_dexcr(which, PR_PPC_DEXCR_CTRL_SET | PR_PPC_DEXCR_CTRL_CLEAR);
 62         errno_save = errno;
 63         FAIL_IF_MSG(err != -1, "simultaneous set and clear should be rejected");
 64         FAIL_IF_MSG(errno_save != EINVAL, "simultaneous set and clear should be rejected with EINVAL");
 65 
 66         err = pr_set_dexcr(which, PR_PPC_DEXCR_CTRL_SET_ONEXEC | PR_PPC_DEXCR_CTRL_CLEAR_ONEXEC);
 67         errno_save = errno;
 68         FAIL_IF_MSG(err != -1, "simultaneous set and clear on exec should be rejected");
 69         FAIL_IF_MSG(errno_save != EINVAL, "simultaneous set and clear on exec should be rejected with EINVAL");
 70 
 71         /* We set the aspect */
 72         err = pr_set_dexcr(which, PR_PPC_DEXCR_CTRL_SET);
 73         FAIL_IF_MSG(err, "PR_PPC_DEXCR_CTRL_SET failed");
 74 
 75         ctrl = pr_get_dexcr(which);
 76         FAIL_IF_MSG(!(ctrl & PR_PPC_DEXCR_CTRL_SET), "config value not PR_PPC_DEXCR_CTRL_SET");
 77         FAIL_IF_MSG(ctrl & PR_PPC_DEXCR_CTRL_CLEAR, "config value unexpected clear flag");
 78         FAIL_IF_MSG(!(aspect & mfspr(SPRN_DEXCR_RO)), "setting aspect did not take effect");
 79 
 80         /* We clear the aspect */
 81         err = pr_set_dexcr(which, PR_PPC_DEXCR_CTRL_CLEAR);
 82         FAIL_IF_MSG(err, "PR_PPC_DEXCR_CTRL_CLEAR failed");
 83 
 84         ctrl = pr_get_dexcr(which);
 85         FAIL_IF_MSG(!(ctrl & PR_PPC_DEXCR_CTRL_CLEAR), "config value not PR_PPC_DEXCR_CTRL_CLEAR");
 86         FAIL_IF_MSG(ctrl & PR_PPC_DEXCR_CTRL_SET, "config value unexpected set flag");
 87         FAIL_IF_MSG(aspect & mfspr(SPRN_DEXCR_RO), "clearing aspect did not take effect");
 88 
 89         /* We make it set on exec (doesn't change our current value) */
 90         err = pr_set_dexcr(which, PR_PPC_DEXCR_CTRL_SET_ONEXEC);
 91         FAIL_IF_MSG(err, "PR_PPC_DEXCR_CTRL_SET_ONEXEC failed");
 92 
 93         ctrl = pr_get_dexcr(which);
 94         FAIL_IF_MSG(!(ctrl & PR_PPC_DEXCR_CTRL_CLEAR), "process aspect should still be cleared");
 95         FAIL_IF_MSG(!(ctrl & PR_PPC_DEXCR_CTRL_SET_ONEXEC), "config value not PR_PPC_DEXCR_CTRL_SET_ONEXEC");
 96         FAIL_IF_MSG(ctrl & PR_PPC_DEXCR_CTRL_CLEAR_ONEXEC, "config value unexpected clear on exec flag");
 97         FAIL_IF_MSG(aspect & mfspr(SPRN_DEXCR_RO), "scheduling aspect to set on exec should not change it now");
 98 
 99         /* We make it clear on exec (doesn't change our current value) */
100         err = pr_set_dexcr(which, PR_PPC_DEXCR_CTRL_CLEAR_ONEXEC);
101         FAIL_IF_MSG(err, "PR_PPC_DEXCR_CTRL_CLEAR_ONEXEC failed");
102 
103         ctrl = pr_get_dexcr(which);
104         FAIL_IF_MSG(!(ctrl & PR_PPC_DEXCR_CTRL_CLEAR), "process aspect config should still be cleared");
105         FAIL_IF_MSG(!(ctrl & PR_PPC_DEXCR_CTRL_CLEAR_ONEXEC), "config value not PR_PPC_DEXCR_CTRL_CLEAR_ONEXEC");
106         FAIL_IF_MSG(ctrl & PR_PPC_DEXCR_CTRL_SET_ONEXEC, "config value unexpected set on exec flag");
107         FAIL_IF_MSG(aspect & mfspr(SPRN_DEXCR_RO), "process aspect should still be cleared");
108 
109         /* We allow setting the current and on-exec value in a single call */
110         err = pr_set_dexcr(which, PR_PPC_DEXCR_CTRL_SET | PR_PPC_DEXCR_CTRL_CLEAR_ONEXEC);
111         FAIL_IF_MSG(err, "PR_PPC_DEXCR_CTRL_SET | PR_PPC_DEXCR_CTRL_CLEAR_ONEXEC failed");
112 
113         ctrl = pr_get_dexcr(which);
114         FAIL_IF_MSG(!(ctrl & PR_PPC_DEXCR_CTRL_SET), "config value not PR_PPC_DEXCR_CTRL_SET");
115         FAIL_IF_MSG(!(ctrl & PR_PPC_DEXCR_CTRL_CLEAR_ONEXEC), "config value not PR_PPC_DEXCR_CTRL_CLEAR_ONEXEC");
116         FAIL_IF_MSG(!(aspect & mfspr(SPRN_DEXCR_RO)), "process aspect should be set");
117 
118         err = pr_set_dexcr(which, PR_PPC_DEXCR_CTRL_CLEAR | PR_PPC_DEXCR_CTRL_SET_ONEXEC);
119         FAIL_IF_MSG(err, "PR_PPC_DEXCR_CTRL_CLEAR | PR_PPC_DEXCR_CTRL_SET_ONEXEC failed");
120 
121         ctrl = pr_get_dexcr(which);
122         FAIL_IF_MSG(!(ctrl & PR_PPC_DEXCR_CTRL_CLEAR), "config value not PR_PPC_DEXCR_CTRL_CLEAR");
123         FAIL_IF_MSG(!(ctrl & PR_PPC_DEXCR_CTRL_SET_ONEXEC), "config value not PR_PPC_DEXCR_CTRL_SET_ONEXEC");
124         FAIL_IF_MSG(aspect & mfspr(SPRN_DEXCR_RO), "process aspect should be clear");
125 
126         /* Verify the onexec value is applied across exec */
127         pid = fork();
128         if (!pid) {
129                 char which_str[32] = {};
130                 char *args[] = { "dexcr_prctl_onexec_test_child", which_str, "set", NULL };
131                 unsigned int ctrl = pr_get_dexcr(which);
132 
133                 sprintf(which_str, "%lu", which);
134 
135                 FAIL_IF_EXIT_MSG(!(ctrl & PR_PPC_DEXCR_CTRL_SET_ONEXEC),
136                                  "setting aspect on exec not copied across fork");
137 
138                 FAIL_IF_EXIT_MSG(mfspr(SPRN_DEXCR_RO) & aspect,
139                                  "setting aspect on exec wrongly applied to fork");
140 
141                 execve("/proc/self/exe", args, NULL);
142                 _exit(errno);
143         }
144         await_child_success(pid);
145 
146         err = pr_set_dexcr(which, PR_PPC_DEXCR_CTRL_SET | PR_PPC_DEXCR_CTRL_CLEAR_ONEXEC);
147         FAIL_IF_MSG(err, "PR_PPC_DEXCR_CTRL_SET | PR_PPC_DEXCR_CTRL_CLEAR_ONEXEC failed");
148 
149         pid = fork();
150         if (!pid) {
151                 char which_str[32] = {};
152                 char *args[] = { "dexcr_prctl_onexec_test_child", which_str, "clear", NULL };
153                 unsigned int ctrl = pr_get_dexcr(which);
154 
155                 sprintf(which_str, "%lu", which);
156 
157                 FAIL_IF_EXIT_MSG(!(ctrl & PR_PPC_DEXCR_CTRL_CLEAR_ONEXEC),
158                                  "clearing aspect on exec not copied across fork");
159 
160                 FAIL_IF_EXIT_MSG(!(mfspr(SPRN_DEXCR_RO) & aspect),
161                                  "clearing aspect on exec wrongly applied to fork");
162 
163                 execve("/proc/self/exe", args, NULL);
164                 _exit(errno);
165         }
166         await_child_success(pid);
167 
168         return 0;
169 }
170 
171 static int dexcr_prctl_ibrtpd_test(void)
172 {
173         return dexcr_prctl_aspect_test(PR_PPC_DEXCR_IBRTPD);
174 }
175 
176 static int dexcr_prctl_srapd_test(void)
177 {
178         return dexcr_prctl_aspect_test(PR_PPC_DEXCR_SRAPD);
179 }
180 
181 static int dexcr_prctl_nphie_test(void)
182 {
183         return dexcr_prctl_aspect_test(PR_PPC_DEXCR_NPHIE);
184 }
185 
186 int main(int argc, char *argv[])
187 {
188         int err = 0;
189 
190         /*
191          * Some tests require checking what happens across exec, so we may be
192          * invoked as the child of a particular test
193          */
194         if (argc > 1) {
195                 if (argc == 3 && !strcmp(argv[0], "dexcr_prctl_onexec_test_child")) {
196                         unsigned long which;
197 
198                         err = parse_ulong(argv[1], strlen(argv[1]), &which, 10);
199                         FAIL_IF_MSG(err, "failed to parse which value for child");
200 
201                         return dexcr_prctl_onexec_test_child(which, argv[2]);
202                 }
203 
204                 FAIL_IF_MSG(true, "unknown test case");
205         }
206 
207         /*
208          * Otherwise we are the main test invocation and run the full suite
209          */
210         err |= test_harness(dexcr_prctl_ibrtpd_test, "dexcr_prctl_ibrtpd");
211         err |= test_harness(dexcr_prctl_srapd_test, "dexcr_prctl_srapd");
212         err |= test_harness(dexcr_prctl_nphie_test, "dexcr_prctl_nphie");
213 
214         return err;
215 }
216 

~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

kernel.org | git.kernel.org | LWN.net | Project Home | SVN repository | Mail admin

Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.

sflogo.php