Gentoo Websites Logo
Go to: Gentoo Home Documentation Forums Lists Bugs Planet Store Wiki Get Gentoo!
View | Details | Raw Unified | Return to bug 3141 | Differences between
and this patch

Collapse All | Expand All

(-)libsandbox.c.orig (-15 / +132 lines)
Lines 8-13 Link Here
8
 *
8
 *
9
 *  it's very important that the --enable-static-link option is NOT specified
9
 *  it's very important that the --enable-static-link option is NOT specified
10
 *
10
 *
11
 *  To use, you need to set environment variables:
12
 *  SANDBOX_ON          If this is set, it turns on sandboxing
13
 *  SANDBOX_LOG         The log file used for reporting violations.
14
 *                      Sandbox writes to stderr if not set.
15
 *  SANDBOX_DEBUG       Turn on sandbox debugging, so you know what it did
16
 *  SANDBOX_DEBUG_LOG   Logfile for debugging, stderr if not set
17
 *  SANDBOX_TRACE       Turn on tracing, listing all interesting files read
18
 *  SANDBOX_TRACE_LOG   Logfile for the above, needs to be set to work
19
 *
20
 *  These take path prefixes separated by ':' :
21
 *  SANDBOX_DENY        Deny access to the listed prefixes
22
 *  SANDBOX_READ        Allow reads from these prefixes. Normally set to "/"
23
 *  SANDBOX_WRITE       Allow write access to these prefixes
24
 *  SANDBOX_PREDICT     Dunno really. Something with error logging.
25
 *
26
 *  Notes:
27
 *  - the above just do sandboxing, the regular access permissions still apply.
28
 *
29
 *  - sandbox works by messing with libc. If you have applications that call
30
 *    the kernel directly (like dietlibc?), it won't work. This means that
31
 *    malicious code could still be executed. Which is why the portage user is
32
 *    a good idea.
33
 *
34
 *  - using sandbox is faster than something based on ptrace(), which would
35
 *    not have the above problem. Easily checked by comparing the difference
36
 *    between
37
 *    # time FEATURES=-sandbox strace -f -e\!all emerge blabla
38
 *    and
39
 *    # time emerge blabla
40
 *
41
 *  - If we want total security, maybe something like the systrace patch
42
 *    (http://www.systrace.org) would be better, although that only exists
43
 *    for the Linux kernel.
44
 *
11
 *  Copyright (C) 2001 Geert Bevin, Uwyn, http://www.uwyn.com
45
 *  Copyright (C) 2001 Geert Bevin, Uwyn, http://www.uwyn.com
12
 *  Distributed under the terms of the GNU General Public License, v2 or later 
46
 *  Distributed under the terms of the GNU General Public License, v2 or later 
13
 *  Author : Geert Bevin <gbevin@uwyn.com>
47
 *  Author : Geert Bevin <gbevin@uwyn.com>
Lines 21-26 Link Here
21
 *
55
 *
22
 *    Martin Schlemmer <azarah@gentoo.org> (18 Aug 2002)
56
 *    Martin Schlemmer <azarah@gentoo.org> (18 Aug 2002)
23
 *
57
 *
58
 *    Added logging for opened files in the forbidden zone, thus knowing
59
 *    what packages were used, see bug #3141
60
 *
61
 *    Removed unused write_denied structures
62
 *
63
 *    Added docs for libsandbox
64
 *
65
 *    Wout Mertens <wmertens@gentoo.org> (13 May 2003)
66
 *
24
 *  Partly Copyright (C) 1998-9 Pancrazio `Ezio' de Mauro <p@demauro.net>,
67
 *  Partly Copyright (C) 1998-9 Pancrazio `Ezio' de Mauro <p@demauro.net>,
25
 *  as some of the InstallWatch code was used.
68
 *  as some of the InstallWatch code was used.
26
 *
69
 *
Lines 105-112 Link Here
105
  int num_write_prefixes;
148
  int num_write_prefixes;
106
  char** predict_prefixes;
149
  char** predict_prefixes;
107
  int num_predict_prefixes;
150
  int num_predict_prefixes;
108
  char** write_denied_prefixes;
109
  int num_write_denied_prefixes;
110
} sbcontext_t;
151
} sbcontext_t;
111
152
112
/* glibc modified realpath() functions */
153
/* glibc modified realpath() functions */
Lines 714-721 Link Here
714
  context->num_write_prefixes = 0;
755
  context->num_write_prefixes = 0;
715
  context->predict_prefixes = NULL;
756
  context->predict_prefixes = NULL;
716
  context->num_predict_prefixes = 0;
757
  context->num_predict_prefixes = 0;
717
  context->write_denied_prefixes = NULL;
718
  context->num_write_denied_prefixes = 0;
