Example #1
0
/* ====================================================================== */
int
kedr_init_module_ms_alloc(void)
{
	int ret = kallsyms_on_each_symbol(symbol_walk_callback, NULL);
	if (ret)
		return ret;
	
	if (module_alloc_func == NULL) {
		pr_warning(KEDR_MSG_PREFIX
		"Unable to find \"module_alloc\" function\n");
		return -EFAULT;
	}

#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 19, 0))
	if (module_memfree_func == NULL) {
		pr_warning(KEDR_MSG_PREFIX
		"Unable to find \"module_memfree\" function.\n");
		return -EFAULT;
	}
#else
	if (module_free_func == NULL) {
		pr_warning(KEDR_MSG_PREFIX
		"Unable to find \"module_free\" function.\n");
		return -EFAULT;
	}
#endif
	return 0; /* success */
}
Example #2
0
static int find_syscalls(void)
{
	int rc;

	ugidctl_sys_setuid = NULL;
	ugidctl_sys_setgid = NULL;
	ugidctl_sys_setgroups = NULL;

	rc = kallsyms_on_each_symbol(symbol_walk_callback, NULL);
	if (rc)
		return rc;

	if (ugidctl_sys_setuid == NULL) {
		printk(KERN_ERR "%s: unable to find sys_setuid()\n",
				MOD_NAME);
		return -EFAULT;
	}

	if (ugidctl_sys_setgid == NULL) {
		printk(KERN_ERR "%s: unable to find sys_setgid()\n",
				MOD_NAME);
		return -EFAULT;
	}

	if (ugidctl_sys_setgroups == NULL) {
		printk(KERN_ERR "%s: unable to find sys_setgroups()\n",
				MOD_NAME);
		return -EFAULT;
	}

	return 0;
}
static int
stapkp_init(struct stap_kprobe_probe *probes,
            size_t nprobes)
{
    size_t i;

#ifdef STAPCONF_KALLSYMS_ON_EACH_SYMBOL
    // If we have any symbol_name+offset probes, we need to try to
    // convert those into address-based probes.
    size_t probe_max = 0;
    for (i = 0; i < nprobes; i++) {
        struct stap_kprobe_probe *skp = &probes[i];

        if (! skp->symbol_name)
            continue;
        ++probe_max;
    }
    if (probe_max > 0) {
        // Here we're going to try to convert any symbol_name+offset
        // probes into address probes.
        struct stapkp_symbol_data sd;
        dbug_stapkp("looking up %lu probes\n", probe_max);
        sd.probes = probes;
        sd.nprobes = nprobes;
        sd.probe_max = probe_max;
        sd.modname = NULL;
        preempt_disable();
        kallsyms_on_each_symbol(stapkp_symbol_callback, &sd);
        preempt_enable();
        dbug_stapkp("found %lu probes\n", sd.probe_max);
    }
#endif

    for (i = 0; i < nprobes; i++) {
        struct stap_kprobe_probe *skp = &probes[i];
        int rc = 0;

        rc = stapkp_register_probe(skp);
        if (rc == 1) // failed to relocate addr?
            continue; // don't fuss about it, module probably not loaded

        // NB: We keep going even if a probe failed to register (PR6749). We only
        // warn about it if it wasn't optional and isn't in a module.
        if (rc && !skp->optional_p
                && ((skp->module == NULL) || skp->module[0] == '\0'
                    || strcmp(skp->module, "kernel") == 0)) {
            if (skp->symbol_name)
                _stp_warn("probe %s (%s+%u) registration error (rc %d)",
                          skp->probe->pp, skp->symbol_name, skp->offset, rc);
            else
                _stp_warn("probe %s (address 0x%lx) registration error (rc %d)",
                          skp->probe->pp, stapkp_relocate_addr(skp), rc);
        }
    }

    return 0;
}
Example #4
0
static int cmd_profile_dump(struct vmm_chardev * cdev, char *filter_mode)
{
	int index = 0;
	int (*cmp_function) (void *, size_t, size_t) = cmd_profile_count_cmp;

	if (filter_mode != NULL) {
		cmp_function = NULL;
		while (filters[index].name) {
			if (strcmp(filter_mode, filters[index].name) == 0) {
				cmp_function = filters[index].function;
				break;
			}
			index++;
		}
	}

	if (cmp_function == NULL) {
		cmd_profile_usage(cdev);
		return VMM_EFAIL;
	}

	kallsyms_on_each_symbol(cmd_profile_count_iterator, count_array);

	libsort_smoothsort(count_array, 0, kallsyms_num_syms, cmp_function,
			   cmd_profile_swap);

	for (index = 0; index < kallsyms_num_syms; index++) {
		if (count_array[index].count) {
			vmm_printf("%-30s %-10u %-10u %u\n",
				   count_array[index].function_name,
				   count_array[index].count,
				   ns_to_micros(count_array[index].total_time),
				   ns_to_micros(count_array[index].time_per_call));
		}
	}

	return VMM_OK;
}
/* stapkp_refresh is called for two reasons: either a kprobe needs to be
 * enabled/disabled (modname is NULL), or a module has been loaded/unloaded and
 * kprobes need to be registered/unregistered (modname is !NULL). */
