aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
Diffstat (limited to 'kernel/kprobes.c')
-rw-r--r--kernel/kprobes.c39
1 files changed, 31 insertions, 8 deletions
diff --git a/kernel/kprobes.c b/kernel/kprobes.c
index 2161f519d481..993b84cc1db5 100644
--- a/kernel/kprobes.c
+++ b/kernel/kprobes.c
@@ -1921,28 +1921,48 @@ bool __weak arch_kprobe_on_func_entry(unsigned long offset)
1921 return !offset; 1921 return !offset;
1922} 1922}
1923 1923
1924bool kprobe_on_func_entry(kprobe_opcode_t *addr, const char *sym, unsigned long offset) 1924/**
1925 * kprobe_on_func_entry() -- check whether given address is function entry
1926 * @addr: Target address
1927 * @sym: Target symbol name
1928 * @offset: The offset from the symbol or the address
1929 *
1930 * This checks whether the given @addr+@offset or @sym+@offset is on the
1931 * function entry address or not.
1932 * This returns 0 if it is the function entry, or -EINVAL if it is not.
1933 * And also it returns -ENOENT if it fails the symbol or address lookup.
1934 * Caller must pass @addr or @sym (either one must be NULL), or this
1935 * returns -EINVAL.
1936 */
1937int kprobe_on_func_entry(kprobe_opcode_t *addr, const char *sym, unsigned long offset)
1925{ 1938{
1926 kprobe_opcode_t *kp_addr = _kprobe_addr(addr, sym, offset); 1939 kprobe_opcode_t *kp_addr = _kprobe_addr(addr, sym, offset);
1927 1940
1928 if (IS_ERR(kp_addr)) 1941 if (IS_ERR(kp_addr))
1929 return false; 1942 return PTR_ERR(kp_addr);
1930 1943
1931 if (!kallsyms_lookup_size_offset((unsigned long)kp_addr, NULL, &offset) || 1944 if (!kallsyms_lookup_size_offset((unsigned long)kp_addr, NULL, &offset))
1932 !arch_kprobe_on_func_entry(offset)) 1945 return -ENOENT;
1933 return false;
1934 1946
1935 return true; 1947 if (!arch_kprobe_on_func_entry(offset))
1948 return -EINVAL;
1949
1950 return 0;
1936} 1951}
1937 1952
1938int register_kretprobe(struct kretprobe *rp) 1953int register_kretprobe(struct kretprobe *rp)
1939{ 1954{
1940 int ret = 0; 1955 int ret;
1941 struct kretprobe_instance *inst; 1956 struct kretprobe_instance *inst;
1942 int i; 1957 int i;
1943 void *addr; 1958 void *addr;
1944 1959
1945 if (!kprobe_on_func_entry(rp->kp.addr, rp->kp.symbol_name, rp->kp.offset)) 1960 ret = kprobe_on_func_entry(rp->kp.addr, rp->kp.symbol_name, rp->kp.offset);
1961 if (ret)
1962 return ret;
1963
1964 /* If only rp->kp.addr is specified, check reregistering kprobes */
1965 if (rp->kp.addr && check_kprobe_rereg(&rp->kp))
1946 return -EINVAL; 1966 return -EINVAL;
1947 1967
1948 if (kretprobe_blacklist_size) { 1968 if (kretprobe_blacklist_size) {
@@ -1956,6 +1976,9 @@ int register_kretprobe(struct kretprobe *rp)
1956 } 1976 }
1957 } 1977 }
1958 1978
1979 if (rp->data_size > KRETPROBE_MAX_DATA_SIZE)
1980 return -E2BIG;
1981
1959 rp->kp.pre_handler = pre_handler_kretprobe; 1982 rp->kp.pre_handler = pre_handler_kretprobe;
1960 rp->kp.post_handler = NULL; 1983 rp->kp.post_handler = NULL;
1961 rp->kp.fault_handler = NULL; 1984 rp->kp.fault_handler = NULL;