Skip to content

Commit

Permalink
improvement
Browse files Browse the repository at this point in the history
  • Loading branch information
mildred committed Dec 14, 2023
1 parent 0f862c2 commit 3ef278c
Show file tree
Hide file tree
Showing 2 changed files with 26 additions and 10 deletions.
15 changes: 8 additions & 7 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -35,16 +35,17 @@ This is still a young project. Don't hesitate to report bugs or submit fixes.
Known bugs
----------

- ptrace can mess up and can make syscalls return -ENOSYS (no implemented)
- if the process close a systemd activated socket and opens a new socket on the
same file descriptor number that is not catched by force-bind, then the
subsequent listen() calls will be skipped
- security issue: the target process could bypass the force-bind policy using a
race condition when replacing the network address. If timed correctly, it can
bind an otherwise forbidden address. Can be solved with pidfd_getfd.
- When the file descriptors are not passed by systemd (the service is started
while the socket was not active for example), force-bind should let the
process bind() and listen() normally
- security issue: the target process could bypass the force-bind policy using a
race condition when replacing the network address. If timed correctly, it can
bind an otherwise forbidden address. Can be solved with pidfd_getfd.
- when using `-L` flag and if the process close a systemd activated socket and
opens a new socket on the same file descriptor number that is not catched by
force-bind, then the subsequent listen() calls will be skipped
- ptrace can mess up and can make syscalls return -ENOSYS (no implemented).
Workaround is not to use `-p` flag and rely on seccomp user notif instead.

TODO:

Expand Down
21 changes: 18 additions & 3 deletions main.c
Original file line number Diff line number Diff line change
Expand Up @@ -126,6 +126,7 @@ struct mapping {

struct cmdLineOpts {
bool require_ptrace;
bool prevent_listen;
bool debug;
bool quiet;
bool verbose;
Expand Down Expand Up @@ -411,7 +412,7 @@ watchForNotifications(int notifyFd, struct cmdLineOpts *opts)
resp->error = 0;
resp->flags = SECCOMP_USER_NOTIF_FLAG_CONTINUE;

if(rfd) {
if(opts->prevent_listen && rfd) {
// Ignore syscall
resp->flags = 0;
if(opts->verbose) printf("force-bind: ignore listen(%d, %d)\n", req->data.args[0], req->data.args[1]);
Expand Down Expand Up @@ -880,7 +881,7 @@ process_ptrace(pid_t target, struct cmdLineOpts *opts) {
if(rfd->fd == fd) break;
rfd = rfd->next;
}
if(rfd) {
if(opts->prevent_listen && rfd) {
// ignore listen syscall
if(opts->debug) printf("Tracer: listen(%d, %d), ignoring\n", fd, regs.rsi);
// first change syscall number to -1 (invalid) and run
Expand Down Expand Up @@ -1260,10 +1261,12 @@ usageError(char *msg, char *pname)
" -m MATCH=ADDR Replace bind() matching first MATCH with ADDR\n"
" -b ADDR Replace all bind() with ADDR (if same family)\n"
" -d Deny all bind()\n"
" -p Force seccomp-ptrace instead of only seccomp\n"
" -D Debug messages\n"
" -v Verbose\n"
" -q Quiet\n"
" -L Block listen(2) for fd-N or sd-N sockets\n"
" -p Force seccomp-ptrace instead of seccomp user notif\n"
" (might not work very well)\n"
"\n"
"Last rules (-m, -b, -d) are applied first so you can put your general policy\n"
"first on your command-line and any following argument can override it.\n"
Expand Down Expand Up @@ -1304,6 +1307,14 @@ usageError(char *msg, char *pname)
"\n"
" Replace any bind to port 80 using first socket from systemd socket\n"
" activation. Any port 81 is replaced by passed file descriptor 4.\n"
"\n"
"Limitations:\n"
"\n"
" When replacing a socket with an existing file descriptor (by fd number\n"
" or using systemd socket activation) and -L flag is used, then all\n"
" listen() syscalls on that file descriptor will be ignored. Than can\n"
" cause bugs if the file descriptor number is reused (listen calls will\n"
" still be blocked).\n"
"\n");
#ifdef VERSION
fprintf(stderr, "\nVersion: %s\n", VERSION);
Expand All @@ -1321,6 +1332,7 @@ parseCommandLineOptions(int argc, char *argv[], struct cmdLineOpts *opts)
opts->debug = false;
opts->map = NULL;
opts->require_ptrace = false;
opts->prevent_listen = false;

int i;
for(i = 1; argv[i]; i++){
Expand All @@ -1334,6 +1346,9 @@ parseCommandLineOptions(int argc, char *argv[], struct cmdLineOpts *opts)
} else if(!strcmp("-d", arg)) { /* Deny */
opts->map = parseMap(NULL, opts->map, opts, false);

} else if(!strcmp("-L", arg)) { /* block listen */
opts->prevent_listen = true;

} else if(!strcmp("-p", arg)) { /* Ptrace */
opts->require_ptrace = true;

Expand Down

0 comments on commit 3ef278c

Please # to comment.