Skip to content

Commit

Permalink
Merge branch 'trace-sudo'
Browse files Browse the repository at this point in the history
  • Loading branch information
hmgle committed May 31, 2024
2 parents a18d303 + 8f330d3 commit 2fc9f8a
Show file tree
Hide file tree
Showing 4 changed files with 84 additions and 12 deletions.
7 changes: 7 additions & 0 deletions conf.c
Original file line number Diff line number Diff line change
Expand Up @@ -171,6 +171,7 @@ int conf_init(struct graftcp_conf *conf)
conf->blackip_file_path = NULL;
conf->whiteip_file_path = NULL;
conf->ignore_local = NULL;
conf->username = NULL;
return 0;
}

Expand Down Expand Up @@ -200,6 +201,10 @@ void conf_free(struct graftcp_conf *conf)
free(conf->ignore_local);
conf->ignore_local = NULL;
}
if (conf->username) {
free(conf->username);
conf->username = NULL;
}
}

static char *xdg_config_path_dup(void)
Expand Down Expand Up @@ -283,4 +288,6 @@ void conf_override(struct graftcp_conf *w, const struct graftcp_conf *r)
w->whiteip_file_path = r->whiteip_file_path;
if (r->ignore_local)
w->ignore_local = r->ignore_local;
if (r->username)
w->username = r->username;
}
1 change: 1 addition & 0 deletions conf.h
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ struct graftcp_conf {
char *blackip_file_path;
char *whiteip_file_path;
bool *ignore_local;
char *username;
};

typedef int (*config_cb)(const char *, const char *, struct graftcp_conf *);
Expand Down
83 changes: 71 additions & 12 deletions graftcp.c
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@
#include <stdio.h>
#include <getopt.h>
#include <stdlib.h>
#include <pwd.h>
#include <grp.h>
#include <linux/version.h>
#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 8, 0)
#define ENABLE_SECCOMP_BPF
Expand Down Expand Up @@ -47,6 +49,10 @@ int LOCAL_PIPE_FD;
cidr_trie_t *BLACKLIST_IP = NULL;
cidr_trie_t *WHITELACKLIST_IP = NULL;


static uid_t run_uid;
static gid_t run_gid;

static int exit_code = 0;

static void load_ip_file(char *path, cidr_trie_t **trie)
Expand Down Expand Up @@ -160,14 +166,28 @@ static void install_seccomp()
.len = (unsigned short)ARRAY_SIZE(filter),
.filter = filter,
};
if (prctl(PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0)) {
perror("prctl(PR_SET_NO_NEW_PRIVS)");
exit(errno);
}
if (prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, &prog)) {
perror("prctl(PR_SET_SECCOMP)");
exit(errno);
if (prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, &prog) == 0)
return;
if (errno == EACCES) {
/*
* https://www.kernel.org/doc/Documentation/prctl/no_new_privs.txt
* Filters installed for the seccomp mode 2 sandbox persist across
* execve and can change the behavior of newly-executed programs.
* Unprivileged users are therefore only allowed to install such filters
* if no_new_privs is set.
*/
if (prctl(PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0)) {
perror("prctl(PR_SET_NO_NEW_PRIVS)");
exit(errno);
}
if (prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, &prog)) {
perror("prctl(PR_SET_SECCOMP)");
exit(errno);
}
return;
}
perror("prctl(PR_SET_SECCOMP)");
exit(errno);
}
#endif

Expand Down Expand Up @@ -285,7 +305,7 @@ void socket_exiting_handle(struct proc_info *pinfp, int fd)
add_socket_info(si);
}

