Exemple #1
0
    def install(cls, db, logger=None):
        if logger is None:
            logger = log.getChildLogger(cls.__name__)

        for flag, (char, nice_name) in cls.tainted_flags.items():
            if get_taint_flag_by_ureport_name(db, flag) is None:
                logger.info("Adding kernel taint flag '{0}': {1}"
                            .format(char, nice_name))

                new = KernelTaintFlag()
                new.character = char
                new.ureport_name = flag
                new.nice_name = nice_name
                db.session.add(new)

        db.session.flush()
Exemple #2
0
    def save_ureport(self, db, db_report, ureport, flush=False, count=1):
        bthash1 = self._hash_koops(ureport["frames"], skip_unreliable=False)
        bthash2 = self._hash_koops(ureport["frames"], skip_unreliable=True)

        if len(db_report.backtraces) < 1:
            db_backtrace = ReportBacktrace()
            db_backtrace.report = db_report
            db.session.add(db_backtrace)

            db_thread = ReportBtThread()
            db_thread.backtrace = db_backtrace
            db_thread.crashthread = True
            db.session.add(db_thread)

            db_bthash1 = ReportBtHash()
            db_bthash1.backtrace = db_backtrace
            db_bthash1.hash = bthash1
            db_bthash1.type = "NAMES"
            db.session.add(db_bthash1)

            if bthash2 is not None and bthash1 != bthash2:
                db_bthash2 = ReportBtHash()
                db_bthash2.backtrace = db_backtrace
                db_bthash2.hash = bthash2
                db_bthash2.type = "NAMES"
                db.session.add(db_bthash2)

            new_symbols = {}
            new_symbolsources = {}

            i = 0
            for frame in ureport["frames"]:
                # OK, this is totally ugly.
                # Frames may contain inlined functions, that would normally
                # require shifting all frames by 1 and inserting a new one.
                # There is no way to do this efficiently with SQL Alchemy
                # (you need to go one by one and flush after each) so
                # creating a space for additional frames is a huge speed
                # optimization.
                i += 10

                # nah, another hack, deals with wrong parsing
                if frame["function_name"].startswith("0x"):
                    continue

                if not "module_name" in frame:
                    module = "vmlinux"
                else:
                    module = frame["module_name"]

                db_symbol = get_symbol_by_name_path(db, frame["function_name"],
                                                    module)
                if db_symbol is None:
                    key = (frame["function_name"], module)
                    if key in new_symbols:
                        db_symbol = new_symbols[key]
                    else:
                        db_symbol = Symbol()
                        db_symbol.name = frame["function_name"]
                        db_symbol.normalized_path = module
                        db.session.add(db_symbol)
                        new_symbols[key] = db_symbol

                # this doesn't work well. on 64bit, kernel maps to
                # the end of address space (64bit unsigned), but in
                # postgres bigint is 64bit signed and can't save
                # the value - let's just map it to signed
                if frame["address"] >= (1 << 63):
                    address = frame["address"] - (1 << 64)
                else:
                    address = frame["address"]

                db_symbolsource = get_ssource_by_bpo(db, ureport["version"],
                                                     module, address)
                if db_symbolsource is None:
                    key = (ureport["version"], module, address)
                    if key in new_symbolsources:
                        db_symbolsource = new_symbolsources[key]
                    else:
                        db_symbolsource = SymbolSource()
                        db_symbolsource.path = module
                        db_symbolsource.offset = address
                        db_symbolsource.func_offset = frame["function_offset"]
                        db_symbolsource.symbol = db_symbol
                        db_symbolsource.build_id = ureport["version"]
                        db.session.add(db_symbolsource)
                        new_symbolsources[key] = db_symbolsource

                db_frame = ReportBtFrame()
                db_frame.thread = db_thread
                db_frame.order = i
                db_frame.symbolsource = db_symbolsource
                db_frame.inlined = False
                db_frame.reliable = frame["reliable"]
                db.session.add(db_frame)

            for taintflag in ureport["taint_flags"]:
                db_taintflag = get_taint_flag_by_ureport_name(db, taintflag)
                if db_taintflag is None:
                    self.log_warn("Skipping unsupported taint flag '{0}'"
                                  .format(taintflag))
                    continue

                db_bttaintflag = ReportBtTaintFlag()
                db_bttaintflag.backtrace = db_backtrace
                db_bttaintflag.taintflag = db_taintflag
                db.session.add(db_bttaintflag)

            if "modules" in ureport:
                new_modules = {}

                # use set() to remove duplicates
                for module in set(ureport["modules"]):
                    idx = module.find("(")
                    if idx >= 0:
                        module = module[:idx]

                    db_module = get_kernelmodule_by_name(db, module)
                    if db_module is None:
                        if module in new_modules:
                            db_module = new_modules[module]
                        else:
                            db_module = KernelModule()
                            db_module.name = module
                            db.session.add(db_module)
                            new_modules[module] = db_module

                    db_btmodule = ReportBtKernelModule()
                    db_btmodule.kernelmodule = db_module
                    db_btmodule.backtrace = db_backtrace
                    db.session.add(db_btmodule)

            # do not overwrite an existing oops
            if not db_report.has_lob("oops"):
                # do not append here, but create a new dict
                # we only want save_ureport_post_flush process the most
                # recently saved report
                self.add_lob = {db_report: ureport["raw_oops"].encode("utf-8")}

        if flush:
            db.session.flush()
Exemple #3
0
    def installed(cls, db):
        for flag in cls.tainted_flags.keys():
            if get_taint_flag_by_ureport_name(db, flag) is None:
                return False

        return True