static void
stapkp_refresh(const char *modname,
               struct stap_kprobe_probe *probes,
               size_t nprobes)
{
    size_t i;

    dbug_stapkp("refresh %lu probes with module %s\n", nprobes, modname ?: "?");

#ifdef STAPCONF_KALLSYMS_ON_EACH_SYMBOL
    if (modname) {
        size_t probe_max = 0;
        for (i = 0; i < nprobes; i++) {
            struct stap_kprobe_probe *skp = &probes[i];

            // If this probe is in the same module that is being
            // loaded/unloaded and the probe is symbol_name+offset based
            // and it isn't registered (so the module must be loaded),
            // try to convert all probes in the same module to
            // address-based probes.
            if (skp->module && strcmp(modname, skp->module) == 0
                    && skp->symbol_name && skp->registered_p == 0)
                ++probe_max;
        }
        if (probe_max > 0) {
            struct stapkp_symbol_data sd;
            sd.probes = probes;
            sd.nprobes = nprobes;
            sd.probe_max = probe_max;
            sd.modname = modname;
            preempt_disable();
            kallsyms_on_each_symbol(stapkp_symbol_callback, &sd);
            preempt_enable();
        }
    }
#endif

    for (i = 0; i < nprobes; i++) {

        struct stap_kprobe_probe *skp = &probes[i];

        // was this probe's target module loaded/unloaded
        if (modname && skp->module
                && strcmp(modname, skp->module) == 0) {
            int rc;
            unsigned long addr = (! skp->symbol_name
                                  ? stapkp_relocate_addr(skp) : 0);

            // module being loaded?
            if (skp->registered_p == 0 && (addr != 0 || skp->symbol_name))
                stapkp_register_probe(skp);
            // module/section being unloaded?
            else if (skp->registered_p == 1 && addr == 0)
                stapkp_unregister_probe(skp);

        }
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,30)
        else if (stapkp_should_enable_probe(skp)
                 || stapkp_should_disable_probe(skp)) {
            stapkp_refresh_probe(skp);
        }
#endif
    }
}
Example #6
0
static int klp_find_object_symbol(const char *objname, const char *name,
				  unsigned long sympos, unsigned long *addr)
{
	struct klp_find_arg args = {
		.objname = objname,
		.name = name,
		.addr = 0,
		.count = 0,
		.pos = sympos,
	};

	mutex_lock(&module_mutex);
	if (objname)
		module_kallsyms_on_each_symbol(klp_find_callback, &args);
	else
		kallsyms_on_each_symbol(klp_find_callback, &args);
	mutex_unlock(&module_mutex);

	/*
	 * Ensure an address was found. If sympos is 0, ensure symbol is unique;
	 * otherwise ensure the symbol position count matches sympos.
	 */
	if (args.addr == 0)
		pr_err("symbol '%s' not found in symbol table\n", name);
	else if (args.count > 1 && sympos == 0) {
		pr_err("unresolvable ambiguity for symbol '%s' in object '%s'\n",
		       name, objname);
	} else if (sympos != args.count && sympos > 0) {
		pr_err("symbol position %lu for symbol '%s' in object '%s' not found\n",
		       sympos, name, objname ? objname : "vmlinux");
	} else {
		*addr = args.addr;
		return 0;
	}

	*addr = 0;
	return -EINVAL;
}

static int klp_resolve_symbols(Elf_Shdr *relasec, struct module *pmod)
{
	int i, cnt, vmlinux, ret;
	char objname[MODULE_NAME_LEN];
	char symname[KSYM_NAME_LEN];
	char *strtab = pmod->core_kallsyms.strtab;
	Elf_Rela *relas;
	Elf_Sym *sym;
	unsigned long sympos, addr;

	/*
	 * Since the field widths for objname and symname in the sscanf()
	 * call are hard-coded and correspond to MODULE_NAME_LEN and
	 * KSYM_NAME_LEN respectively, we must make sure that MODULE_NAME_LEN
	 * and KSYM_NAME_LEN have the values we expect them to have.
	 *
	 * Because the value of MODULE_NAME_LEN can differ among architectures,
	 * we use the smallest/strictest upper bound possible (56, based on
	 * the current definition of MODULE_NAME_LEN) to prevent overflows.
	 */
	BUILD_BUG_ON(MODULE_NAME_LEN < 56 || KSYM_NAME_LEN != 128);

	relas = (Elf_Rela *) relasec->sh_addr;
	/* For each rela in this klp relocation section */
	for (i = 0; i < relasec->sh_size / sizeof(Elf_Rela); i++) {
		sym = pmod->core_kallsyms.symtab + ELF_R_SYM(relas[i].r_info);
		if (sym->st_shndx != SHN_LIVEPATCH) {
			pr_err("symbol %s is not marked as a livepatch symbol\n",
			       strtab + sym->st_name);
			return -EINVAL;
		}

		/* Format: .klp.sym.objname.symname,sympos */
		cnt = sscanf(strtab + sym->st_name,
			     ".klp.sym.%55[^.].%127[^,],%lu",
			     objname, symname, &sympos);
		if (cnt != 3) {
			pr_err("symbol %s has an incorrectly formatted name\n",
			       strtab + sym->st_name);
			return -EINVAL;
		}

		/* klp_find_object_symbol() treats a NULL objname as vmlinux */
		vmlinux = !strcmp(objname, "vmlinux");
		ret = klp_find_object_symbol(vmlinux ? NULL : objname,
					     symname, sympos, &addr);
		if (ret)
			return ret;

		sym->st_value = addr;
	}

	return 0;
}