github.com/SagerNet/gvisor@v0.0.0-20210707092255-7731c139d75c/pkg/sentry/kernel/ptrace_amd64.go (about)

     1  // Copyright 2019 The gVisor Authors.
     2  //
     3  // Licensed under the Apache License, Version 2.0 (the "License");
     4  // you may not use this file except in compliance with the License.
     5  // You may obtain a copy of the License at
     6  //
     7  //     http://www.apache.org/licenses/LICENSE-2.0
     8  //
     9  // Unless required by applicable law or agreed to in writing, software
    10  // distributed under the License is distributed on an "AS IS" BASIS,
    11  // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    12  // See the License for the specific language governing permissions and
    13  // limitations under the License.
    14  
    15  // +build amd64
    16  
    17  package kernel
    18  
    19  import (
    20  	"github.com/SagerNet/gvisor/pkg/abi/linux"
    21  	"github.com/SagerNet/gvisor/pkg/hostarch"
    22  	"github.com/SagerNet/gvisor/pkg/syserror"
    23  	"github.com/SagerNet/gvisor/pkg/usermem"
    24  )
    25  
    26  // ptraceArch implements arch-specific ptrace commands.
    27  func (t *Task) ptraceArch(target *Task, req int64, addr, data hostarch.Addr) error {
    28  	switch req {
    29  	case linux.PTRACE_PEEKUSR: // aka PTRACE_PEEKUSER
    30  		n, err := target.Arch().PtracePeekUser(uintptr(addr))
    31  		if err != nil {
    32  			return err
    33  		}
    34  		_, err = n.CopyOut(t, data)
    35  		return err
    36  
    37  	case linux.PTRACE_POKEUSR: // aka PTRACE_POKEUSER
    38  		return target.Arch().PtracePokeUser(uintptr(addr), uintptr(data))
    39  
    40  	case linux.PTRACE_GETREGS:
    41  		// "Copy the tracee's general-purpose ... registers ... to the address
    42  		// data in the tracer. ... (addr is ignored.) Note that SPARC systems
    43  		// have the meaning of data and addr reversed ..."
    44  		_, err := target.Arch().PtraceGetRegs(&usermem.IOReadWriter{
    45  			Ctx:  t,
    46  			IO:   t.MemoryManager(),
    47  			Addr: data,
    48  			Opts: usermem.IOOpts{
    49  				AddressSpaceActive: true,
    50  			},
    51  		})
    52  		return err
    53  
    54  	case linux.PTRACE_GETFPREGS:
    55  		s := target.Arch().FloatingPointData()
    56  		_, err := target.Arch().FloatingPointData().PtraceGetFPRegs(&usermem.IOReadWriter{
    57  			Ctx:  t,
    58  			IO:   t.MemoryManager(),
    59  			Addr: data,
    60  			Opts: usermem.IOOpts{
    61  				AddressSpaceActive: true,
    62  			},
    63  		}, len(*s))
    64  		return err
    65  
    66  	case linux.PTRACE_SETREGS:
    67  		_, err := target.Arch().PtraceSetRegs(&usermem.IOReadWriter{
    68  			Ctx:  t,
    69  			IO:   t.MemoryManager(),
    70  			Addr: data,
    71  			Opts: usermem.IOOpts{
    72  				AddressSpaceActive: true,
    73  			},
    74  		})
    75  		return err
    76  
    77  	case linux.PTRACE_SETFPREGS:
    78  		s := target.Arch().FloatingPointData()
    79  		_, err := s.PtraceSetFPRegs(&usermem.IOReadWriter{
    80  			Ctx:  t,
    81  			IO:   t.MemoryManager(),
    82  			Addr: data,
    83  			Opts: usermem.IOOpts{
    84  				AddressSpaceActive: true,
    85  			},
    86  		}, len(*s))
    87  		return err
    88  
    89  	default:
    90  		return syserror.EIO
    91  	}
    92  }