Ejemplo n.º 1
0
 def callafter(self, pid, call, result, state):
     if call == 'rt_sigaction' or call == 'sigaction' or call == 'signal':
         if state != None and not (-1024 < result < 0):
             sig = state[0]
             f = self.allflags[pid]
             handler = state[1]
             if sig == signal.SIGCHLD:
                 sa_flags = ptrace.peekdata(pid, handler + 4)
                 f['SA_NOCLDSTOP'] = sa_flags & 0x1 # SA_NOCLDSTOP
             else:
                 if call != 'signal':
                     handler = ptrace.peekdata(pid, handler)
                 f[signalmap.lookup_name(sig)] = handler
     elif call == 'wait4' or call == 'waitpid':
         f = self.allflags[pid]
         if f.has_key('waitresult'):
             wpid, statusptr, status = f['waitresult']
             del f['waitresult']
             del f['waiting']
             if statusptr != 0:
                 try:
                     ptrace.pokedata(pid, statusptr, status)
                 except OSError, e:
                     if e.errno != errno.ESRCH:
                         # FIX
                         assert 0, "wait status pointer bad? (%s)" % e
                     else:
                         print 'waiter dead or not stopped' # XXX
             return wpid
         # XXX: is this actually correct and useful?
         if result == -errno_internal.ERESTARTNOHAND: # like pause
             return -errno_internal.ERESTARTSYS # like wait
Ejemplo n.º 2
0
    def callbefore(self, pid, call, args):
        # delay read/write calls here according to bandwidth limit
        # track network fds (including across fork/vfork/clone)

        if not self.fds.has_key(pid):
            self.fds[pid] = {}

        if call == 'socketcall':
            subcall = args[0]
            if subcall == 1:  # socket
                # FIX: might fail
                if ptrace.peekdata(pid, args[1]) == socket.AF_INET:
                    return (('fd', ), None, None, None)
            elif subcall == 5:  # accept
                return (('fd', ), None, None, None)
        elif call == 'dup' or call == 'dup2':
            return (('dup', args[0]), None, None, None)
        elif call == 'close':
            return (('close', args[0]), None, None, None)
        elif call == 'open':
            # if open works, we missed prior close (on fork/exec?)
            return (('open', ), None, None, None)
        elif call == 'fork' or call == 'vfork' or call == 'clone':
            return (('fork', pid), None, None, None)

        elif call == 'read' or call == 'write':
            if self.fds[pid].has_key(args[0]):
                #print 'io: [%s] %s on %s of %s bytes' % (pid, call, args[0], args[2])
                return (('netio', ), None, None, None)
Ejemplo n.º 3
0
    def callbefore(self, pid, call, args):
	# delay read/write calls here according to bandwidth limit
	# track network fds (including across fork/vfork/clone)

        if not self.fds.has_key(pid):
            self.fds[pid] = {}

        if call == 'socketcall':
            subcall = args[0]
            if subcall == 1:            # socket
                # FIX: might fail
                if ptrace.peekdata(pid, args[1]) == socket.AF_INET:
                    return (('fd',), None, None, None)
            elif subcall == 5:          # accept
                return (('fd',), None, None, None)
        elif call == 'dup' or call == 'dup2':
            return (('dup', args[0]), None, None, None)
        elif call == 'close':
            return (('close', args[0]), None, None, None)
        elif call == 'open':
            # if open works, we missed prior close (on fork/exec?)
            return (('open',), None, None, None)
        elif call == 'fork' or call == 'vfork' or call == 'clone':
            return (('fork', pid), None, None, None)

        elif call == 'read' or call == 'write':
            if self.fds[pid].has_key(args[0]):
                #print 'io: [%s] %s on %s of %s bytes' % (pid, call, args[0], args[2])
                return (('netio',), None, None, None)
Ejemplo n.º 4
0
    def callbefore(self, pid, call, args):
        #		print pid, call, args
        def doreadwrite(callt, args):
            #			print 'doreadwrite',call,callt,args,
            fd = args[0]
            pfd = pid, fd
            fdinfo = self.__do_fail.get(pfd, None)
            #			if fdinfo:
            #				print fdinfo
            if fdinfo and callt in fdinfo.modes:
                if callt == 'r':
                    #after = self.afterr
                    if not fdinfo.rerrs:
                        return
                    after = min([err.after for err in fdinfo.rerrs])
                    failinfo = fdinfo.r
                else:
                    #after = self.afterw
                    if not fdinfo.werrs:
                        return
                    after = min([err.after for err in fdinfo.werrs])
                    failinfo = fdinfo.w
                failcount, bytes = failinfo.failed, failinfo.bytes

                if failcount > 5:
                    print 'exiting on %ith failed %s of %i' % (failcount,
                                                               callt, pfd)
                    import sys
                    sys.exit(1)

                if bytes < after:
                    size = args[2]
                    if bytes + size > after:
                        size = after - bytes
                    print pfd, callt, (fd, args[1], size), 'was', args
                    return (pfd, None, None, (fd, args[1], size))

                failinfo.failed += 1
                print pid, 'failing', call, callt, '#%i' % failcount, 'for fd', fd
                return (pfd, -errno.EIO, None, None)
