Commit c7ca0b61 authored by Andy Lutomirski's avatar Andy Lutomirski Committed by Thomas Gleixner
Browse files

Revert "x86/ptrace: Prevent ptrace from clearing the FS/GS selector" and fix the test



This reverts commit 48f5e52e.

The ptrace ABI change was a prerequisite to the proposed design for
FSGSBASE.  Since FSGSBASE support has been reverted, and since I'm not
convinced that the ABI was ever adequately tested, revert the ABI change as
well.

This also modifies the test case so that it tests the preexisting behavior.

Signed-off-by: default avatarAndy Lutomirski <luto@kernel.org>
Signed-off-by: default avatarThomas Gleixner <tglx@linutronix.de>
Link: https://lkml.kernel.org/r/fca39c478ea7fb15bc76fe8a36bd180810a067f6.1563200250.git.luto@kernel.org
parent fec88ab0
Loading
Loading
Loading
Loading
+12 −2
Original line number Diff line number Diff line
@@ -369,12 +369,22 @@ static int putreg(struct task_struct *child,
	case offsetof(struct user_regs_struct,fs_base):
		if (value >= TASK_SIZE_MAX)
			return -EIO;
		x86_fsbase_write_task(child, value);
		/*
		 * When changing the FS base, use do_arch_prctl_64()
		 * to set the index to zero and to set the base
		 * as requested.
		 */
		if (child->thread.fsbase != value)
			return do_arch_prctl_64(child, ARCH_SET_FS, value);
		return 0;
	case offsetof(struct user_regs_struct,gs_base):
		/*
		 * Exactly the same here as the %fs handling above.
		 */
		if (value >= TASK_SIZE_MAX)
			return -EIO;
		x86_gsbase_write_task(child, value);
		if (child->thread.gsbase != value)
			return do_arch_prctl_64(child, ARCH_SET_GS, value);
		return 0;
#endif
	}
+4 −18
Original line number Diff line number Diff line
@@ -489,25 +489,11 @@ static void test_ptrace_write_gsbase(void)
		 * selector value is changed or not by the GSBASE write in
		 * a ptracer.
		 */
		if (gs != *shared_scratch) {
			nerrs++;
			printf("[FAIL]\tGS changed to %lx\n", gs);

			/*
			 * On older kernels, poking a nonzero value into the
			 * base would zero the selector.  On newer kernels,
			 * this behavior has changed -- poking the base
			 * changes only the base and, if FSGSBASE is not
			 * available, this may have no effect.
			 */
			if (gs == 0)
				printf("\tNote: this is expected behavior on older kernels.\n");
		} else if (have_fsgsbase && (base != 0xFF)) {
			nerrs++;
			printf("[FAIL]\tGSBASE changed to %lx\n", base);
		if (gs == 0 && base == 0xFF) {
			printf("[OK]\tGS was reset as expected\n");
		} else {
			printf("[OK]\tGS remained 0x%hx%s", *shared_scratch, have_fsgsbase ? " and GSBASE changed to 0xFF" : "");
			printf("\n");
			nerrs++;
			printf("[FAIL]\tGS=0x%lx, GSBASE=0x%lx (should be 0, 0xFF)\n", gs, base);
		}
	}