Linux Audio

Check our new training course

Loading...
v6.2
  1// SPDX-License-Identifier: GPL-2.0
  2#include <linux/compiler.h>
  3#include <sys/types.h>
  4#include <sys/wait.h>
  5#include <sys/user.h>
  6#include <syscall.h>
  7#include <unistd.h>
  8#include <stdio.h>
  9#include <stdlib.h>
 10#include <string.h>
 11#include <sys/ptrace.h>
 12#include <asm/ptrace.h>
 13#include <errno.h>
 14#include "debug.h"
 15#include "tests/tests.h"
 16#include "arch-tests.h"
 17
 18static noinline int bp_1(void)
 19{
 20	pr_debug("in %s\n", __func__);
 21	return 0;
 22}
 23
 24static noinline int bp_2(void)
 25{
 26	pr_debug("in %s\n", __func__);
 27	return 0;
 28}
 29
 30static int spawn_child(void)
 31{
 32	int child = fork();
 33
 34	if (child == 0) {
 35		/*
 36		 * The child sets itself for as tracee and
 37		 * waits in signal for parent to trace it,
 38		 * then it calls bp_1 and quits.
 39		 */
 40		int err = ptrace(PTRACE_TRACEME, 0, NULL, NULL);
 41
 42		if (err) {
 43			pr_debug("failed to PTRACE_TRACEME\n");
 44			exit(1);
 45		}
 46
 47		raise(SIGCONT);
 48		bp_1();
 49		exit(0);
 50	}
 51
 52	return child;
 53}
 54
 55/*
 56 * This tests creates HW breakpoint, tries to
 57 * change it and checks it was properly changed.
 58 */
 59static int bp_modify1(void)
 60{
 61	pid_t child;
 62	int status;
 63	unsigned long rip = 0, dr7 = 1;
 64
 65	child = spawn_child();
 66
 67	waitpid(child, &status, 0);
 68	if (WIFEXITED(status)) {
 69		pr_debug("tracee exited prematurely 1\n");
 70		return TEST_FAIL;
 71	}
 72
 73	/*
 74	 * The parent does following steps:
 75	 *  - creates a new breakpoint (id 0) for bp_2 function
 76	 *  - changes that breakpoint to bp_1 function
 77	 *  - waits for the breakpoint to hit and checks
 78	 *    it has proper rip of bp_1 function
 79	 *  - detaches the child
 80	 */
 81	if (ptrace(PTRACE_POKEUSER, child,
 82		   offsetof(struct user, u_debugreg[0]), bp_2)) {
 83		pr_debug("failed to set breakpoint, 1st time: %s\n",
 84			 strerror(errno));
 85		goto out;
 86	}
 87
 88	if (ptrace(PTRACE_POKEUSER, child,
 89		   offsetof(struct user, u_debugreg[0]), bp_1)) {
 90		pr_debug("failed to set breakpoint, 2nd time: %s\n",
 91			 strerror(errno));
 92		goto out;
 93	}
 94
 95	if (ptrace(PTRACE_POKEUSER, child,
 96		   offsetof(struct user, u_debugreg[7]), dr7)) {
 97		pr_debug("failed to set dr7: %s\n", strerror(errno));
 98		goto out;
 99	}
100
101	if (ptrace(PTRACE_CONT, child, NULL, NULL)) {
102		pr_debug("failed to PTRACE_CONT: %s\n", strerror(errno));
103		goto out;
104	}
105
106	waitpid(child, &status, 0);
107	if (WIFEXITED(status)) {
108		pr_debug("tracee exited prematurely 2\n");
109		return TEST_FAIL;
110	}
111
112	rip = ptrace(PTRACE_PEEKUSER, child,
113		     offsetof(struct user_regs_struct, rip), NULL);
114	if (rip == (unsigned long) -1) {
115		pr_debug("failed to PTRACE_PEEKUSER: %s\n",
116			 strerror(errno));
117		goto out;
118	}
119
120	pr_debug("rip %lx, bp_1 %p\n", rip, bp_1);
121
122out:
123	if (ptrace(PTRACE_DETACH, child, NULL, NULL)) {
124		pr_debug("failed to PTRACE_DETACH: %s", strerror(errno));
125		return TEST_FAIL;
126	}
127
128	return rip == (unsigned long) bp_1 ? TEST_OK : TEST_FAIL;
129}
130
131/*
132 * This tests creates HW breakpoint, tries to
133 * change it to bogus value and checks the original
134 * breakpoint is hit.
135 */
136static int bp_modify2(void)
137{
138	pid_t child;
139	int status;
140	unsigned long rip = 0, dr7 = 1;
141
142	child = spawn_child();
143
144	waitpid(child, &status, 0);
145	if (WIFEXITED(status)) {
146		pr_debug("tracee exited prematurely 1\n");
147		return TEST_FAIL;
148	}
149
150	/*
151	 * The parent does following steps:
152	 *  - creates a new breakpoint (id 0) for bp_1 function
153	 *  - tries to change that breakpoint to (-1) address
154	 *  - waits for the breakpoint to hit and checks
155	 *    it has proper rip of bp_1 function
156	 *  - detaches the child
157	 */
158	if (ptrace(PTRACE_POKEUSER, child,
159		   offsetof(struct user, u_debugreg[0]), bp_1)) {
160		pr_debug("failed to set breakpoint: %s\n",
161			 strerror(errno));
162		goto out;
163	}
164
165	if (ptrace(PTRACE_POKEUSER, child,
166		   offsetof(struct user, u_debugreg[7]), dr7)) {
167		pr_debug("failed to set dr7: %s\n", strerror(errno));
168		goto out;
169	}
170
171	if (!ptrace(PTRACE_POKEUSER, child,
172		   offsetof(struct user, u_debugreg[0]), (unsigned long) (-1))) {
173		pr_debug("failed, breakpoint set to bogus address\n");
174		goto out;
175	}
176
177	if (ptrace(PTRACE_CONT, child, NULL, NULL)) {
178		pr_debug("failed to PTRACE_CONT: %s\n", strerror(errno));
179		goto out;
180	}
181
182	waitpid(child, &status, 0);
183	if (WIFEXITED(status)) {
184		pr_debug("tracee exited prematurely 2\n");
185		return TEST_FAIL;
186	}
187
188	rip = ptrace(PTRACE_PEEKUSER, child,
189		     offsetof(struct user_regs_struct, rip), NULL);
190	if (rip == (unsigned long) -1) {
191		pr_debug("failed to PTRACE_PEEKUSER: %s\n",
192			 strerror(errno));
193		goto out;
194	}
195
196	pr_debug("rip %lx, bp_1 %p\n", rip, bp_1);
197
198out:
199	if (ptrace(PTRACE_DETACH, child, NULL, NULL)) {
200		pr_debug("failed to PTRACE_DETACH: %s", strerror(errno));
201		return TEST_FAIL;
202	}
203
204	return rip == (unsigned long) bp_1 ? TEST_OK : TEST_FAIL;
205}
206
207int test__bp_modify(struct test_suite *test __maybe_unused,
208		    int subtest __maybe_unused)
209{
210	TEST_ASSERT_VAL("modify test 1 failed\n", !bp_modify1());
211	TEST_ASSERT_VAL("modify test 2 failed\n", !bp_modify2());
212
213	return 0;
214}
v5.14.15
  1// SPDX-License-Identifier: GPL-2.0
  2#include <linux/compiler.h>
  3#include <sys/types.h>
  4#include <sys/wait.h>
  5#include <sys/user.h>
  6#include <syscall.h>
  7#include <unistd.h>
  8#include <stdio.h>
  9#include <stdlib.h>
 10#include <string.h>
 11#include <sys/ptrace.h>
 12#include <asm/ptrace.h>
 13#include <errno.h>
 14#include "debug.h"
 15#include "tests/tests.h"
 16#include "arch-tests.h"
 17
 18static noinline int bp_1(void)
 19{
 20	pr_debug("in %s\n", __func__);
 21	return 0;
 22}
 23
 24static noinline int bp_2(void)
 25{
 26	pr_debug("in %s\n", __func__);
 27	return 0;
 28}
 29
 30static int spawn_child(void)
 31{
 32	int child = fork();
 33
 34	if (child == 0) {
 35		/*
 36		 * The child sets itself for as tracee and
 37		 * waits in signal for parent to trace it,
 38		 * then it calls bp_1 and quits.
 39		 */
 40		int err = ptrace(PTRACE_TRACEME, 0, NULL, NULL);
 41
 42		if (err) {
 43			pr_debug("failed to PTRACE_TRACEME\n");
 44			exit(1);
 45		}
 46
 47		raise(SIGCONT);
 48		bp_1();
 49		exit(0);
 50	}
 51
 52	return child;
 53}
 54
 55/*
 56 * This tests creates HW breakpoint, tries to
 57 * change it and checks it was properly changed.
 58 */
 59static int bp_modify1(void)
 60{
 61	pid_t child;
 62	int status;
 63	unsigned long rip = 0, dr7 = 1;
 64
 65	child = spawn_child();
 66
 67	waitpid(child, &status, 0);
 68	if (WIFEXITED(status)) {
 69		pr_debug("tracee exited prematurely 1\n");
 70		return TEST_FAIL;
 71	}
 72
 73	/*
 74	 * The parent does following steps:
 75	 *  - creates a new breakpoint (id 0) for bp_2 function
 76	 *  - changes that breakpoint to bp_1 function
 77	 *  - waits for the breakpoint to hit and checks
 78	 *    it has proper rip of bp_1 function
 79	 *  - detaches the child
 80	 */
 81	if (ptrace(PTRACE_POKEUSER, child,
 82		   offsetof(struct user, u_debugreg[0]), bp_2)) {
 83		pr_debug("failed to set breakpoint, 1st time: %s\n",
 84			 strerror(errno));
 85		goto out;
 86	}
 87
 88	if (ptrace(PTRACE_POKEUSER, child,
 89		   offsetof(struct user, u_debugreg[0]), bp_1)) {
 90		pr_debug("failed to set breakpoint, 2nd time: %s\n",
 91			 strerror(errno));
 92		goto out;
 93	}
 94
 95	if (ptrace(PTRACE_POKEUSER, child,
 96		   offsetof(struct user, u_debugreg[7]), dr7)) {
 97		pr_debug("failed to set dr7: %s\n", strerror(errno));
 98		goto out;
 99	}
100
101	if (ptrace(PTRACE_CONT, child, NULL, NULL)) {
102		pr_debug("failed to PTRACE_CONT: %s\n", strerror(errno));
103		goto out;
104	}
105
106	waitpid(child, &status, 0);
107	if (WIFEXITED(status)) {
108		pr_debug("tracee exited prematurely 2\n");
109		return TEST_FAIL;
110	}
111
112	rip = ptrace(PTRACE_PEEKUSER, child,
113		     offsetof(struct user_regs_struct, rip), NULL);
114	if (rip == (unsigned long) -1) {
115		pr_debug("failed to PTRACE_PEEKUSER: %s\n",
116			 strerror(errno));
117		goto out;
118	}
119
120	pr_debug("rip %lx, bp_1 %p\n", rip, bp_1);
121
122out:
123	if (ptrace(PTRACE_DETACH, child, NULL, NULL)) {
124		pr_debug("failed to PTRACE_DETACH: %s", strerror(errno));
125		return TEST_FAIL;
126	}
127
128	return rip == (unsigned long) bp_1 ? TEST_OK : TEST_FAIL;
129}
130
131/*
132 * This tests creates HW breakpoint, tries to
133 * change it to bogus value and checks the original
134 * breakpoint is hit.
135 */
136static int bp_modify2(void)
137{
138	pid_t child;
139	int status;
140	unsigned long rip = 0, dr7 = 1;
141
142	child = spawn_child();
143
144	waitpid(child, &status, 0);
145	if (WIFEXITED(status)) {
146		pr_debug("tracee exited prematurely 1\n");
147		return TEST_FAIL;
148	}
149
150	/*
151	 * The parent does following steps:
152	 *  - creates a new breakpoint (id 0) for bp_1 function
153	 *  - tries to change that breakpoint to (-1) address
154	 *  - waits for the breakpoint to hit and checks
155	 *    it has proper rip of bp_1 function
156	 *  - detaches the child
157	 */
158	if (ptrace(PTRACE_POKEUSER, child,
159		   offsetof(struct user, u_debugreg[0]), bp_1)) {
160		pr_debug("failed to set breakpoint: %s\n",
161			 strerror(errno));
162		goto out;
163	}
164
165	if (ptrace(PTRACE_POKEUSER, child,
166		   offsetof(struct user, u_debugreg[7]), dr7)) {
167		pr_debug("failed to set dr7: %s\n", strerror(errno));
168		goto out;
169	}
170
171	if (!ptrace(PTRACE_POKEUSER, child,
172		   offsetof(struct user, u_debugreg[0]), (unsigned long) (-1))) {
173		pr_debug("failed, breakpoint set to bogus address\n");
174		goto out;
175	}
176
177	if (ptrace(PTRACE_CONT, child, NULL, NULL)) {
178		pr_debug("failed to PTRACE_CONT: %s\n", strerror(errno));
179		goto out;
180	}
181
182	waitpid(child, &status, 0);
183	if (WIFEXITED(status)) {
184		pr_debug("tracee exited prematurely 2\n");
185		return TEST_FAIL;
186	}
187
188	rip = ptrace(PTRACE_PEEKUSER, child,
189		     offsetof(struct user_regs_struct, rip), NULL);
190	if (rip == (unsigned long) -1) {
191		pr_debug("failed to PTRACE_PEEKUSER: %s\n",
192			 strerror(errno));
193		goto out;
194	}
195
196	pr_debug("rip %lx, bp_1 %p\n", rip, bp_1);
197
198out:
199	if (ptrace(PTRACE_DETACH, child, NULL, NULL)) {
200		pr_debug("failed to PTRACE_DETACH: %s", strerror(errno));
201		return TEST_FAIL;
202	}
203
204	return rip == (unsigned long) bp_1 ? TEST_OK : TEST_FAIL;
205}
206
207int test__bp_modify(struct test *test __maybe_unused,
208		    int subtest __maybe_unused)
209{
210	TEST_ASSERT_VAL("modify test 1 failed\n", !bp_modify1());
211	TEST_ASSERT_VAL("modify test 2 failed\n", !bp_modify2());
212
213	return 0;
214}