#			else:
#				print 'allowing',call,'for',args[0]

        if call == 'read':
            return doreadwrite('r', args)
        elif call == 'write':
            return doreadwrite('w', args)
        elif call == 'close':
            fd = args[0]
            pfd = pid, fd
            fdinfo = self.__do_fail.get(pfd, None)
            #			print pfd, call, args, fdinfo
            if fdinfo and fdinfo.cerrs:
                return (pfd, -errno.EIO, None, None)
            return (pfd, None, None, None)

        elif call == 'dup' or call == 'dup2':
            return (args[0], None, None, None)
        elif call == 'open':
            getarg = Memory.getMemory(pid).get_string
            fn = getarg(args[0])
            #			print pid,call,[fn]+args[1:],args[1]&O_ACCMODE
            fes = []
            m = ''
            flags = args[1] & O_ACCMODE
            for fe in self.ferrs:
                if (flags == os.O_RDWR
                        or (flags == os.O_WRONLY and 'w' in fe.modes)
                        or (flags == os.O_RDONLY and 'r' in fe.modes)):
                    if fe.match.search(fn):
                        fes.append(fe)
            if fes:
                fdinfo = FDInfo(fes)
                #if flags == FCNTL.O_WRONLY:
                #	after = min([err.after for err in fdinfo.werrs])
                #elif flags == FCNTL.O_RDONLY:
                #	after = min([err.after for err in fdinfo.rerrs])
                #else: #elif flags == FCNTL.O_RDWR:
                after = min([err.after for err in fdinfo.errs])
                if after < 0:
                    print pid, 'failing', call, [fn] + args[1:]
                    return (None, -errno.EIO, None, None)
                return (fdinfo, None, None, None)

        elif call == 'socketcall':
            #			print pid, call, args
            subcall = args[0]
            do = 0
            if subcall == 1:  # socket
                # FIX: might fail
                if ptrace.peekdata(pid, args[1]) in (socket.AF_INET,
                                                     socket.AF_INET6):
                    do = -2
            elif subcall == 3:  # connect
                do = -1
            elif subcall == 4:  # listen
                do = -1
            elif subcall == 5:  # accept
                do = -1
            elif subcall in (9, 10):  # send/recv
                if subcall == 9:  # send
                    r = doreadwrite('w', (ptrace.peekdata(
                        pid, args[1]), ptrace.peekdata(pid, args[1] + 4),
                                          ptrace.peekdata(pid, args[1] + 8)))
                    subcalln = 'write'
                elif subcall == 10:  # recv
                    r = doreadwrite('r', (ptrace.peekdata(
                        pid, args[1]), ptrace.peekdata(pid, args[1] + 4),
                                          ptrace.peekdata(pid, args[1] + 8)))
                    subcalln = 'read'
                if not r or r[
                        1]:  # if default return or error, we can return it with no probs.
                    return r
                #otherwise we have to convert from doreadwrite return which is in read()/write() format to socketcall format
                ptrace.pokedata(args[1] + 8,
                                r[3][2])  # set new recv/write size
                return ((subcalln, r[0]), r[1], r[2], args)

            if do:
                #ses = []
                #for se in self.serrs:
                after = min([err.after for err in self.serrs])
                if after == do:
                    print pid, 'failing', call, args
                    return (None, -errno.EIO, None, None)
                errs = [err for err in self.serrs if err.after >= 0]
                if errs:
                    fdinfo = FDInfo(errs)
                    return (('open', fdinfo), None, None, None)

        elif call == 'rename':
            getarg = Memory.getMemory(pid).get_string
            sfn = getarg(args[0])
            dfn = getarg(args[1])
            #			print pid,call,sfn,dfn
            for rene in self.renameerrs:
                if rene.srcmatch.search(sfn) and rene.dstmatch.search(dfn):
                    print pid, 'failing', call, sfn, dfn
                    return (None, -errno.EIO, None, None)
Ejemplo n.º 5
0
def _get_timeval_2(pid, addr):
    sec = ptrace.peekdata(pid, addr)
    usec = ptrace.peekdata(pid, addr + 4)
    return (sec, usec)
Ejemplo n.º 6
0
    def _readbyte(self, address):
        """Read one byte (ptrace allows us to read words, only).  This needs
	to be changed for non-i386."""
        word = ptrace.peekdata(self.pid, address & ~3)
        return (word >> ((address & 3) * 8)) & 0xFF
Ejemplo n.º 7
0
def _get_timeval_2(pid, addr):
    sec = ptrace.peekdata(pid, addr)
    usec = ptrace.peekdata(pid, addr + 4)
    return (sec, usec)
Ejemplo n.º 8
0
    def _readbyte(self, address):
	"""Read one byte (ptrace allows us to read words, only).  This needs
	to be changed for non-i386."""
	word = ptrace.peekdata(self.pid, address & ~3)
        return (word >> ((address & 3)*8)) & 0xff