1
0
mirror of https://github.com/rofl0r/proxychains-ng synced 2026-05-13 17:03:07 +08:00

Compare commits

..

8 Commits

  • configure: make buildsystem-set CPPFLAGS non-overridable
    we temporarily store all buildsystem-set conditionals into
    OUR_CPPFLAGS and write it into config.mak as an addition to eventually
    user-supplied CPPFLAGS. this should prevent crucial things we set from
    being overwritten by a user that has CPPFLAGS exported.
    
    fixes #142
  • Fix random_chain on Mac OS X
    On Mac OS X, random chain was broken and returned always the last proxy from the
    config file.  Use fix as suggested by @ravomavain.
    
    Closes #75.
  • configure: do not use mktemp
    apparently mktemp on OSX 10.9.5 requires a parameter.
    instead of playing whack-a-mole with apple we now use the portable
    code from musl's configure script which should work everywhere.
    
    adresses #142
  • Fix build failure with -pie in user LDFLAGS
    When hardening flags are set by Debian's auto build system,
    the project fails to build due to usage of -pie, which tells the linker
    to build a PIE binary, and since the user LDFLAGS are deliberately put
    later in the command line to override things, this overrides -shared.
    work around by putting it directly in the last position of the linker
    command line.
    
    closes #124
    Commit message authored by commiter.
  • Fix trivial compilation warning
    Fix "missing braces around initializer" warning.
  • don't call dlsym() from close() hook
    it turned out that calling dlsym() may call malloc() in turn,
    so we end up with the same deadlock described in the latest commit.
    
    we thus now put all the fds passed to close pre-init into a list
    and close them at init time.
    
    this may finally fix #119.
  • don't call INIT() from close hook
    it was observed that it is a bad idea to initialize the entire
    infrastructure used by proxychains from the close hook,
    because the following scenario will lead to a deadlock:
    
    - it is possible that the dynlinker executes the initializer code of
      other shared libs first
    - if that code directly or indirectly calls malloc()
    - which calls close() if it decided to use an mmap based allocation
    - will now call our close(), which does
    - call pthread_once which requires a lock
    - creates a thread which calls malloc()
    - which in turn calls our close() another time
    - and our close is still in locked state.
    
    so it seems the only save thing to do is to just get the address
    of the original close function, and call that when we're in a
    pre-init state.
    this may hold for other functions that do lazy initialization as well,
    however for those just calling the original function is probably
    undesired since that could result in unproxified connections.
    it will be needed to analyze on a per-function basis what the best
    thing to do is, and finally rely only on the execution of the init
    function from the gcc initializer.
    
    should fix #119