void do_child(int argc, char **argv)
void do_child(struct graftcp_conf *conf, int argc, char **argv)
{
char *args[argc + 1];
int i;
Expand All @@ -295,6 +315,22 @@ void do_child(int argc, char **argv)
args[i] = argv[i];
args[argc] = NULL;
ptrace(PTRACE_TRACEME, 0, NULL, NULL);
if (conf->username) {
if (initgroups(conf->username, run_gid) < 0) {
perror("initgroups");
exit(errno);
}

if (setregid(run_gid, run_gid) < 0) {
perror("setregid");
exit(errno);
}
if (setreuid(run_uid, run_uid) < 0) {
perror("setreuid");
exit(errno);
}
}

pid = getpid();
/*
* Induce a ptrace stop. Tracer (our parent)
Expand All @@ -308,7 +344,7 @@ void do_child(int argc, char **argv)
}
}

void init(int argc, char **argv)
void init(struct graftcp_conf *conf, int argc, char **argv)
{
pid_t child;
struct proc_info *pi;
Expand All @@ -321,7 +357,7 @@ void init(int argc, char **argv)
#ifdef ENABLE_SECCOMP_BPF
install_seccomp();
#endif
do_child(argc, argv);
do_child(conf, argc, argv);
}
pi = alloc_proc_info(child);
pi->flags |= FLAG_STARTUP;
Expand Down Expand Up @@ -495,6 +531,8 @@ static void usage(char **argv)
" -n --not-ignore-local\n"
" Connecting to local is not changed by default, this\n"
" option will redirect it to SOCKS5\n"
" -u --user=<username>\n"
" Run command as USERNAME handling setuid and/or setgid\n"
" -V --version\n"
" Show version\n"
" -h --help\n"
Expand All @@ -514,6 +552,7 @@ int client_main(int argc, char **argv)
{"local-fifo", required_argument, 0, 'f'},
{"blackip-file", required_argument, 0, 'b'},
{"whiteip-file", required_argument, 0, 'w'},
{"user", required_argument, 0, 'u'},
{"not-ignore-local", no_argument, 0, 'n'},
{0, 0, 0, 0}
};
Expand All @@ -525,6 +564,7 @@ int client_main(int argc, char **argv)
.blackip_file_path = NULL,
.whiteip_file_path = NULL,
.ignore_local = &DEFAULT_IGNORE_LOCAL,
.username = NULL,
};

__defer_free char *conf_file_path = NULL;
Expand All @@ -533,7 +573,7 @@ int client_main(int argc, char **argv)
conf_init(&file_conf);
conf_init(&cmd_conf);

while ((opt = getopt_long(argc, argv, "+Vha:p:f:b:w:c:n", long_opts,
while ((opt = getopt_long(argc, argv, "+Vha:p:f:b:w:c:u:n", long_opts,
&index)) != -1) {
switch (opt) {
case 'a':
Expand All @@ -559,6 +599,9 @@ int client_main(int argc, char **argv)
case 'c':
conf_file_path = strdup(optarg);
break;
case 'u':
cmd_conf.username = strdup(optarg);
break;
case 'V':
fprintf(stderr, "graftcp %s\n", VERSION);
exit(0);
Expand Down Expand Up @@ -609,7 +652,23 @@ int client_main(int argc, char **argv)
exit(errno);
}

init(argc - optind, argv + optind);
if (conf.username) {
struct passwd *pent;

if (getuid() != 0 || geteuid() != 0) {
fprintf(stderr, "You must be root to use the -u option\n");
exit(1);
}
pent = getpwnam(conf.username);
if (pent == NULL) {
fprintf(stderr, "Cannot find user '%s'\n", conf.username);
exit(1);
}
run_gid = pent->pw_gid;
run_uid = pent->pw_uid;
}

init(&conf, argc - optind, argv + optind);
if (do_trace() < 0)
return -1;
return exit_code;
Expand Down
5 changes: 5 additions & 0 deletions local/cmd/mgraftcp/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,7 @@ var (

blackIPFile string
whiteIPFile string
userName string
notIgnoreLocal bool
enableDebugLog bool

Expand All @@ -79,6 +80,7 @@ func init() {
getopt.FlagLong(&blackIPFile, "blackip-file", 'b', "The IP in black-ip-file will connect direct")
getopt.FlagLong(&whiteIPFile, "whiteip-file", 'w', "Only redirect the connect that destination ip in the white-ip-file to SOCKS5")
getopt.FlagLong(&notIgnoreLocal, "not-ignore-local", 'n', "Connecting to local is not changed by default, this option will redirect it to SOCKS5")
getopt.FlagLong(&userName, "username", 'u', "Run command as USERNAME handling setuid and/or setgid")
getopt.FlagLong(&help, "help", 'h', "Display this help and exit")
getopt.FlagLong(&showVersion, "version", 0, "Print the mgraftcp version information")
}
Expand Down Expand Up @@ -241,6 +243,9 @@ func main() {
if whiteIPFile != "" {
fixArgs = append(fixArgs, "-w", whiteIPFile)
}
if userName != "" {
fixArgs = append(fixArgs, "-u", userName)
}
if notIgnoreLocal {
fixArgs = append(fixArgs, "-n")
}
Expand Down

0 comments on commit 2fc9f8a

Please sign in to comment.