1. 05 6月, 2014 2 次提交
  2. 14 5月, 2014 2 次提交
    • O
      uprobes/x86: Fix the wrong ->si_addr when xol triggers a trap · b02ef20a
      Oleg Nesterov 提交于
      If the probed insn triggers a trap, ->si_addr = regs->ip is technically
      correct, but this is not what the signal handler wants; we need to pass
      the address of the probed insn, not the address of xol slot.
      
      Add the new arch-agnostic helper, uprobe_get_trap_addr(), and change
      fill_trap_info() and math_error() to use it. !CONFIG_UPROBES case in
      uprobes.h uses a macro to avoid include hell and ensure that it can be
      compiled even if an architecture doesn't define instruction_pointer().
      
      Test-case:
      
      	#include <signal.h>
      	#include <stdio.h>
      	#include <unistd.h>
      
      	extern void probe_div(void);
      
      	void sigh(int sig, siginfo_t *info, void *c)
      	{
      		int passed = (info->si_addr == probe_div);
      		printf(passed ? "PASS\n" : "FAIL\n");
      		_exit(!passed);
      	}
      
      	int main(void)
      	{
      		struct sigaction sa = {
      			.sa_sigaction	= sigh,
      			.sa_flags	= SA_SIGINFO,
      		};
      
      		sigaction(SIGFPE, &sa, NULL);
      
      		asm (
      			"xor %ecx,%ecx\n"
      			".globl probe_div; probe_div:\n"
      			"idiv %ecx\n"
      		);
      
      		return 0;
      	}
      
      it fails if probe_div() is probed.
      
      Note: show_unhandled_signals users should probably use this helper too,
      but we need to cleanup them first.
      Signed-off-by: NOleg Nesterov <oleg@redhat.com>
      Reviewed-by: NMasami Hiramatsu <masami.hiramatsu.pt@hitachi.com>
      b02ef20a
    • O
      uprobes: Add mem_cgroup_charge_anon() into uprobe_write_opcode() · 29dedee0
      Oleg Nesterov 提交于
      Hugh says:
      
          The one I noticed was that it forgets all about memcg (because
          it was copied from KSM, and there the replacement page has already
          been charged to a memcg). See how mm/memory.c do_anonymous_page()
          does a mem_cgroup_charge_anon().
      
      Hopefully not a big problem, uprobes is a system-wide thing and only
      root can insert the probes. But I agree, should be fixed anyway.
      
      Add mem_cgroup_{un,}charge_anon() into uprobe_write_opcode(). To simplify
      the error handling (and avoid the new "uncharge" label) the patch also
      moves anon_vma_prepare() up before we alloc/charge the new page.
      
      While at it fix the comment about ->mmap_sem, it is held for write.
      Suggested-by: NHugh Dickins <hughd@google.com>
      Signed-off-by: NOleg Nesterov <oleg@redhat.com>
      29dedee0
  3. 01 5月, 2014 1 次提交
    • O
      uprobes: Refuse to insert a probe into MAP_SHARED vma · 13f59c5e
      Oleg Nesterov 提交于
      valid_vma() rejects the VM_SHARED vmas, but this still allows to insert
      a probe into the MAP_SHARED but not VM_MAYWRITE vma.
      
      Currently this is fine, such a mapping doesn't really differ from the
      private read-only mmap except mprotect(PROT_WRITE) won't work. However,
      get_user_pages(FOLL_WRITE | FOLL_FORCE) doesn't allow to COW in this
      case, and it would be safer to follow the same conventions as mm even
      if currently this happens to work.
      
      After the recent cda540ac "mm: get_user_pages(write,force) refuse
      to COW in shared areas" only uprobes can insert an anon page into the
      shared file-backed area, lets stop this and change valid_vma() to check
      VM_MAYSHARE instead.
      Signed-off-by: NOleg Nesterov <oleg@redhat.com>
      13f59c5e
  4. 18 4月, 2014 2 次提交
    • O
      uprobes/x86: Send SIGILL if arch_uprobe_post_xol() fails · 014940ba
      Oleg Nesterov 提交于
      Currently the error from arch_uprobe_post_xol() is silently ignored.
      This doesn't look good and this can lead to the hard-to-debug problems.
      
      1. Change handle_singlestep() to loudly complain and send SIGILL.
      
         Note: this only affects x86, ppc/arm can't fail.
      
      2. Change arch_uprobe_post_xol() to call arch_uprobe_abort_xol() and
         avoid TF games if it is going to return an error.
      
         This can help to to analyze the problem, if nothing else we should
         not report ->ip = xol_slot in the core-file.
      
         Note: this means that handle_riprel_post_xol() can be called twice,
         but this is fine because it is idempotent.
      Signed-off-by: NOleg Nesterov <oleg@redhat.com>
      Reviewed-by: NMasami Hiramatsu <masami.hiramatsu.pt@hitachi.com>
      Reviewed-by: NJim Keniston <jkenisto@us.ibm.com>
      014940ba
    • O
      uprobes: Kill UPROBE_SKIP_SSTEP and can_skip_sstep() · 8a6b1732
      Oleg Nesterov 提交于
      UPROBE_COPY_INSN, UPROBE_SKIP_SSTEP, and uprobe->flags must die. This
      patch kills UPROBE_SKIP_SSTEP. I never understood why it was added;
      not only it doesn't help, it harms.
      
      It can only help to avoid arch_uprobe_skip_sstep() if it was already
      called before and failed. But this is ugly, if we want to know whether
      we can emulate this instruction or not we should do this analysis in
      arch_uprobe_analyze_insn(), not when we hit this probe for the first
      time.
      
      And in fact this logic is simply wrong. arch_uprobe_skip_sstep() can
      fail or not depending on the task/register state, if this insn can be
      emulated but, say, put_user() fails we need to xol it this time, but
      this doesn't mean we shouldn't try to emulate it when this or another
      thread hits this bp next time.
      
      And this is the actual reason for this change. We need to emulate the
      "call" insn, but push(return-address) can obviously fail.
      
      Per-arch notes:
      
      	x86: __skip_sstep() can only emulate "rep;nop". With this
      	     change it will be called every time and most probably
      	     for no reason.
      
      	     This will be fixed by the next changes. We need to
      	     change this suboptimal code anyway.
      
      	arm: Should not be affected. It has its own "bool simulate"
      	     flag checked in arch_uprobe_skip_sstep().
      
      	ppc: Looks like, it can emulate almost everything. Does it
      	     actually need to record the fact that emulate_step()
      	     failed? Hopefully not. But if yes, it can add the ppc-
      	     specific flag into arch_uprobe.
      
      TODO: rename arch_uprobe_skip_sstep() to arch_uprobe_emulate_insn(),
      Signed-off-by: NOleg Nesterov <oleg@redhat.com>
      Reviewed-by: NMasami Hiramatsu <masami.hiramatsu.pt@hitachi.com>
      Reviewed-by: NDavid A. Long <dave.long@linaro.org>
      Reviewed-by: NJim Keniston <jkenisto@us.ibm.com>
      Acked-by: NSrikar Dronamraju <srikar@linux.vnet.ibm.com>
      8a6b1732
  5. 19 3月, 2014 1 次提交
  6. 03 1月, 2014 1 次提交
  7. 20 11月, 2013 4 次提交
  8. 10 11月, 2013 2 次提交
    • O
      uprobes: Fix the memory out of bound overwrite in copy_insn() · 2ded0980
      Oleg Nesterov 提交于
      1. copy_insn() doesn't look very nice, all calculations are
         confusing and it is not immediately clear why do we read
         the 2nd page first.
      
      2. The usage of inode->i_size is wrong on 32-bit machines.
      
      3. "Instruction at end of binary" logic is simply wrong, it
         doesn't handle the case when uprobe->offset > inode->i_size.
      
         In this case "bytes" overflows, and __copy_insn() writes to
         the memory outside of uprobe->arch.insn.
      
         Yes, uprobe_register() checks i_size_read(), but this file
         can be truncated after that. All i_size checks are racy, we
         do this only to catch the obvious mistakes.
      
      Change copy_insn() to call __copy_insn() in a loop, simplify
      and fix the bytes/nbytes calculations.
      
      Note: we do not care if we read extra bytes after inode->i_size
      if we got the valid page. This is fine because the task gets the
      same page after page-fault, and arch_uprobe_analyze_insn() can't
      know how many bytes were actually read anyway.
      Signed-off-by: NOleg Nesterov <oleg@redhat.com>
      2ded0980
    • O
      uprobes: Fix the wrong usage of current->utask in uprobe_copy_process() · 70d7f987
      Oleg Nesterov 提交于
      Commit aa59c53f "uprobes: Change uprobe_copy_process() to dup
      xol_area" has a stupid typo, we need to setup t->utask->vaddr but
      the code wrongly uses current->utask.
      
      Even with this bug dup_xol_work() works "in practice", but only
      because get_unmapped_area(NULL, TASK_SIZE - PAGE_SIZE) likely
      returns the same address every time.
      Signed-off-by: NOleg Nesterov <oleg@redhat.com>
      70d7f987
  9. 07 11月, 2013 3 次提交
    • O
      uprobes: Export write_opcode() as uprobe_write_opcode() · f72d41fa
      Oleg Nesterov 提交于
      set_swbp() and set_orig_insn() are __weak, but this is pointless
      because write_opcode() is static.
      
      Export write_opcode() as uprobe_write_opcode() for the upcoming
      arm port, this way it can actually override set_swbp() and use
      __opcode_to_mem_arm(bpinsn) instead if UPROBE_SWBP_INSN.
      Signed-off-by: NOleg Nesterov <oleg@redhat.com>
      f72d41fa
    • O
      uprobes: Introduce arch_uprobe->ixol · 8a8de66c
      Oleg Nesterov 提交于
      Currently xol_get_insn_slot() assumes that we should simply copy
      arch_uprobe->insn[] which is (ignoring arch_uprobe_analyze_insn)
      just the copy of the original insn.
      
      This is not true for arm which needs to create another insn to
      execute it out-of-line.
      
      So this patch simply adds the new member, ->ixol into the union.
      This doesn't make any difference for x86 and powerpc, but arm
      can divorce insn/ixol and initialize the correct xol insn in
      arch_uprobe_analyze_insn().
      Signed-off-by: NOleg Nesterov <oleg@redhat.com>
      8a8de66c
    • O
      uprobes: Kill module_init() and module_exit() · 736e89d9
      Oleg Nesterov 提交于
      Turn module_init() into __initcall() and kill module_exit().
      
      This code can't be compiled as a module so these module_*()
      calls only add the confusion, especially if arch-dependant
      code needs its own initialization hooks.
      Signed-off-by: NOleg Nesterov <oleg@redhat.com>
      736e89d9
  10. 30 10月, 2013 6 次提交
    • O
      uprobes: Teach uprobe_copy_process() to handle CLONE_VFORK · 3ab67966
      Oleg Nesterov 提交于
      uprobe_copy_process() does nothing if the child shares ->mm with
      the forking process, but there is a special case: CLONE_VFORK.
      In this case it would be more correct to do dup_utask() but avoid
      dup_xol(). This is not that important, the child should not unwind
      its stack too much, this can corrupt the parent's stack, but at
      least we need this to allow to ret-probe __vfork() itself.
      
      Note: in theory, it would be better to check task_pt_regs(p)->sp
      instead of CLONE_VFORK, we need to dup_utask() if and only if the
      child can return from the function called by the parent. But this
      needs the arch-dependant helper, and I think that nobody actually
      does clone(same_stack, CLONE_VM).
      Reported-by: NMartin Cermak <mcermak@redhat.com>
      Reported-by: NDavid Smith <dsmith@redhat.com>
      Signed-off-by: NOleg Nesterov <oleg@redhat.com>
      3ab67966
    • O
      uprobes: Change uprobe_copy_process() to dup xol_area · aa59c53f
      Oleg Nesterov 提交于
      This finally fixes the serious bug in uretprobes: a forked child
      crashes if the parent called fork() with the pending ret probe.
      
      Trivial test-case:
      
      	# perf probe -x /lib/libc.so.6 __fork%return
      	# perf record -e probe_libc:__fork perl -le 'fork || print "OK"'
      
      (the child doesn't print "OK", it is killed by SIGSEGV)
      
      If the child returns from the probed function it actually returns
      to trampoline_vaddr, because it got the copy of parent's stack
      mangled by prepare_uretprobe() when the parent entered this func.
      
      It crashes because a) this address is not mapped and b) until the
      previous change it doesn't have the proper->return_instances info.
      
      This means that uprobe_copy_process() has to create xol_area which
      has the trampoline slot, and its vaddr should be equal to parent's
      xol_area->vaddr.
      
      Unfortunately, uprobe_copy_process() can not simply do
      __create_xol_area(child, xol_area->vaddr). This could actually work
      but perf_event_mmap() doesn't expect the usage of foreign ->mm. So
      we offload this to task_work_run(), and pass the argument via not
      yet used utask->vaddr.
      
      We know that this vaddr is fine for install_special_mapping(), the
      necessary hole was recently "created" by dup_mmap() which skips the
      parent's VM_DONTCOPY area, and nobody else could use the new mm.
      
      Unfortunately, this also means that we can not handle the errors
      properly, we obviously can not abort the already completed fork().
      So we simply print the warning if GFP_KERNEL allocation (the only
      possible reason) fails.
      Reported-by: NMartin Cermak <mcermak@redhat.com>
      Reported-by: NDavid Smith <dsmith@redhat.com>
      Signed-off-by: NOleg Nesterov <oleg@redhat.com>
      Acked-by: NSrikar Dronamraju <srikar@linux.vnet.ibm.com>
      aa59c53f
    • O
      uprobes: Change uprobe_copy_process() to dup return_instances · 248d3a7b
      Oleg Nesterov 提交于
      uprobe_copy_process() assumes that the new child doesn't need
      ->utask, it should be allocated by demand.
      
      But this is not true if the forking task has the pending ret-
      probes, the child should report them as well and thus it needs
      the copy of parent's ->return_instances chain. Otherwise the
      child crashes when it returns from the probed function.
      
      Alternatively we could cleanup the child's stack, but this needs
      per-arch changes and this is not what we want. At least systemtap
      expects a .return in the child too.
      
      Note: this change alone doesn't fix the problem, see the next
      change.
      Reported-by: NMartin Cermak <mcermak@redhat.com>
      Reported-by: NDavid Smith <dsmith@redhat.com>
      Signed-off-by: NOleg Nesterov <oleg@redhat.com>
      Acked-by: NSrikar Dronamraju <srikar@linux.vnet.ibm.com>
      248d3a7b
    • O
      uprobes: Teach __create_xol_area() to accept the predefined vaddr · af0d95af
      Oleg Nesterov 提交于
      Currently xol_add_vma() uses get_unmapped_area() for area->vaddr,
      but the next patches need to use the fixed address. So this patch
      adds the new "vaddr" argument to __create_xol_area() which should
      be used as area->vaddr if it is nonzero.
      
      xol_add_vma() doesn't bother to verify that the predefined addr is
      not used, insert_vm_struct() should fail if find_vma_links() detects
      the overlap with the existing vma.
      
      Also, __create_xol_area() doesn't need __GFP_ZERO to allocate area.
      Signed-off-by: NOleg Nesterov <oleg@redhat.com>
      Acked-by: NSrikar Dronamraju <srikar@linux.vnet.ibm.com>
      af0d95af
    • O
      uprobes: Introduce __create_xol_area() · 6441ec8b
      Oleg Nesterov 提交于
      No functional changes, preparation.
      
      Extract the code which actually allocates/installs the new area
      into the new helper, __create_xol_area().
      
      While at it remove the unnecessary "ret = ENOMEM" and "ret = 0"
      in xol_add_vma(), they both have no effect.
      Signed-off-by: NOleg Nesterov <oleg@redhat.com>
      Acked-by: NSrikar Dronamraju <srikar@linux.vnet.ibm.com>
      6441ec8b
    • O
      uprobes: Change the callsite of uprobe_copy_process() · b68e0749
      Oleg Nesterov 提交于
      Preparation for the next patches.
      
      Move the callsite of uprobe_copy_process() in copy_process() down
      to the succesfull return. We do not care if copy_process() fails,
      uprobe_free_utask() won't be called in this case so the wrong
      ->utask != NULL doesn't matter.
      
      OTOH, with this change we know that copy_process() can't fail when
      uprobe_copy_process() is called, the new task should either return
      to user-mode or call do_exit(). This way uprobe_copy_process() can:
      
      	1. setup p->utask != NULL if necessary
      
      	2. setup uprobes_state.xol_area
      
      	3. use task_work_add(p)
      
      Also, move the definition of uprobe_copy_process() down so that it
      can see get_utask().
      Signed-off-by: NOleg Nesterov <oleg@redhat.com>
      Acked-by: NSrikar Dronamraju <srikar@linux.vnet.ibm.com>
      b68e0749
  11. 12 9月, 2013 1 次提交
  12. 13 4月, 2013 6 次提交
  13. 04 4月, 2013 7 次提交
  14. 09 2月, 2013 2 次提交
    • O
      uprobes: Introduce uprobe_apply() · bdf8647c
      Oleg Nesterov 提交于
      Currently it is not possible to change the filtering constraints after
      uprobe_register(), so a consumer can not, say, start to trace a task/mm
      which was previously filtered out, or remove the no longer needed bp's.
      
      Introduce uprobe_apply() which simply does register_for_each_vma() again
      to consult uprobe_consumer->filter() and install/remove the breakpoints.
      The only complication is that register_for_each_vma() can no longer
      assume that uprobe->consumers should be consulter if is_register == T,
      so we change it to accept "struct uprobe_consumer *new" instead.
      
      Unlike uprobe_register(), uprobe_apply(true) doesn't do "unregister" if
      register_for_each_vma() fails, it is up to caller to handle the error.
      
      Note: we probably need to cleanup the current interface, it is strange
      that uprobe_apply/unregister need inode/offset. We should either change
      uprobe_register() to return "struct uprobe *", or add a private ->uprobe
      member in uprobe_consumer. And in the long term uprobe_apply() should
      take a single argument, uprobe or consumer, even "bool add" should go
      away.
      Signed-off-by: NOleg Nesterov <oleg@redhat.com>
      bdf8647c
    • J
      uprobes: Add exports for module use · e8440c14
      Josh Stone 提交于
      The original pull message for uprobes (commit 654443e2) noted:
      
        This tree includes uprobes support in 'perf probe' - but SystemTap
        (and other tools) can take advantage of user probe points as well.
      
      In order to actually be usable in module-based tools like SystemTap, the
      interface needs to be exported.  This patch first adds the obvious
      exports for uprobe_register and uprobe_unregister.  Then it also adds
      one for task_user_regset_view, which is necessary to get the correct
      state of userspace registers.
      Signed-off-by: NJosh Stone <jistone@redhat.com>
      Signed-off-by: NOleg Nesterov <oleg@redhat.com>
      e8440c14