5 changed files with 44 additions and 19 deletions
+2 -2
View File
@@ -25,7 +25,7 @@ GENH = src/version.h
CFLAGS += -Wall -O0 -g -std=c99 -D_GNU_SOURCE -pipe
NO_AS_NEEDED = -Wl,--no-as-needed
LIBDL = -ldl
LDFLAGS = -shared -fPIC $(NO_AS_NEEDED) $(LIBDL) -lpthread
LDFLAGS = -fPIC $(NO_AS_NEEDED) $(LIBDL) -lpthread
INC =
PIC = -fPIC
AR = $(CROSS_COMPILE)ar
@@ -82,7 +82,7 @@ src/version.o: src/version.h
$(LDSO_PATHNAME): $(LOBJS)
$(CC) $(LDFLAGS) $(LD_SET_SONAME)$(LDSO_PATHNAME) $(USER_LDFLAGS) \
-o $@ $(LOBJS)
-shared -o $@ $(LOBJS)
$(ALL_TOOLS): $(OBJS)
$(CC) src/main.o src/common.o $(USER_LDFLAGS) -o $(PXCHAINS)
Vendored
+23 -13
View File
@@ -1,6 +1,18 @@
#!/bin/sh
prefix=/usr/local
OUR_CPPFLAGS=
# Get a temporary filename
i=0
set -C
while : ; do i=$(($i+1))
tmpc="./conf$$-$PPID-$i.c"
2>|/dev/null > "$tmpc" && break
test "$i" -gt 50 && fail "$0: cannot create temporary file $tmpc"
done
set +C
trap 'rm "$tmpc"' EXIT INT QUIT TERM HUP
ismac() {
uname -s | grep Darwin >/dev/null
@@ -20,14 +32,12 @@ isopenbsd() {
check_compile() {
printf "checking %s ... " "$1"
local tmp=$(mktemp)
printf "$3" > "$tmp".c
printf "$3" > "$tmpc"
local res=0
$CC $CPPFLAGS $2 $CFLAGS -c "$tmp".c -o "$tmp".o >/dev/null 2>&1 \
$CC $OUR_CPPFLAGS $CPPFLAGS $2 $CFLAGS -c "$tmpc" -o /dev/null >/dev/null 2>&1 \
|| res=1
rm -f "$tmp".c "$tmp".o
test x$res = x0 && \
{ printf "yes\n" ; test x"$2" = x || CPPFLAGS="$CPPFLAGS $2" ; } \
{ printf "yes\n" ; test x"$2" = x || OUR_CPPFLAGS="$OUR_CPPFLAGS $2" ; } \
|| printf "no\n"
return $res
}
@@ -35,20 +45,19 @@ check_compile() {
check_define() {
printf "checking whether \$CC defines %s ... " "$1"
local res=1
$CC $CPPFLAGS $CFLAGS -dM -E - </dev/null | grep "$1" >/dev/null && res=0
$CC $OUR_CPPFLAGS $CPPFLAGS $CFLAGS -dM -E - </dev/null | grep "$1" >/dev/null && res=0
test x$res = x0 && printf "yes\n" || printf "no\n"
return $res
}
check_compile_run() {
printf "checking %s ... " "$1"
local tmp=$(mktemp)
printf "$2" > "$tmp".c
printf "$2" > "$tmpc"
local res=0
$CC $CPPFLAGS $CFLAGS "$tmp".c -o "$tmp".out >/dev/null 2>&1 \
$CC $OUR_CPPFLAGS $CPPFLAGS $CFLAGS "$tmpc" -o "$tmpc".out >/dev/null 2>&1 \
|| res=1
test x$res = x0 && { "$tmp".out || res=1 ; }
rm -f "$tmp".c "$tmp".o "$tmp".out
test x$res = x0 && { "$tmpc".out || res=1 ; }
rm -f "$tmpc".out
test x$res = x0 && printf "yes\n" || printf "no\n"
return $res
}
@@ -135,7 +144,7 @@ check_compile 'whether netinet/in.h defines __u6_addr.__u6_addr16' \
check_define __OpenBSD__ && \
check_compile_run 'whether OpenBSDs fclose() (illegally) calls close()' \
'#include <stdio.h>\n#include<stdlib.h>\nint close(int x){exit(0);}int main(){fclose(stdin);return 1;}' && \
CPPFLAGS="$CPPFLAGS -DBROKEN_FCLOSE"
OUR_CPPFLAGS="$OUR_CPPFLAGS -DBROKEN_FCLOSE"
echo CC?=$CC>config.mak
[ -z "$CPPFLAGS" ] || echo CPPFLAGS?=$CPPFLAGS>>config.mak
@@ -147,7 +156,8 @@ echo bindir=$bindir>>config.mak
echo libdir=$libdir>>config.mak
echo includedir=$includedir>>config.mak
echo sysconfdir=$sysconfdir>>config.mak
[ "$ignore_cve" = "no" ] && echo CPPFLAGS+= -DSUPER_SECURE>>config.mak
[ "$ignore_cve" = "no" ] && echo "CPPFLAGS+= -DSUPER_SECURE">>config.mak
[ -z "$OUR_CPPFLAGS" ] || echo "CPPFLAGS+= $OUR_CPPFLAGS" >>config.mak
make_cmd=make
if ismac ; then
echo NO_AS_NEEDED=>>config.mak
+1 -1
View File
@@ -464,7 +464,7 @@ static proxy_data *select_proxy(select_type how, proxy_data * pd, unsigned int p
case RANDOMLY:
do {
k++;
i = 0 + (unsigned int) (proxy_count * 1.0 * rand() / (RAND_MAX + 1.0));
i = rand() % proxy_count;
} while(pd[i].ps != PLAY_STATE && k < proxy_count * 100);
break;
case FIFOLY:
+1 -1
View File
@@ -1,5 +1,5 @@
#include "ip_type.h"
const ip_type ip_type_invalid = { .addr.v4.as_int = -1 };
const ip_type ip_type_localhost = { .addr.v4 = {127, 0, 0, 1} };
const ip_type ip_type_localhost = { .addr.v4.octet = {127, 0, 0, 1} };
+17 -2
View File
@@ -93,7 +93,7 @@ static void* load_sym(char* symname, void* proxyfunc) {
#define INIT() init_lib_wrapper(__FUNCTION__)
#define SETUP_SYM(X) do { true_ ## X = load_sym( # X, X ); } while(0)
#define SETUP_SYM(X) do { if (! true_ ## X ) true_ ## X = load_sym( # X, X ); } while(0)
#include "allocator_thread.h"
@@ -110,6 +110,9 @@ static void setup_hooks(void) {
SETUP_SYM(close);
}
static int close_fds[16];
static int close_fds_cnt = 0;
static void do_init(void) {
srand(time(NULL));
core_initialize();
@@ -123,6 +126,8 @@ static void do_init(void) {
setup_hooks();
while(close_fds_cnt) true_close(close_fds[--close_fds_cnt]);
init_l = 1;
}
@@ -280,6 +285,10 @@ static void get_chain_data(proxy_data * pd, unsigned int *proxy_count, chain_typ
char *pc;
int len;
pc = strchr(buff, '=');
if(!pc) {
fprintf(stderr, "error: missing equals sign '=' in chain_len directive.\n");
exit(1);
}
len = atoi(++pc);
proxychains_max_chain = (len ? len : 1);
} else if(strstr(buff, "quiet_mode")) {
@@ -304,12 +313,18 @@ static void get_chain_data(proxy_data * pd, unsigned int *proxy_count, chain_typ
/******* HOOK FUNCTIONS *******/
int close(int fd) {
INIT();
if(!init_l) {
if(close_fds_cnt>=(sizeof close_fds/sizeof close_fds[0])) goto err;
close_fds[close_fds_cnt++] = fd;
errno = 0;
return 0;
}
/* prevent rude programs (like ssh) from closing our pipes */
if(fd != req_pipefd[0] && fd != req_pipefd[1] &&
fd != resp_pipefd[0] && fd != resp_pipefd[1]) {
return true_close(fd);
}
err:
errno = EBADF;
return -1;
}