Skip to content

Commit

Permalink
Merge pull request #48 from P403n1x87/fix/where-pipe-permissions
Browse files Browse the repository at this point in the history
fix: where mode named pipe permissions
  • Loading branch information
P403n1x87 authored Oct 14, 2023
2 parents 27b4023 + 08fcad9 commit e6a06c5
Show file tree
Hide file tree
Showing 5 changed files with 46 additions and 17 deletions.
25 changes: 16 additions & 9 deletions echion/__main__.py
Original file line number Diff line number Diff line change
Expand Up @@ -31,19 +31,24 @@ def detach(pid: int) -> None:
def attach(args: argparse.Namespace) -> None:
from hypno import inject_py

script = dedent(
f"""
from echion.bootstrap.attach import attach
attach({args.__dict__!r})
"""
).strip()

pid = args.pid or args.where

try:
pipe_name = None
if args.where:
pipe_name = Path(tempfile.gettempdir()) / f"echion-{pid}"
os.mkfifo(pipe_name)
# This named pipe is likely created by the superuser, so we need to
# make it writable by everyone to allow the target process to write
# to it.
os.chmod(pipe_name, 0o666)

script = dedent(
f"""
from echion.bootstrap.attach import attach
attach({args.__dict__!r}, {repr(str(pipe_name)) if pipe_name is not None else str(None)})
"""
).strip()

inject_py(pid, script)

Expand All @@ -53,6 +58,7 @@ def attach(args: argparse.Namespace) -> None:
from time import monotonic as time

end = time() + args.exposure

while not args.where:
try:
os.kill(pid, 0)
Expand All @@ -61,11 +67,12 @@ def attach(args: argparse.Namespace) -> None:
if end is not None and time() > end:
break
os.sched_yield()

except (KeyboardInterrupt, ProcessLookupError):
pass

# Read the output
if args.where and pipe_name.exists():
if args.where and pipe_name is not None and pipe_name.exists():
with pipe_name.open("r") as f:
while True:
line = f.readline()
Expand All @@ -76,7 +83,7 @@ def attach(args: argparse.Namespace) -> None:
detach(pid)

finally:
if args.where and pipe_name.exists():
if args.where and pipe_name is not None and pipe_name.exists():
pipe_name.unlink()


Expand Down
8 changes: 7 additions & 1 deletion echion/bootstrap/attach.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
import typing as t


def attach(config: t.Dict[str, str]) -> None:
def attach(config: t.Dict[str, str], pipe_name: t.Optional[str] = None) -> None:
os.environ["ECHION_CPU"] = str(int(config["cpu"]))
os.environ["ECHION_NATIVE"] = str(int(config["native"]))
os.environ["ECHION_OUTPUT"] = config["output"]
Expand All @@ -15,6 +15,12 @@ def attach(config: t.Dict[str, str]) -> None:

from echion.bootstrap import start

# This is used in where mode for IPC.
if pipe_name is not None:
from echion.core import set_pipe_name

set_pipe_name(pipe_name)

start()


Expand Down
16 changes: 16 additions & 0 deletions echion/config.h
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,9 @@ static int native = 0;
// Where mode
static int where = 0;

// Pipe name (where mode IPC)
static std::string pipe_name;

// ----------------------------------------------------------------------------
static PyObject *
set_interval(PyObject *Py_UNUSED(m), PyObject *args)
Expand Down Expand Up @@ -77,3 +80,16 @@ set_where(PyObject *Py_UNUSED(m), PyObject *args)

Py_RETURN_NONE;
}

// ----------------------------------------------------------------------------
static PyObject *
set_pipe_name(PyObject *Py_UNUSED(m), PyObject *args)
{
const char *name;
if (!PyArg_ParseTuple(args, "s", &name))
return NULL;

pipe_name = name;

Py_RETURN_NONE;
}
1 change: 1 addition & 0 deletions echion/core.pyi
Original file line number Diff line number Diff line change
Expand Up @@ -23,3 +23,4 @@ def set_interval(interval: int) -> None: ...
def set_cpu(cpu: bool) -> None: ...
def set_native(native: bool) -> None: ...
def set_where(where: bool) -> None: ...
def set_pipe_name(name: str) -> None: ...
13 changes: 6 additions & 7 deletions echion/coremodule.cc
Original file line number Diff line number Diff line change
Expand Up @@ -138,15 +138,13 @@ _sampler()

if (where)
{
auto pipe_name = std::filesystem::temp_directory_path() / ("echion-" + std::to_string(getpid()));
std::ofstream pipe(pipe_name, std::ios::out);
if (!pipe)
{
std::cerr << "Failed to open pipe " << pipe_name << std::endl;
return;
}

do_where(pipe);
if (pipe)
do_where(pipe);

else
std::cerr << "Failed to open pipe " << pipe_name << std::endl;

running = 0;

Expand Down Expand Up @@ -398,6 +396,7 @@ static PyMethodDef echion_core_methods[] = {
{"set_cpu", set_cpu, METH_VARARGS, "Set whether to use CPU time instead of wall time"},
{"set_native", set_native, METH_VARARGS, "Set whether to sample the native stacks"},
{"set_where", set_where, METH_VARARGS, "Set whether to use where mode"},
{"set_pipe_name", set_pipe_name, METH_VARARGS, "Set the pipe name"},
{NULL, NULL, 0, NULL} /* Sentinel */
};

Expand Down

0 comments on commit e6a06c5

Please sign in to comment.