Skip to content

Commit

Permalink
fddev: add debugging wrapper
Browse files Browse the repository at this point in the history
  • Loading branch information
mmcgee-jump committed Aug 18, 2023
1 parent 8abb52f commit d740266
Show file tree
Hide file tree
Showing 3 changed files with 153 additions and 0 deletions.
37 changes: 37 additions & 0 deletions .vscode/launch.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
{
"version": "0.2.0",
"configurations": [
{
"name": "fddev",
"type": "cppdbg",
"request": "launch",
"cwd": "${workspaceFolder}/build/native/gcc/bin",
"program": "${workspaceFolder}/build/native/gcc/bin/fddev",
"args": ["--no-sandbox"],
"miDebuggerPath": "${workspaceFolder}/build/native/gcc/bin/fddbg",
"MIMode": "gdb",
"setupCommands": [
{
"description": "Enable pretty-printing for gdb",
"text": "-enable-pretty-printing",
"ignoreFailures": true
},
{
"description": "Set Disassembly Flavor to Intel",
"text": "-gdb-set disassembly-flavor intel",
"ignoreFailures": true
},
{
"description": "Don't detach on fork",
"text": "-gdb-set detach-on-fork off",
"ignoreFailures": false
},
{
"description": "Stay parent after fork",
"text": "-gdb-set follow-fork-mode parent",
"ignoreFailures": false
}
]
}
]
}
3 changes: 3 additions & 0 deletions src/app/fddbg/Local.mk
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
ifdef FD_HAS_HOSTED
$(call make-bin,fddbg,main,fd_util)
endif
113 changes: 113 additions & 0 deletions src/app/fddbg/main.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,113 @@
#define _GNU_SOURCE

#include "../../util/fd_util.h"

#include <stdlib.h>
#include <unistd.h>
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include <sys/types.h>
#include <sys/prctl.h>
#include <sys/syscall.h>
#include <sys/xattr.h>
#include <sys/wait.h>
#include <linux/limits.h>
#include <linux/capability.h>

static int
has_all_capabilities( void ) {
struct __user_cap_header_struct capheader;
struct __user_cap_data_struct capdata[2];

capheader.version = _LINUX_CAPABILITY_VERSION_3;
capheader.pid = 0;
FD_TEST( syscall( SYS_capget, &capheader, &capdata ) >= 0 );
return
capdata[0].permitted == 0xFFFFFFFF &&
( capdata[1].permitted & 0x000001FF ) == 0x000001FF;
}

static void
raise_all_capabilities( void ) {
struct __user_cap_header_struct capheader;
struct __user_cap_data_struct capdata[2];

capheader.version = _LINUX_CAPABILITY_VERSION_3;
capheader.pid = 0;
FD_TEST( syscall( SYS_capget, &capheader, &capdata ) >= 0 );

capdata[0].effective = 0xFFFFFFFF;
capdata[0].inheritable = 0xFFFFFFFF;
capdata[1].effective = 0xFFFFFFFF;
capdata[1].inheritable = 0xFFFFFFFF;
FD_TEST( syscall(SYS_capset, &capheader, &capdata) >= 0 );

for ( int cap = 0; cap <= CAP_LAST_CAP; cap++ )
FD_TEST( !prctl(PR_CAP_AMBIENT, PR_CAP_AMBIENT_RAISE, cap, 0, 0) );
}

static void
self_exe( char * path ) {
long count = readlink( "/proc/self/exe", path, PATH_MAX );
FD_TEST( count >= 0 && count < PATH_MAX );
path[ count ] = '\0';
}

int
main( int argc,
char ** argv ) {
fd_boot( &argc, &argv );

for( int i=0; i<argc; i++ )
FD_LOG_NOTICE(( "argv[%d] = %s", i, argv[i] ));

if( FD_UNLIKELY( argc > 1 && !strcmp( argv[1], "--setcap" ) ) ) {
struct vfs_cap_data {
__le32 magic_etc; // Always set to VFS_CAP_REVISION_2
struct {
__le32 permitted; // Mask of permitted capabilities
__le32 inheritable; // Mask of inheritable capabilities
} data[2];
} cap_data;

cap_data.magic_etc = VFS_CAP_REVISION_2;
cap_data.data[0].permitted = 0xFFFFFFFF;
cap_data.data[0].inheritable = 0xFFFFFFFF;
cap_data.data[1].permitted = 0xFFFFFFFF;
cap_data.data[1].inheritable = 0xFFFFFFFF;

char self_path[ PATH_MAX ];
self_exe( self_path );
FD_TEST( !setxattr( self_path, "security.capability", &cap_data, sizeof(cap_data), 0) );
} else {
if( FD_UNLIKELY( !has_all_capabilities() ) ) {
if ( FD_UNLIKELY( argc > 1 && !strcmp( argv[1], "--withcap" ) ) ) FD_LOG_ERR(( "missing capabilities" ));

char self_path[ PATH_MAX ];
self_exe( self_path );

pid_t child = fork();
FD_TEST( child >= 0 );
if( child == 0 ) execv( "/bin/sudo", (char *[]){ "sudo", self_path, "--setcap", NULL } );
else {
int wstatus;
FD_TEST( waitpid( child, &wstatus, 0 ) >= 0 );
FD_TEST( WIFEXITED( wstatus ) && !WEXITSTATUS( wstatus ) );
char self_path[ PATH_MAX ];
self_exe( self_path );
FD_TEST( execv( self_path, (char *[]){ "fddbg", "--withcap", NULL } ) >= 0 );
}
} else {
raise_all_capabilities();

char * args[ 32 ];
int start = argc > 1 && !strcmp( argv[1], "--withcap" ) ? 2 : 1;
args[0] = "/bin/gdb";
for( int i=start; i<argc; i++ ) args[i-start+1] = argv[i];
args[ argc-start+1 ] = NULL;

FD_TEST( execv( "/bin/gdb", args ) >= 0 );
}
}
}

0 comments on commit d740266

Please sign in to comment.