Exemple #1
0
    def execve(self, pid):
        enter = self.arg

        dbg.infom("!", "#R<re-execute#>: %s" % str(enter))
        fn = enter.args["filename"].path
        argv = enter.args["argv"]
        envp = enter.args["envp"]

        [ret, root, pwd, fds] = self.ret.aux

        # set sequence number as execve()'s sid
        self.seq = enter.sid & ((1 << 48) - 1) + 1

        # XXX
        # - setup fds
        self.proc = rerun.Ptrace([fn] + argv[1:], envp, kutil.get(pwd),
                                 kutil.get(root) if root.ino != 2 else None,
                                 self.uids)

        # enter/exit should be execve() too
        (r, p) = self.proc.load(True, None)
        (r, p) = self.proc.load(False, None)

        assert r.usage & EXIT and r.nr == syscall.NR_execve

        # virtualize pid
        self.pids[pid] = r.pid
        dbg.rerun("vpid:%s -> pid:%s (active)" % (pid, r.pid))

        # enable rerun module
        self.state = "active"
Exemple #2
0
    def syscall_read(self, arg, ret):
        r = arg.data
        assert r.nr == syscall.NR_read

        fd = arg.data.args["fd"]
        inode = fd.inode
        dbg.syscallm("!", "#R<read#>: reading %s with %s" % (inode, r))

        # read & create mock object
        pn = kutil.get(inode)
        with open(pn, 'r') as f:
            f.seek(fd.offset)
            file_data = f.read(r.args["count"])

        sha = sha1(file_data)

        dbg.syscallm("!", "#R<read#>: sha1:%s (old:%s)" \
                % (hexdigest(sha), hexdigest(ret.origdata.args["buf"])))

        new_data = deepcopy(ret.origdata)
        new_data.args["buf"] = sha
        new_data.args["real_buf"] = file_data
        new_data.ret = len(file_data)

        return new_data
Exemple #3
0
    def syscall_open(self, arg, ret):
        r = arg.data
        assert r.nr == syscall.NR_open
        assert ((r.args["path"].inode is None)
                or (r.args["path"].inode == r.ret.inode))

        inode = r.ret.inode
        dbg.syscallm("!", "#R<open#>: %s" % (str(r)))
        if runopts.dryrun:
            return ret.origdata

        pn = r.args['path'].path  # pathname to file

        # if not absolute pathname, retrieve with iget
        if not pn.startswith('/'):
            dentry = r.args['path'].entries[0]
            assert type(dentry) == sysarg.dentry
            pn = os.path.join("%s/%s" %
                              (kutil.get(dentry.parent), dentry.name))

        # flag == os.O_CREAT and only the case we really created an empty file
        if (r.args["path"].inode is None):
            src_pn = os.path.join(kutil.fsget(inode.dev), ".inodes",
                                  str(inode.ino))
            # to keep the inode
            os.rename(src_pn, pn)
            # make it empty when newly created
            with open(pn, "w") as f:
                pass
            dbg.syscallm("!", "#R<rename#>: %s -> %s" % (src_pn, pn))

        # if explicit truncate request
        if (r.args['flags'] & os.O_TRUNC):
            with open(pn, "w") as f:
                pass

        # If the syscall opened a _different_ inode than the file
        # points to now.
        path = r.args['path']
        arg_name = path.path
        dir_dev = path.entries[0].parent.dev
        dir_ino = path.entries[0].parent.ino

        dirent = fsmgr.DirentDataNode.get(dir_dev, dir_ino, arg_name)
        (cur_dev, cur_ino) = dirent.get_file_dev_ino()
        ret.data = deepcopy(ret.origdata)
        ret.data.ret.inode.ino, ret.data.ret.inode.dev = (cur_ino, cur_dev)

        return ret.data
Exemple #4
0
    def syscall_write(self, arg, ret):
        r = arg.data
        assert r.nr == syscall.NR_write

        dbg.syscallm(
            "!", "#R<write#>: %d with %s" % (r.args["fd"].inode.ino, str(r)))
        if runopts.dryrun:
            return ret.origdata

        fd = r.args["fd"]

        # XXX pts
        if not fd.inode.prefix in ["file"]:
            print "-" * 60
            print r.args["buf"]
            print "-" * 60
            return ret.origdata

        # regular write on files
        cur_pn = kutil.get(fd.inode)
        offset = fd.offset

        f = open(cur_pn, "r+")
        # append
        if offset == -1:
            f.seek(0, os.SEEK_END)
        else:
            f.seek(offset)
        f.write(r.args["buf"])
        f.close()

        # XXX
        # dynamically generated snapshots for fast lookup
        # dev = fd.inode.dev
        # ino = fd.inode.ino
        # tic = ret.origdata.ts
        # cp = fsmgr.FileContentCheckpoint(tic, tic, dev, ino)
        # fsmgr.FileDataNode.get(dev, ino).checkpoints.add(cp)

        # XXX update ret node
        return ret.origdata
Exemple #5
0
    def equiv(self):
        # ipopov: conjecture: the following four lines are probably to
        # guard against equiv() going ahead with incomplete data about
        # argument values and return values and such.
        if self.argsnode is None or self.retnode is None:
            return False
        if self.argsnode.data is None or self.retnode.data is None:
            return False

        if (hasattr(self.argsnode, "rerun")
                and self.argsnode.rerun.is_active()):
            return False

        r = self.argsnode.data

        if r.nr == syscall.NR_read:
            fd = r.args["fd"]

            dev = fd.inode.dev
            ino = fd.inode.ino
            off = fd.offset
            cnt = self.retnode.data.ret
            sha = self.retnode.data.args["buf"]

            if not fd.inode.prefix in ["file"]:
                return False

            src_pn = kutil.get(fd.inode)
            with open(src_pn, 'r') as f:
                f.seek(off)
                h = sha1(f.read(cnt))
                dbg.sha1m("!", "%s vs %s = %s" \
                      % (hexdigest(h),
                         hexdigest(sha),
                         h == sha))
                return h == sha
            return False
        elif r.nr == syscall.NR_open:
            path = r.args['path']
            arg_name = path.path
            dir_dev = path.entries[0].parent.dev
            dir_ino = path.entries[0].parent.ino

            ret_dev = self.retnode.data.ret.inode.dev
            ret_ino = self.retnode.data.ret.inode.ino

            dirent = fsmgr.DirentDataNode.get(dir_dev, dir_ino, arg_name)
            (cur_dev, cur_ino) = dirent.get_file_dev_ino()

            #code.interact(local=locals())

            dbg.info('open on %s yields (dev, ino) (%s, %s) origdata was'
                     '(%s %s)' % (path, cur_dev, cur_ino, ret_dev, ret_ino))

            if (cur_dev, cur_ino) == (ret_dev, ret_ino):
                # XXXX what if the file got _created_ by the open syscall? i.e.
                # if r.args['path'] contains no inode?
                return True
            else:
                return False

        if self.argsnode.origdata == self.argsnode.data:
            return True
        #
        # add any cases to stop the propagations
        #
        dbg.warn('#Y<XXX#> not quite right')
        return False