block: fix 32 bit overflow in __blkdev_issue_discard()
[sfrench/cifs-2.6.git] / kernel / trace / trace_uprobe.c
index 912cb2093944ec310acd3d30f6c0a1eaa1e1df67..31ea48eceda184ed5e807f9fe22394f831980982 100644 (file)
@@ -101,11 +101,11 @@ static unsigned long get_user_stack_nth(struct pt_regs *regs, unsigned int n)
  * Uprobes-specific fetch functions
  */
 static nokprobe_inline int
-probe_user_read(void *dest, void *src, size_t size)
+probe_mem_read(void *dest, void *src, size_t size)
 {
        void __user *vaddr = (void __force __user *)src;
 
-       return copy_from_user(dest, vaddr, size);
+       return copy_from_user(dest, vaddr, size) ? -EFAULT : 0;
 }
 /*
  * Fetch a null-terminated string. Caller MUST set *(u32 *)dest with max
@@ -162,7 +162,6 @@ process_fetch_insn(struct fetch_insn *code, struct pt_regs *regs, void *dest,
                   void *base)
 {
        unsigned long val;
-       int ret = 0;
 
        /* 1st stage: get value from context */
        switch (code->op) {
@@ -189,45 +188,7 @@ process_fetch_insn(struct fetch_insn *code, struct pt_regs *regs, void *dest,
        }
        code++;
 
-       /* 2nd stage: dereference memory if needed */
-       while (code->op == FETCH_OP_DEREF) {
-               ret = probe_user_read(&val, (void *)val + code->offset,
-                                     sizeof(val));
-               if (ret)
-                       return ret;
-               code++;
-       }
-
-       /* 3rd stage: store value to buffer */
-       if (unlikely(!dest)) {
-               if (code->op == FETCH_OP_ST_STRING)
-                       return fetch_store_strlen(val + code->offset);
-               else
-                       return -EILSEQ;
-       }
-
-       switch (code->op) {
-       case FETCH_OP_ST_RAW:
-               fetch_store_raw(val, code, dest);
-               break;
-       case FETCH_OP_ST_MEM:
-               probe_kernel_read(dest, (void *)val + code->offset, code->size);
-               break;
-       case FETCH_OP_ST_STRING:
-               ret = fetch_store_string(val + code->offset, dest, base);
-               break;
-       default:
-               return -EILSEQ;
-       }
-       code++;
-
-       /* 4th stage: modify stored value if needed */
-       if (code->op == FETCH_OP_MOD_BF) {
-               fetch_apply_bitfield(code, dest);
-               code++;
-       }
-
-       return code->op == FETCH_OP_END ? ret : -EILSEQ;
+       return process_fetch_insn_bottom(code, val, dest, base);
 }
 NOKPROBE_SYMBOL(process_fetch_insn)
 
@@ -596,7 +557,7 @@ static int create_trace_uprobe(int argc, char **argv)
 
                /* Parse fetch argument */
                ret = traceprobe_parse_probe_arg(arg, &tu->tp.size, parg,
-                                                is_return, false);
+                                       is_return ? TPARG_FL_RETURN : 0);
                if (ret) {
                        pr_info("Parse error at argument[%d]. (%d)\n", i, ret);
                        goto error;