def prefix(self): """Returns the prefix of the string representation of this inode. e.g. 'dir', 'fifo', ... """ if hasattr(self, "_prefix"): return self._prefix assert self.mode > 0 d = { S_ISDIR: "dir", S_ISCHR: "cdev", S_ISBLK: "bdev", S_ISREG: "file", S_ISFIFO: "fifo", S_ISLNK: "link", S_ISSOCK: "socket" } p = None for k, v in d.items(): if k(self.mode): p = v break if p == None: dbg.warn("%s should be one of modes" % self.mode) if p == "cdev": if hasattr(self, "pts"): assert self.rdev == 0x0502 return "ptm" major = os.major(self.rdev) if major >= 136 and major < 144: return "pts" self._prefix = p return p
def cancel_hook(self): if not self.argsnode.data: dbg.warn('cancel called on %s, but no argsnode' % self) return if (hasattr(self.argsnode, "rerun") and self.argsnode.rerun.is_active()): self.argsnode.rerun.kill(self.argsnode.data.pid) else: dbg.warn('rerun instance present, but not killing process, ' 'because rerun is inactive')
def equiv(self): # TODO # This function should consider only those parts of an argsnode # that are visible to the calling process. if self.retnode.data is None: return False if self.actor.rerun and self.actor.rerun.is_active(): return False if (self.retnode.origdata.args == self.retnode.data.args and self.retnode.origdata.ret == self.retnode.data.ret): return True dbg.warn('#Y<XXX#> not quite right') return False
def _fix_f(f): # find 0x84 0xE4 (time stamp) to fix up skip = 0 dump = [] while True: skip += 1 c = f.read(1) dump.append(c) if ord(c) == 0x84: c = f.read(1) if ord(c) & 0xE0 == 0xE0: f.seek(f.tell() - 2) break dbg.warn("Skip:%d [%s]" % (skip, "".join("%02x" % ord(c) for c in dump)))
def _feeder(self, pn, start, end): # only @@<< ... @@>> state_enable = False fd = self._dual_open(pn, start, end) for (l, n) in fd: if l == "": continue elif l.startswith("@@<<"): state_enable = True elif l.startswith("@@>>"): state_enable = False else: # if it is in the middle of a state, skip until next if state_enable == False: continue # relax, found a case where clang crashes if l[0] != "@" or not ":" in l: dbg.warn("not parsable: %s", l) continue (key, val) = self._split(l) # ok, new entry # None: end of line # "" : newline # "@" : normal entry if n is None or n == "" or n[0] == "@": yield (key, val) continue # entry w/ multiple lines for (l, n) in fd: val += l if n is None or n == "" or n[0] == "@": break yield (key, val)
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