Skip to content

Commit

Permalink
Resolve relative paths
Browse files Browse the repository at this point in the history
  • Loading branch information
p-e-w committed May 8, 2016
1 parent 0e112a6 commit f411315
Show file tree
Hide file tree
Showing 8 changed files with 63 additions and 55 deletions.
15 changes: 15 additions & 0 deletions maybe/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,12 @@
# (https://gnu.org/licenses/gpl.html)


from os import readlink
from os.path import join
from collections import namedtuple

from blessings import Terminal
from ptrace.syscall.posix_arg import AT_FDCWD


SyscallFilter = namedtuple("SyscallFilter", ["syscall", "format", "substitute"])
Expand Down Expand Up @@ -38,3 +41,15 @@ def initialize_terminal(style_output):
"no": None,
"auto": False,
}[style_output])


# Implements the path resolution logic of the "*at" syscalls
def get_full_path(pid, path, directory_descriptor=AT_FDCWD):
if directory_descriptor == AT_FDCWD:
# Current working directory
directory = readlink("/proc/%d/cwd" % pid)
else:
# Directory referred to by directory_descriptor
directory = readlink("/proc/%d/fd/%d" % (pid, directory_descriptor))
# Note that join will discard directory if path is absolute, as desired
return join(directory, path)
11 changes: 5 additions & 6 deletions maybe/filters/change_owner.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,8 @@

from pwd import getpwuid
from grp import getgrgid
from os.path import abspath

from maybe import SyscallFilter, SYSCALL_FILTERS, T
from maybe import SyscallFilter, SYSCALL_FILTERS, T, get_full_path
from maybe.filters.create_write_file import get_file_descriptor_path


Expand All @@ -26,24 +25,24 @@ def format_change_owner(path, owner, group):
else:
label = "change owner"
owner = getpwuid(owner)[0] + ":" + getgrgid(group)[0]
return "%s of %s to %s" % (T.yellow(label), T.underline(abspath(path)), T.bold(owner))
return "%s of %s to %s" % (T.yellow(label), T.underline(path), T.bold(owner))


SYSCALL_FILTERS["change_owner"] = [
SyscallFilter(
syscall="chown",
format=lambda pid, args: format_change_owner(args[0], args[1], args[2]),
format=lambda pid, args: format_change_owner(get_full_path(pid, args[0]), args[1], args[2]),
),
SyscallFilter(
syscall="fchown",
format=lambda pid, args: format_change_owner(get_file_descriptor_path(args[0]), args[1], args[2]),
),
SyscallFilter(
syscall="lchown",
format=lambda pid, args: format_change_owner(args[0], args[1], args[2]),
format=lambda pid, args: format_change_owner(get_full_path(pid, args[0]), args[1], args[2]),
),
SyscallFilter(
syscall="fchownat",
format=lambda pid, args: format_change_owner(args[1], args[2], args[3]),
format=lambda pid, args: format_change_owner(get_full_path(pid, args[1], args[0]), args[2], args[3]),
),
]
10 changes: 4 additions & 6 deletions maybe/filters/change_permissions.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,7 @@
# (https://gnu.org/licenses/gpl.html)


from os.path import abspath

from maybe import SyscallFilter, SYSCALL_FILTERS, T
from maybe import SyscallFilter, SYSCALL_FILTERS, T, get_full_path
from maybe.filters.create_write_file import get_file_descriptor_path


Expand All @@ -24,21 +22,21 @@ def format_permissions(permissions):


