🚀 go-pugleaf

RetroBBS NetNews Server

Inspired by RockSolid Light RIP Retro Guy

Article View: comp.sys.sun
Article #12289

just what is PTRACE_POKEUSER good for, anyway?

#12289
From: Benson I. Margulies
Date: Wed, 26 Apr 1989 07:29
129 lines
4595 bytes
The documentation for ptrace in 4.0 says that PTRACE_POKEUSER can be used
to poke the general registers, floating point status, and some psw bits.
However, the enclosed program(s) demonstrates that the only pokable
locations in user proper are high addresses in the kernel stack area, just
below the PCB. This certainly seems wrong, as u_pcb would appear to be a
much more reasonable field of addresses for poking.

If this is a bug, it is a serious security bug, since the kernel is
probably spoofable by sticking junk into a ptrace child's kernel stack.

In any case the documentation for ptrace isn't really good enough, as it
fails to give enough information to make POKEUSER useful. In particular,
if only some fields of the psw are changable, which ones are they?

Benson I. Margulies, Object Design. Sun 3/60 serial 912F0077, under
contract. 1 NE Executive Park, Burlington, MA 01802.  617-270-9797.
odi!benson@talcott.harvard.edu.

#include <sys/types.h>
#include <stdio.h>
#include <sys/ptrace.h>
#include <sys/wait.h>
#include <sys/param.h>
#include <sys/dir.h>
#include <sys/user.h>
#include <signal.h>

extern int errno;

/* Survey PTRACE_POKEUSER */

main ()
{
    int cpid;
    int uoffset;

    switch(cpid = fork ())
    {
      case 0: /* child */
	be_childish ();
	break;
      case -1: /* error */
	perror("ptrace_poke_survey");
	exit(1);
    }

   /* The parent */

    /* wait for child to send itself signal */
    wait((union wait *) 0);

    /* now start the fun */

    for(uoffset = 0; uoffset < sizeof(struct user);uoffset += sizeof(int)) {
	errno = 0;
	ptrace(PTRACE_POKEUSER, cpid, (char *)uoffset, 0, 0);
	if(errno == 0) printf("Offset %4d\n", uoffset);
    }

    ptrace(PTRACE_KILL, cpid, 0, 0, 0);
    exit(0);
}

be_childish ()
{
    ptrace(PTRACE_TRACEME, 0, 0, 0, 0);
    kill(getpid(), SIGINT);
}

#include <sys/types.h>
#include <stdio.h>
#include <sys/ptrace.h>
#include <sys/wait.h>
#include <sys/param.h>
#include <sys/dir.h>
#include <sys/user.h>
#include <signal.h>

main()
{
    struct user u;

#define UO(n) ((char *)&u.n - (char *)&u)

    printf("u_stack:\t%d\n", UO(u_stack));
    printf("u_pcb:\t%d\n", UO(u_pcb));
    printf("u_procp:\t%d\n", UO(u_procp));
    printf("u_ar0:\t%d\n", UO(u_ar0));
    printf("u_comm:\t%d\n", UO(u_comm));
    printf("u_arg:\t%d\n", UO(u_arg));
    printf("u_ap:\t%d\n", UO(u_ap));
    printf("u_qsave:\t%d\n", UO(u_qsave));
    printf("u_r:\t%d\n", UO(u_r));
    printf("u_error:\t%d\n", UO(u_error));
    printf("u_eosys:\t%d\n", UO(u_eosys));
    printf("u_ssave:\t%d\n", UO(u_ssave));
    printf("u_signal:\t%d\n", UO(u_signal));
    printf("u_sigmask:\t%d\n", UO(u_sigmask));
    printf("u_sigonstack:\t%d\n", UO(u_sigonstack));
    printf("u_sigintr:\t%d\n", UO(u_sigintr));
    printf("u_sigreset:\t%d\n", UO(u_sigreset));
    printf("u_oldmask:\t%d\n", UO(u_oldmask));
    printf("u_code:\t%d\n", UO(u_code));
    printf("u_addr:\t%d\n", UO(u_addr));
    printf("u_sigstack:\t%d\n", UO(u_sigstack));
    printf("u_ofileX:\t%d\n", UO(u_ofileX));
    printf("u_pofileX:\t%d\n", UO(u_pofileX));
    printf("u_ofile:\t%d\n", UO(u_ofile));
    printf("u_pofile:\t%d\n", UO(u_pofile));
    printf("u_lastfile:\t%d\n", UO(u_lastfile));
    printf("u_cwd:\t%d\n", UO(u_cwd));
    printf("u_cdir:\t%d\n", UO(u_cdir));
    printf("u_rdir:\t%d\n", UO(u_rdir));
    printf("u_ttyp:\t%d\n", UO(u_ttyp));
    printf("u_ttyd:\t%d\n", UO(u_ttyd));
    printf("u_ttyvp:\t%d\n", UO(u_ttyvp));
    printf("u_cmask:\t%d\n", UO(u_cmask));
    printf("u_ru:\t%d\n", UO(u_ru));
    printf("u_cru:\t%d\n", UO(u_cru));
    printf("u_timer:\t%d\n", UO(u_timer));
    printf("u_XXX:\t%d\n", UO(u_XXX));
    printf("u_start:\t%d\n", UO(u_start));
    printf("u_acflag:\t%d\n", UO(u_acflag));
    printf("u_prof:\t%d\n", UO(u_prof));
    printf("u_rlimit:\t%d\n", UO(u_rlimit));
    printf("u_exdata:\t%d\n", UO(u_exdata));
    printf("u_lofault:\t%d\n", UO(u_lofault));
    exit(0);
}
Technical Details
Message-ID: <8904121236.AA08203@odi.com>
Path: arc1-ca.pugleaf.net!utzoo!utgpu!jarvis.csri.toronto.edu!mailrus!cornell!uw-beaver!rice!sun-spots-request

Show Full Headers
Complete Article Headers
Path: arc1-ca.pugleaf.net!utzoo!utgpu!jarvis.csri.toronto.edu!mailrus!cornell!uw-beaver!rice!sun-spots-request
From: odi!benson@talcott.harvard.edu (Benson I. Margulies)
Newsgroups: comp.sys.sun
Subject: just what is PTRACE_POKEUSER good for, anyway?
Keywords: SunOS
Message-ID: <8904121236.AA08203@odi.com>
Date: 26 Apr 89 07:29:28 GMT
Sender: usenet@rice.edu
Organization: Sun-Spots
Lines: 129
Approved: Sun-Spots@rice.edu
Original-Date: Wed, 12 Apr 89 08:36:57 EDT
X-Sun-Spots-Digest: Volume 7, Issue 254, message 9 of 12