// PR11234: __get_argv can overflow its return buffer // __get_argv has a signature like this: // struct function___get_argv_locals { // int64_t a; // int64_t first; // string_t __retvalue; // } function___get_argv; // // These functions are meant to have an overlap such that we can tell if // __get_argv overran its __retvalue. // // int64_t x; // int64_t y; // string_t z; // string_t __retvalue; // // NB: __retvalue[0] always gets cleared on call, but the rest should be // untouched, so we can use it as a sentinal. function clear:string(x:long, y:long, z:string) %{ memset(THIS->__retvalue, 0, MAXSTRINGLEN); %} function check:string(x:long, y:long, z:string) %{ int i, bad = 0; for (i=1; i__retvalue[i]) ++bad; if (bad) snprintf(THIS->__retvalue, MAXSTRINGLEN, "%d non-zero bytes", bad); else strlcpy(THIS->__retvalue, "ok", MAXSTRINGLEN); %} global result = "untested" probe syscall.execve { if (pid() != target()) next clear(0, 0, "") foo = __get_argv($argv, 0) result = check(0, 0, "") // ensure that foo isn't optimized away if (foo == "foo") next } probe begin { println("systemtap starting probe") } probe end { println("systemtap ending probe") if (result == "ok") println("systemtap test success") else println("systemtap test failure: ", result) }