]> git.rm.cloudns.org Git - xonotic/darkplaces.git/commitdiff
now also detect LD_PRELOAD and such stuff
authorRudolf Polzer <divverent@alientrap.org>
Mon, 4 Jun 2012 08:29:23 +0000 (10:29 +0200)
committerRudolf Polzer <divverent@alientrap.org>
Mon, 4 Jun 2012 08:29:23 +0000 (10:29 +0200)
sys_linux.c

index 4db3811c813eacf18307c8d97b5c0c8262581ad1..7cb28b6aa28de44945426210c9219eb60aa008f1 100644 (file)
@@ -153,59 +153,112 @@ void Sys_InitConsole (void)
 #  include <errno.h>
 # endif
 #endif
-static void anticheat_init(void)
+static void anticheat_init(char **envp)
 {
 #ifdef ANTICHEAT
 #define FAIL exit(42)
 
-       // anti ptrace; also, make a forked process copy to detach from debuggers
-# ifndef WIN32
-       pid_t pid = fork();
-       if(pid < 0)
-               FAIL;
-       if(pid == 0)
+       // anti LD_PRELOAD
+       // note that we're using envp here, so one doesn't simply hook into getenv()
+       static char *unsecure_envvars =
+               // UNSECURE_ENVVARS from glibc
+               "GCONV_PATH\0" // libraries are loaded from here
+               //"GETCONF_DIR\0" // harmless, can only fake getconf() output
+               //"HOSTALIASES\0" // harmless, just messes with DNS
+               "LD_AUDIT\0" // loads libraries
+               // "LD_DEBUG\0" // harmless, just shows data
+               // "LD_DEBUG_OUTPUT\0" // harmless, just shows data
+               "LD_DYNAMIC_WEAK\0" // changes name resolution
+               "LD_LIBRARY_PATH\0" // loads libraries
+               "LD_ORIGIN_PATH\0" // may load libraries
+               "LD_PRELOAD\0" // loads libraries
+               // "LD_PROFILE\0" // harmless, just creates profile
+               // "LD_SHOW_AUXV\0" // harmless, just shows data
+               // "LD_USE_LOAD_BIAS\0" // harmless
+               // "LOCALDOMAIN\0" // harmless, just messes with DNS
+               // "LOCPATH\0" // harmless, just messes with locales
+               // "MALLOC_TRACE\0" // harmless, just shows data
+               // "NIS_PATH\0" // harmless, just messes with DNS and user ID data
+               // "NLSPATH\0" // harmless, just messes with locales
+               // "RESOLV_HOST_CONF\0" // harmless, can cause private data to be printed from suid, but we're not suid
+               // "RES_OPTIONS\0" // harmless, just messes with DNS
+               // "TMPDIR\0" // harmless, we don't use temp files anyway
+               // "TZDIR\0" // harmless, just enables time travel
+               // EXTRA_UNSECURE_ENVVARS from glibc
+               "LD_AOUT_LIBRARY_PATH\0" // loads libraries
+               "LD_AOUT_PRELOAD\0" // loads libraries
+               ;
+
+       while(*envp)
        {
-               // nothing to do here
+               char *p = unsecure_envvars;
+               while(*p)
+               {
+                       char *q = envp[0];
+                       while(*p && *p == *q)
+                       {
+                               ++p;
+                               ++q;
+                       }
+                       if(*p == 0 && *q == '=')
+                               FAIL; // match!
+                       // next!
+                       while(*p)
+                               ++p;
+                       ++p;
+               }
+               ++envp;
        }
-       else
+
+       // anti ptrace; also, make a forked process copy to detach from debuggers
+# ifndef WIN32
        {
-               // parent
-               int status;
-               if(ptrace(PTRACE_ATTACH, pid, NULL, NULL) < 0)
-               {
-                       kill(pid, SIGKILL);
+               pid_t pid = fork();
+               if(pid < 0)
                        FAIL;
+               if(pid == 0)
+               {
+                       // nothing to do here
                }
-               for(;;)
+               else
                {
-                       if(waitpid(pid, &status, 0) == (pid_t) -1)
-                       {
-                               if(errno == ECHILD) // process no longer exists
-                                       FAIL;
-                       }
-                       if(WIFEXITED(status))
+                       // parent
+                       int status;
+                       if(ptrace(PTRACE_ATTACH, pid, NULL, NULL) < 0)
                        {
-                               exit(WEXITSTATUS(status));
+                               kill(pid, SIGKILL);
+                               FAIL;
                        }
-                       if(WIFSTOPPED(status))
+                       for(;;)
                        {
-                               printf("ptrace: continue... (signal: %d)\n", (int) WSTOPSIG(status));
-                               if(ptrace(PTRACE_CONT, pid, (void *) WSTOPSIG(status), NULL) < 0)
+                               if(waitpid(pid, &status, 0) == (pid_t) -1)
                                {
-                                       perror("okay.png");
+                                       if(errno == ECHILD) // process no longer exists
+                                               FAIL;
+                               }
+                               if(WIFEXITED(status))
+                               {
+                                       exit(WEXITSTATUS(status));
+                               }
+                               if(WIFSTOPPED(status))
+                               {
+                                       printf("ptrace: continue... (signal: %d)\n", (int) WSTOPSIG(status));
+                                       if(ptrace(PTRACE_CONT, pid, (void *) WSTOPSIG(status), NULL) < 0)
+                                       {
+                                               perror("okay.png");
+                                       }
                                }
                        }
+                       // never gonna get to here
                }
-               // never gonna get to here
        }
 # endif
-
 #endif
 }
 
-int main (int argc, char **argv)
+int main (int argc, char **argv, char **envp)
 {
-       anticheat_init();
+       anticheat_init(envp);
 
        signal(SIGFPE, SIG_IGN);