719
}
758
}
720
759
721
static int is_sandbox_pid()
760
static int is_sandbox_pid()
Lines 932-948 Link Here
932
              ) {
971
              ) {
933
        struct stat tmp_stat;
972
        struct stat tmp_stat;
934
973
935
        for (i = 0; i < sbcontext->num_write_denied_prefixes; i++) {
936
          if (NULL != sbcontext->write_denied_prefixes[i]) {
937
            if (0 == strncmp(filtered_path,
938
                             sbcontext->write_denied_prefixes[i],
939
                             strlen(sbcontext->write_denied_prefixes[i]))) {
940
              result = 0;
941
              break;
942
            }
943
          }
944
        }
945
946
        if (-1 == result) {
974
        if (-1 == result) {
947
          for (i = 0; i < sbcontext->num_write_prefixes; i++) {
975
          for (i = 0; i < sbcontext->num_write_prefixes; i++) {
948
            if (NULL != sbcontext->write_prefixes[i]) {
976
            if (NULL != sbcontext->write_prefixes[i]) {
Lines 995-1000 Link Here
995
  return result;
1023
  return result;
996
}
1024
}
997
1025
1026
/* We define as interesting: */
1027
/* All files that we don't have write access to and are reading from */
1028
static int is_interesting(sbcontext_t* sbcontext, const char* func, const char* path)
1029
{
1030
  int result = -1;
1031
  int i = 0;
1032
  char* filtered_path = filter_path(path);
1033
1034
  if ('/' != filtered_path[0]) {
1035
    return 0;
1036
  }
1037
1038
  if ((0 == strncmp(filtered_path, "/etc/ld.so.preload", 18)) && (is_sandbox_pid())) {
1039
    result = 0;
1040
  }
1041
   
1042
  if (-1 == result) {
1043
    /* These are the functions we care about */
1044
    if ((NULL != sbcontext->write_prefixes) &&
1045
        ((0 == strncmp(func, "open_rd", 7)) ||
1046
         (0 == strncmp(func, "popen", 5)) ||
1047
         (0 == strncmp(func, "system", 6)) ||
1048
         (0 == strncmp(func, "execl", 5)) ||
1049
         (0 == strncmp(func, "execlp", 6)) ||
1050
         (0 == strncmp(func, "execle", 6)) ||
1051
         (0 == strncmp(func, "execv", 5)) ||
1052
         (0 == strncmp(func, "execvp", 6)) ||
1053
         (0 == strncmp(func, "execve", 6))
1054
        )
1055
       ) {
1056
      /* See if we are allowed to write to it */
1057
      for (i = 0; i < sbcontext->num_write_prefixes; i++) {
1058
        if (NULL != sbcontext->write_prefixes[i]) {
1059
          if (0 == strncmp(filtered_path,
1060
                           sbcontext->write_prefixes[i],
1061
                           strlen(sbcontext->write_prefixes[i]))) {
1062
            result = 0;
1063
            break;
1064
          }
1065
        }
1066
      }
1067
      /* All the rest is interesting */
1068
      if (-1 == result) {
1069
        result = 1;
1070
      }
1071
    }
1072
  }
1073
   
1074
  if (-1 == result) {
1075
    result = 0;
1076
  }
1077
1078
  if (filtered_path) free(filtered_path);
1079
  filtered_path = NULL;
1080
1081
  return result;
1082
}
1083
998
static int check_syscall(sbcontext_t* sbcontext, const char* func, const char* file)
1084
static int check_syscall(sbcontext_t* sbcontext, const char* func, const char* file)
999
{
1085
{
1000
  int old_errno = errno;
1086
  int old_errno = errno;
Lines 1008-1013 Link Here
1008
  char* debug_log_env = NULL;
1094
  char* debug_log_env = NULL;
1009
  char* debug_log_path = NULL;
1095
  char* debug_log_path = NULL;
1010
  int debug_log_file = 0;
1096
  int debug_log_file = 0;
1097
  struct stat trace_log_stat;
1098
  char* trace_log_env = NULL;
1099
  char* trace_log_path = NULL;
1100
  int trace_log_file = 0;
1011
  char buffer[512];
1101
  char buffer[512];
1012
1102
1013
  init_wrappers();
1103
  init_wrappers();
Lines 1027-1032 Link Here
1027
  log_path = getenv("SANDBOX_LOG");
1117
  log_path = getenv("SANDBOX_LOG");
1028
  debug_log_env = getenv("SANDBOX_DEBUG");
1118
  debug_log_env = getenv("SANDBOX_DEBUG");
1029
  debug_log_path = getenv("SANDBOX_DEBUG_LOG");
1119
  debug_log_path = getenv("SANDBOX_DEBUG_LOG");
1120
  trace_log_env = getenv("SANDBOX_TRACE");
1121
  trace_log_path = getenv("SANDBOX_TRACE_LOG");
1030
   
1122
   
1031
  if (((NULL == log_path) ||
1123
  if (((NULL == log_path) ||
1032
       (0 != strncmp(absolute_path, log_path, strlen(log_path)))) &&
1124
       (0 != strncmp(absolute_path, log_path, strlen(log_path)))) &&
Lines 1089-1094 Link Here
1089
    }
1181
    }
1090
  }
1182
  }
1091
1183
1184
  /* Save the path if tracing and it's interesting enough */
1185
  if ( (NULL != trace_log_env) &&
1186
       (NULL != trace_log_path) &&
1187
       (0 != strncmp(absolute_path, trace_log_path, strlen(trace_log_path))) &&
1188
       is_interesting(sbcontext, func, absolute_path)
1189
     ) {
1190
    sprintf(buffer, "%s\n", absolute_path);
1191
    
1192
    if ((0 == lstat(trace_log_path, &trace_log_stat)) &&
1193
        (0 == S_ISREG(trace_log_stat.st_mode))
1194
       ) {
1195
      fprintf(stderr,
1196
              "\e[31;01mSECURITY BREACH\033[0m  %s already exists and is not a regular file.\n",
1197
              log_path);
1198
    } else {
1199
      trace_log_file = true_open(trace_log_path,
1200
                                 O_APPEND | O_WRONLY | O_CREAT,
1201
                                 S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
1202
      if(trace_log_file >= 0) {
1203
        write(trace_log_file, buffer, strlen(buffer));
1204
        close(trace_log_file);
1205
      }
1206
    }
1207
  }
1208
1092
  if (absolute_path) free(absolute_path);
1209
  if (absolute_path) free(absolute_path);
1093
  absolute_path = NULL;
1210
  absolute_path = NULL;
1094
1211

Return to bug 3141