def format_change_permissions(path, permissions):
return "%s of %s to %s" % (T.yellow("change permissions"), T.underline(abspath(path)),
return "%s of %s to %s" % (T.yellow("change permissions"), T.underline(path),
T.bold(format_permissions(permissions)))


SYSCALL_FILTERS["change_permissions"] = [
SyscallFilter(
syscall="chmod",
format=lambda pid, args: format_change_permissions(args[0], args[1]),
format=lambda pid, args: format_change_permissions(get_full_path(pid, args[0]), args[1]),
),
SyscallFilter(
syscall="fchmod",
format=lambda pid, args: format_change_permissions(get_file_descriptor_path(args[0]), args[1]),
),
SyscallFilter(
syscall="fchmodat",
format=lambda pid, args: format_change_permissions(args[1], args[2]),
format=lambda pid, args: format_change_permissions(get_full_path(pid, args[1], args[0]), args[2]),
),
]
10 changes: 4 additions & 6 deletions maybe/filters/create_directory.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,22 +8,20 @@
# (https://gnu.org/licenses/gpl.html)


from os.path import abspath

from maybe import SyscallFilter, SYSCALL_FILTERS, T
from maybe import SyscallFilter, SYSCALL_FILTERS, T, get_full_path


def format_create_directory(path):
return "%s %s" % (T.cyan("create directory"), T.underline(abspath(path)))
return "%s %s" % (T.cyan("create directory"), T.underline(path))


SYSCALL_FILTERS["create_directory"] = [
SyscallFilter(
syscall="mkdir",
format=lambda pid, args: format_create_directory(args[0]),
format=lambda pid, args: format_create_directory(get_full_path(pid, args[0])),
),
SyscallFilter(
syscall="mkdirat",
format=lambda pid, args: format_create_directory(args[1]),
format=lambda pid, args: format_create_directory(get_full_path(pid, args[1], args[0])),
),
]
18 changes: 10 additions & 8 deletions maybe/filters/create_link.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,31 +8,33 @@
# (https://gnu.org/licenses/gpl.html)


from os.path import abspath

from maybe import SyscallFilter, SYSCALL_FILTERS, T
from maybe import SyscallFilter, SYSCALL_FILTERS, T, get_full_path


def format_create_link(path_source, path_target, symbolic):
label = "create symbolic link" if symbolic else "create hard link"
return "%s from %s to %s" % (T.cyan(label), T.underline(abspath(path_source)), T.underline(abspath(path_target)))
return "%s from %s to %s" % (T.cyan(label), T.underline(path_source), T.underline(path_target))


SYSCALL_FILTERS["create_link"] = [
SyscallFilter(
syscall="link",
format=lambda pid, args: format_create_link(args[1], args[0], False),
format=lambda pid, args: format_create_link(get_full_path(pid, args[1]),
get_full_path(pid, args[0]), False),
),
SyscallFilter(
syscall="linkat",
format=lambda pid, args: format_create_link(args[3], args[1], False),
format=lambda pid, args: format_create_link(get_full_path(pid, args[3], args[2]),
get_full_path(pid, args[1], args[0]), False),
),
SyscallFilter(
syscall="symlink",
format=lambda pid, args: format_create_link(args[1], args[0], True),
format=lambda pid, args: format_create_link(get_full_path(pid, args[1]),
get_full_path(pid, args[0]), True),
),
SyscallFilter(
syscall="symlinkat",
format=lambda pid, args: format_create_link(args[2], args[0], True),
format=lambda pid, args: format_create_link(get_full_path(pid, args[2], args[1]),
get_full_path(pid, args[0]), True),
),
]
27 changes: 12 additions & 15 deletions maybe/filters/create_write_file.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,11 @@
# (https://gnu.org/licenses/gpl.html)


from os.path import abspath, exists
from os.path import exists
from os import O_WRONLY, O_RDWR, O_APPEND, O_CREAT, O_TRUNC
from stat import S_IFCHR, S_IFBLK, S_IFIFO, S_IFSOCK

from maybe import SyscallFilter, SYSCALL_FILTERS, T
from maybe import SyscallFilter, SYSCALL_FILTERS, T, get_full_path


# Start with a large number to avoid collisions with other FDs
Expand All @@ -36,7 +36,6 @@ def get_file_descriptor_path(file_descriptor):


def format_open(path, flags):
path = abspath(path)
if path in allowed_files:
return None
elif (flags & O_CREAT) and not exists(path):
Expand All @@ -48,7 +47,6 @@ def format_open(path, flags):


def substitute_open(path, flags):
path = abspath(path)
if path in allowed_files:
return None
elif (flags & O_WRONLY) or (flags & O_RDWR) or (flags & O_APPEND) or (format_open(path, flags) is not None):
Expand All @@ -61,7 +59,6 @@ def substitute_open(path, flags):


def format_mknod(path, type):
path = abspath(path)
if exists(path):
return None
elif (type & S_IFCHR):
Expand Down Expand Up @@ -108,28 +105,28 @@ def substitute_dup(file_descriptor_old, file_descriptor_new=None):
SYSCALL_FILTERS["create_write_file"] = [
SyscallFilter(
syscall="open",
format=lambda pid, args: format_open(args[0], args[1]),
substitute=lambda pid, args: substitute_open(args[0], args[1]),
format=lambda pid, args: format_open(get_full_path(pid, args[0]), args[1]),
substitute=lambda pid, args: substitute_open(get_full_path(pid, args[0]), args[1]),
),
SyscallFilter(
syscall="creat",
format=lambda pid, args: format_open(args[0], O_CREAT | O_WRONLY | O_TRUNC),
substitute=lambda pid, args: substitute_open(args[0], O_CREAT | O_WRONLY | O_TRUNC),
format=lambda pid, args: format_open(get_full_path(pid, args[0]), O_CREAT | O_WRONLY | O_TRUNC),
substitute=lambda pid, args: substitute_open(get_full_path(pid, args[0]), O_CREAT | O_WRONLY | O_TRUNC),
),
SyscallFilter(
syscall="openat",
format=lambda pid, args: format_open(args[1], args[2]),
substitute=lambda pid, args: substitute_open(args[1], args[2]),
format=lambda pid, args: format_open(get_full_path(pid, args[1], args[0]), args[2]),
substitute=lambda pid, args: substitute_open(get_full_path(pid, args[1], args[0]), args[2]),
),
SyscallFilter(
syscall="mknod",
format=lambda pid, args: format_mknod(args[0], args[1]),
substitute=lambda pid, args: substitute_mknod(args[0], args[1]),
format=lambda pid, args: format_mknod(get_full_path(pid, args[0]), args[1]),
substitute=lambda pid, args: substitute_mknod(get_full_path(pid, args[0]), args[1]),
),
SyscallFilter(
syscall="mknodat",
format=lambda pid, args: format_mknod(args[1], args[2]),
substitute=lambda pid, args: substitute_mknod(args[1], args[2]),
format=lambda pid, args: format_mknod(get_full_path(pid, args[1], args[0]), args[2]),
substitute=lambda pid, args: substitute_mknod(get_full_path(pid, args[1], args[0]), args[2]),
),
SyscallFilter(
syscall="write",
Expand Down
12 changes: 5 additions & 7 deletions maybe/filters/delete.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,26 +8,24 @@
# (https://gnu.org/licenses/gpl.html)


from os.path import abspath

from maybe import SyscallFilter, SYSCALL_FILTERS, T
from maybe import SyscallFilter, SYSCALL_FILTERS, T, get_full_path


def format_delete(path):
return "%s %s" % (T.red("delete"), T.underline(abspath(path)))
return "%s %s" % (T.red("delete"), T.underline(path))


SYSCALL_FILTERS["delete"] = [
SyscallFilter(
syscall="unlink",
format=lambda pid, args: format_delete(args[0]),
format=lambda pid, args: format_delete(get_full_path(pid, args[0])),
),
SyscallFilter(
syscall="unlinkat",
format=lambda pid, args: format_delete(args[1]),
format=lambda pid, args: format_delete(get_full_path(pid, args[1], args[0])),
),
SyscallFilter(
syscall="rmdir",
format=lambda pid, args: format_delete(args[0]),
format=lambda pid, args: format_delete(get_full_path(pid, args[0])),
),
]
15 changes: 8 additions & 7 deletions maybe/filters/move.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,14 +8,12 @@
# (https://gnu.org/licenses/gpl.html)


from os.path import abspath, dirname, basename
from os.path import dirname, basename

from maybe import SyscallFilter, SYSCALL_FILTERS, T
from maybe import SyscallFilter, SYSCALL_FILTERS, T, get_full_path


def format_move(path_old, path_new):
path_old = abspath(path_old)
path_new = abspath(path_new)
if dirname(path_old) == dirname(path_new):
label = "rename"
path_new = basename(path_new)
Expand All @@ -27,14 +25,17 @@ def format_move(path_old, path_new):
SYSCALL_FILTERS["move"] = [
SyscallFilter(
syscall="rename",
format=lambda pid, args: format_move(args[0], args[1]),
format=lambda pid, args: format_move(get_full_path(pid, args[0]),
get_full_path(pid, args[1])),
),
SyscallFilter(
syscall="renameat",
format=lambda pid, args: format_move(args[1], args[3]),
format=lambda pid, args: format_move(get_full_path(pid, args[1], args[0]),
get_full_path(pid, args[3], args[2])),
),
SyscallFilter(
syscall="renameat2",
format=lambda pid, args: format_move(args[1], args[3]),
format=lambda pid, args: format_move(get_full_path(pid, args[1], args[0]),
get_full_path(pid, args[3], args[2])),
),
]

0 comments on commit f411315

Please sign in to comment.