Page MenuHomeFreeBSD

Fix PSL_T inheritance on exec for x86.
ClosedPublic

Authored by kib on Apr 6 2018, 10:20 PM.
Tags
None
Referenced Files
Unknown Object (File)
Mar 20 2024, 9:39 AM
Unknown Object (File)
Dec 20 2023, 12:58 AM
Unknown Object (File)
Dec 13 2023, 12:08 AM
Unknown Object (File)
Dec 4 2023, 5:52 AM
Unknown Object (File)
Nov 24 2023, 6:41 PM
Unknown Object (File)
Nov 22 2023, 9:40 PM
Unknown Object (File)
Nov 19 2023, 9:50 PM
Unknown Object (File)
Nov 11 2023, 10:34 AM
Subscribers

Diff Detail

Repository
rS FreeBSD src repository - subversion
Lint
Lint Not Applicable
Unit
Tests Not Applicable

Event Timeline

If nobody has used this in 23 years and it's not present in other platforms do we need this?

So this doesn't get lost this is the original change in SVN. It dates back before FreeBSD 2.0

https://svnweb.freebsd.org/base/head/sys/i386/i386/machdep.c?r1=4193&r2=4201

If nobody has used this in 23 years and it's not present in other platforms do we need this?

Well, preserving the trace flag is IMO reasonable behavior.

I believe the history of the PSL_T on exec is more involved because bzero() seems to disappeared after the commit you mentioned.

Probably you should fix or remove the dead code in the linux compat layer as well.

sys/amd64/linux/linux_sysvec.c Line 412
sys/amd64/linux32/linux32_sysvec.c Line 761

It seems like all this was originally to support exect() and isn't needed since it's never worked past FreeBSD 2.0.

So this doesn't get lost this is the original change in SVN. It dates back before FreeBSD 2.0

https://svnweb.freebsd.org/base/head/sys/i386/i386/machdep.c?r1=4193&r2=4201

I find that hard to believe, given that the cvs versions before 2.0 do not exist in svn, or ncvs, and should only exist in an offline repository called cvs.

So this doesn't get lost this is the original change in SVN. It dates back before FreeBSD 2.0

https://svnweb.freebsd.org/base/head/sys/i386/i386/machdep.c?r1=4193&r2=4201

I find that hard to believe, given that the cvs versions before 2.0 do not exist in svn, or ncvs, and should only exist in an offline repository called cvs.

Well the SVN revisions might be bogus because of the transition from CVS. But I'm assuming the dates and the snapshots of the releases are correct.

r4201 is where the bzero() was introduced to setregs() on Nov. 6, 1994
r4762 is the creation of RELEASE_2_0 on Nov. 22, 1994

https://svnweb.freebsd.org/base/release/2.0/sys/i386/i386/machdep.c?revision=4762&view=markup#l865

In any case the changes look good. Just do something about the Linux compat files I listed as well.

This revision is now accepted and ready to land.Apr 7 2018, 2:33 AM

So this doesn't get lost this is the original change in SVN. It dates back before FreeBSD 2.0

https://svnweb.freebsd.org/base/head/sys/i386/i386/machdep.c?r1=4193&r2=4201

I find that hard to believe, given that the cvs versions before 2.0 do not exist in svn, or ncvs, and should only exist in an offline repository called cvs.

Well the SVN revisions might be bogus because of the transition from CVS. But I'm assuming the dates and the snapshots of the releases are correct.

r4201 is where the bzero() was introduced to setregs() on Nov. 6, 1994
r4762 is the creation of RELEASE_2_0 on Nov. 22, 1994

https://svnweb.freebsd.org/base/release/2.0/sys/i386/i386/machdep.c?revision=4762&view=markup#l865

Yea, that is an "artifact" of cvs2svn, the actual svn version of the file shipped is 4221. You can see that if you use the Select for diff on version 4762 the diff to 4221 is null.
Either way if this bug has existed since then it clearly indicates this code is dead.

The reason I harped on the "Before 2.0" is that technically all 1.x code is to be unpublished by Agreement with AT&T/USL.
The time frame you are looking at here is 2.0, very near its actual release.

The reason I harped on the "Before 2.0" is that technically all 1.x code is to be unpublished by Agreement with AT&T/USL.
The time frame you are looking at here is 2.0, very near its actual release.

Yet, it's widely available. For example, you can find it at https://github.com/dspinellis/unix-history-repo/tree/FreeBSD-release/1.0-Import as well as all the pre-history of FreeBSD in the 386BSD + patchkit era. We're long past the time where it really matters for everybody that wasn't a direct party to that agreement, since there's no legal entity that could make an agreement on my behalf, since I wasn't even part of the project at the time, and the agreement was secret for years.

In D14995#315621, @imp wrote:

The reason I harped on the "Before 2.0" is that technically all 1.x code is to be unpublished by Agreement with AT&T/USL.
The time frame you are looking at here is 2.0, very near its actual release.

Yet, it's widely available. For example, you can find it at https://github.com/dspinellis/unix-history-repo/tree/FreeBSD-release/1.0-Import as well as all the pre-history of FreeBSD in the 386BSD + patchkit era. We're long past the time where it really matters for everybody that wasn't a direct party to that agreement, since there's no legal entity that could make an agreement on my behalf, since I wasn't even part of the project at the time, and the agreement was secret for years.

You can find a single points in time, namely the src's from the releases, that is not the cvs files. I am a party to the agreement, the agreement is still secret, though the UCB version is public. And as far as I know the "project" and Walnut Creeks hiers are still bound by that agreement.

Touch linuxolator on amd64.

This revision now requires review to proceed.Apr 7 2018, 9:37 AM

After reviewing this stuff once more, I think that PSL_T inheritance should be done for a reason different than exect(3). Assume that the process was set for single-step with ptrace(PT_SETSTEP). Then, execve(2) must not clear the command.

We currently provide the exec stop event for execve(2) to debuggers, which is why debuggers typically work. But if you single-step a program and step into a syscall, then exec knocks off debugger despite reporting exec event.

Then this raises the question: should setuid/setgid binary execution inherit PSL_T ? We do not change credentials if the process is traced. Also, we reset signal handlers disposition on exec. So for setuid process, the result of inheritance is un-caught SIGTRAP.

I noticed PSL_T flag is masked out in the trap and system call entry path. It only gets set again by ptrace(PT_STEP, ...). This appears to be intentional because of the way ptrace() is being used.

The result is that the kernel doesn't preserve the trap flag if a user space application sets it. In the example below, the program receives only one signal. It is possible set the trap flag in the signal handler to keep receiving signals (tested it works).

This doesn't appear to be the behavior on other platforms but I didn't run it on my other architectures yet. I did test OS X which also doesn't clear the flag,, but then again it doesn't preserve PSL_T across execve().

This seems to have implications to this patch. Maybe there's a bigger discussion on the expected behavior around ptrace, PSL_T, and user space tracing itself.

https://svnweb.freebsd.org/base/head/sys/amd64/amd64/trap.c?revision=331650&view=markup#l925
sys/amd64/trap.c:
See Line 279 trap() & Line 942 amd64_syscall()

Example

static void
sigtrap_handler(int sig, siginfo_t *info, void *ctx)
{
	assert(sig == SIGTRAP);
	assert(info->si_code == TRAP_TRACE);

	++caught;
}

int main(int argc, const char *argv[])
{
	struct sigaction act;

	assert(sigemptyset(&act.sa_mask) == 0);
	act.sa_sigaction = sigtrap_handler;
	act.sa_flags = SA_SIGINFO;

	assert(sigaction(SIGTRAP, &act, 0) == 0);

	printf("expected caught (1), received (%d)\n", caught);

	settrace(); /* sets PSL_T */
	for (int i = 0; i < 5; i++) {
	    printf("Hello\n");
	}

	printf("expected caught (1), received (%d)\n", caught);
}

Output:

expected caught (1), received (0)
Hello
Hello
Hello
Hello
Hello
expected caught (1), received (1)
This revision was not accepted when it landed; it landed in state Needs Review.Apr 12 2018, 8:44 PM
This revision was automatically updated to reflect the committed changes.