Gentoo Websites Logo
Go to: Gentoo Home Documentation Forums Lists Bugs Planet Store Wiki Get Gentoo!
View | Details | Raw Unified | Return to bug 233
Collapse All | Expand All

(-)libsandbox.c (-128 / +133 lines)
Lines 1-5 Link Here
1
/*
1
/*
2
S *  Path sandbox for the gentoo linux portage package system, initially
2
 *  Path sandbox for the gentoo linux portage package system, initially
3
 *  based on the ROCK Linux Wrapper for getting a list of created files
3
 *  based on the ROCK Linux Wrapper for getting a list of created files
4
 *
4
 *
5
 *  to integrate with bash, bash should have been built like this
5
 *  to integrate with bash, bash should have been built like this
Lines 33-42 Link Here
33
 * This is broken currently. */
33
 * This is broken currently. */
34
/* #define WRAP_MKNOD */
34
/* #define WRAP_MKNOD */
35
35
36
/* Uncomment below to enable the use of strtok_r(). */
37
#define REENTRANT_STRTOK
38
36
39
40
#define open   xxx_open
37
#define open   xxx_open
41
#define open64 xxx_open64
38
#define open64 xxx_open64
42
39
Lines 96-112 Link Here
96
static char sandbox_lib[255];
93
static char sandbox_lib[255];
97
94
98
typedef struct {
95
typedef struct {
96
        char *last_env;
97
        int count;
98
        char **strs;
99
} sbprefix_t;
100
101
typedef struct {
99
  int show_access_violation;
102
  int show_access_violation;
100
  char** deny_prefixes;
103
  sbprefix_t deny;
101
  int num_deny_prefixes;
104
  sbprefix_t read;
102
  char** read_prefixes;
105
  sbprefix_t write;
103
  int num_read_prefixes;
106
  sbprefix_t predict;
104
  char** write_prefixes;
105
  int num_write_prefixes;
106
  char** predict_prefixes;
107
  int num_predict_prefixes;
108
  char** write_denied_prefixes;
109
  int num_write_denied_prefixes;
110
} sbcontext_t;
107
} sbcontext_t;
111
108
112
/* glibc modified realpath() functions */
109
/* glibc modified realpath() functions */
Lines 120-128 Link Here
120
static int before_syscall(const char *, const char *);
117
static int before_syscall(const char *, const char *);
121
static int before_syscall_open_int(const char *, const char *, int);
118
static int before_syscall_open_int(const char *, const char *, int);
122
static int before_syscall_open_char(const char *, const char *, const char *);
119
static int before_syscall_open_char(const char *, const char *, const char *);
123
static void clean_env_entries(char ***, int *);
120
static void clean_env_entries(sbprefix_t *);
124
static void init_context(sbcontext_t *);
121
static void init_context(sbcontext_t *);
125
static void init_env_entries(char ***, int *, char *, int);
122
static void init_env_entries(sbprefix_t *, char *);
126
static char* filter_path(const char*);
123
static char* filter_path(const char*);
127
static int is_sandbox_on();
124
static int is_sandbox_on();
128
static int is_sandbox_pid();
125
static int is_sandbox_pid();
Lines 245-251 Link Here
245
242
246
  /* If path == NULL, return or we get a segfault */
243
  /* If path == NULL, return or we get a segfault */
247
  if (NULL == path) return;
244
  if (NULL == path) return;
248
  
245
249
  if(!erealpath(path, resolved_path) && (path[0] != '/')) {
246
  if(!erealpath(path, resolved_path) && (path[0] != '/')) {
250
    /* The path could not be canonicalized, append it
247
    /* The path could not be canonicalized, append it
251
     * to the current working directory if it was not
248
     * to the current working directory if it was not
Lines 253-259 Link Here
253
     */
250
     */
254
    getcwd(resolved_path, MAXPATHLEN - 2);
251
    getcwd(resolved_path, MAXPATHLEN - 2);
255
    strcat(resolved_path, "/");
252
    strcat(resolved_path, "/");
256
    strncat(resolved_path, path, MAXPATHLEN - 1);
253
    strncat(resolved_path, path, MAXPATHLEN - 1 - strlen(resolved_path));
257
    erealpath(resolved_path, resolved_path);
254
    erealpath(resolved_path, resolved_path);
258
  }
255
  }
259
256
Lines 705-721 Link Here
705
702
706
static void init_context(sbcontext_t* context)
703
static void init_context(sbcontext_t* context)
707
{
704
{
705
  memset(context, 0, sizeof(sbcontext_t));
708
  context->show_access_violation = 1;
706
  context->show_access_violation = 1;
709
  context->deny_prefixes = NULL;
710
  context->num_deny_prefixes = 0;
711
  context->read_prefixes = NULL;
712
  context->num_read_prefixes = 0;
713
  context->write_prefixes = NULL;
714
  context->num_write_prefixes = 0;
715
  context->predict_prefixes = NULL;
716
  context->num_predict_prefixes = 0;
717
  context->write_denied_prefixes = NULL;
718
  context->num_write_denied_prefixes = 0;
719
}
707
}
720
708
721
static int is_sandbox_pid()
709
static int is_sandbox_pid()
Lines 762-788 Link Here
762
  return result;
750
  return result;
763
}
751
}
764
752
765
static void clean_env_entries(char*** prefixes_array, int* prefixes_num)
753
static void clean_env_entries(sbprefix_t* prefix)
766
{
754
{
767
  int old_errno = errno;
755
  int old_errno = errno;
768
  int i = 0;
756
  int i = 0;
769
  
757
770
  if (NULL != *prefixes_array) {
758
  if (NULL != prefix->strs) {
771
    for (i = 0; i < *prefixes_num; i++) {
759
    for (i = 0; i < prefix->count; i++) {
772
      if (NULL != (*prefixes_array)[i]) {
760
      if (NULL != prefix->strs[i]) {
773
        free((*prefixes_array)[i]);
761
        free(prefix->strs[i]);
774
        (*prefixes_array)[i] = NULL;
762
        prefix->strs[i] = NULL;
775
      }
763
      }
776
    }
764
    }
777
    if (*prefixes_array) free(*prefixes_array);
765
    free(prefix->strs);
778
    *prefixes_array = NULL;
766
    prefix->strs = NULL;
779
    *prefixes_num = 0;
767
    prefix->count = 0;
768
  }
769
  if (prefix->last_env) {
770
      free(prefix->last_env);
771
      prefix->last_env = NULL;
780
  }
772
  }
781
773
782
  errno = old_errno;
774
  errno = old_errno;
783
}
775
}
784
776
785
static void init_env_entries(char*** prefixes_array, int* prefixes_num, char* env, int warn)
777
static void init_env_entries(sbprefix_t* prefix, char* env)
786
{
778
{
787
  int old_errno = errno;
779
  int old_errno = errno;
788
  char* prefixes_env = getenv(env);
780
  char* prefixes_env = getenv(env);
Lines 792-842 Link Here
792
            "Sandbox error : the %s environmental variable should be defined.\n",
784
            "Sandbox error : the %s environmental variable should be defined.\n",
793
            env);
785
            env);
794
  } else {
786
  } else {
795
    char* buffer = NULL;
787
          char *ptr;
796
    int prefixes_env_length = strlen(prefixes_env);
788
          int num_colons = 0;
797
    int i = 0;
798
    int num_delimiters = 0;
799
    char* token = NULL;
800
    char* prefix = NULL;
801
802
    for (i = 0; i < prefixes_env_length; i++) {
803
      if (':' == prefixes_env[i]) {
804
        num_delimiters++;
805
      }
806
    }
807
789
808
    if (num_delimiters > 0) {
790
          /* Check to see if the env value has changed since the
809
      *prefixes_array = (char **)malloc((num_delimiters + 1) * sizeof(char *));
791
             last time this was initalized, don't do the work again
810
      buffer = strndupa(prefixes_env, prefixes_env_length);
792
             if it hasn't.
811
      
793
          */
812
#ifdef REENTRANT_STRTOK
794
813
      token = strtok_r(buffer, ":", &buffer);
795
          if (prefix->last_env && !strcmp(prefix->last_env, prefixes_env)) {
814
#else
796
                  errno = old_errno;
815
      token = strtok(buffer, ":");
797
                  return;
816
#endif
798
          }
817
799
818
      while ((NULL != token) && (strlen(token) > 0)) {
800
          /* Env value is different, update the cached copy */
819
        prefix = strndup(token, strlen(token));
801
          if (prefix->last_env) {
820
        (*prefixes_array)[(*prefixes_num)++] = filter_path(prefix);
802
                  free(prefix->last_env);
821
        
803
                  prefix->last_env = NULL;
822
#ifdef REENTRANT_STRTOK
804
          }
823
        token = strtok_r(NULL, ":", &buffer);
805
          prefix->last_env = strdup(prefixes_env);
824
#else
825
        token = strtok(NULL, ":");
826
#endif
827
806
828
        if (prefix) free(prefix);
807
          ptr = prefixes_env;
829
        prefix = NULL;
808
          while (*ptr) {
830
      }
809
                  if (*ptr++ == ':') ++num_colons;
831
    }
810
          }
832
    else if (prefixes_env_length > 0) {
811
833
      (*prefixes_array) = (char **)malloc(sizeof(char *));
812
          if (prefix->strs) {
834
         
813
                  free(prefix->strs);
835
      prefix = strndupa(prefixes_env, prefixes_env_length);
814
                  prefix->strs = 0;
836
      (*prefixes_array)[(*prefixes_num)++] = filter_path(prefix);
815
          }
837
    }
816
          prefix->strs = (char**)malloc((num_colons+1) * sizeof(char*));
838
  }
817
          if (!prefix->strs) return;
818
          memset(prefix->strs, 0, (num_colons+1) * sizeof(char*));
819
          prefix->count = 0;
820
821
          ptr = prefixes_env;
822
          while (*ptr) {
823
                  char *next_colon = strchr(ptr, ':');
824
                  if (next_colon) {
825
                          if (next_colon != ptr) {
826
                                  char *str = strndup(ptr, next_colon-ptr);
827
                                  if (!str) return;
828
                                  prefix->strs[prefix->count++] = filter_path(str);
829
                                  free(str);
830
                          }
831
                  } else {
832
                          prefix->strs[prefix->count++] = filter_path(ptr);
833
                          break;
834
                  }
839
835
836
                  ptr = next_colon+1;
837
          }
838
  }
840
  errno = old_errno;
839
  errno = old_errno;
841
}
840
}
842
841
Lines 844-849 Link Here
844
{
843
{
845
  int old_errno = errno;
844
  int old_errno = errno;
846
  char* filtered_path = (char *)malloc(MAXPATHLEN * sizeof(char));
845
  char* filtered_path = (char *)malloc(MAXPATHLEN * sizeof(char));
846
  filtered_path[0] = 0;
847
847
848
  canonicalize(path, filtered_path);
848
  canonicalize(path, filtered_path);
849
849
Lines 859-865 Link Here
859
  int i = 0;
859
  int i = 0;
860
  char* filtered_path = filter_path(path);
860
  char* filtered_path = filter_path(path);
861
861
862
  if (!filtered_path) {
863
          errno = old_errno;
864
          return 0;
865
  }
866
862
  if ('/' != filtered_path[0]) {
867
  if ('/' != filtered_path[0]) {
868
    free(filtered_path);
863
    errno = old_errno;
869
    errno = old_errno;
864
    return 0;
870
    return 0;
865
  }
871
  }
Lines 869-880 Link Here
869
  }
875
  }
870
   
876
   
871
  if (-1 == result) {
877
  if (-1 == result) {
872
    if (NULL != sbcontext->deny_prefixes) {
878
    if (NULL != sbcontext->deny.strs) {
873
      for (i = 0; i < sbcontext->num_deny_prefixes; i++) {
879
      for (i = 0; i < sbcontext->deny.count; i++) {
874
        if (NULL != sbcontext->deny_prefixes[i]) {
880
        if (NULL != sbcontext->deny.strs[i]) {
875
          if (0 == strncmp(filtered_path,
881
          if (0 == strncmp(filtered_path,
876
                           sbcontext->deny_prefixes[i],
882
                           sbcontext->deny.strs[i],
877
                           strlen(sbcontext->deny_prefixes[i]))) {
883
                           strlen(sbcontext->deny.strs[i]))) {
878
            result = 0;
884
            result = 0;
879
            break;
885
            break;
880
          }
886
          }
Lines 883-889 Link Here
883
    }
889
    }
884
890
885
    if (-1 == result) {
891
    if (-1 == result) {
886
      if ((NULL != sbcontext->read_prefixes) &&
892
      if ((NULL != sbcontext->read.strs) &&
887
          ((0 == strncmp(func, "open_rd", 7)) ||
893
          ((0 == strncmp(func, "open_rd", 7)) ||
888
           (0 == strncmp(func, "popen", 5)) ||
894
           (0 == strncmp(func, "popen", 5)) ||
889
           (0 == strncmp(func, "opendir", 7)) ||
895
           (0 == strncmp(func, "opendir", 7)) ||
Lines 896-913 Link Here
896
           (0 == strncmp(func, "execve", 6))
902
           (0 == strncmp(func, "execve", 6))
897
          )
903
          )
898
         ) {
904
         ) {
899
        for (i = 0; i < sbcontext->num_read_prefixes; i++) {
905
        for (i = 0; i < sbcontext->read.count; i++) {
900
          if (NULL != sbcontext->read_prefixes[i]) {
906
          if (NULL != sbcontext->read.strs[i]) {
901
            if (0 == strncmp(filtered_path,
907
            if (0 == strncmp(filtered_path,
902
                             sbcontext->read_prefixes[i],
908
                             sbcontext->read.strs[i],
903
                             strlen(sbcontext->read_prefixes[i]))) {
909
                             strlen(sbcontext->read.strs[i]))) {
904
              result = 1;
910
              result = 1;
905
              break;
911
              break;
906
            }
912
            }
907
          }
913
          }
908
        }
914
        }
909
      }
915
      }
910
      else if ((NULL != sbcontext->write_prefixes) &&
916
      else if ((NULL != sbcontext->write.strs) &&
911
               ((0 == strncmp(func, "open_wr", 7)) ||
917
               ((0 == strncmp(func, "open_wr", 7)) ||
912
                (0 == strncmp(func, "creat", 5)) ||
918
                (0 == strncmp(func, "creat", 5)) ||
913
                (0 == strncmp(func, "creat64", 7)) ||
919
                (0 == strncmp(func, "creat64", 7)) ||
Lines 932-954 Link Here
932
              ) {
938
              ) {
933
        struct stat tmp_stat;
939
        struct stat tmp_stat;
934
940
935
        for (i = 0; i < sbcontext->num_write_denied_prefixes; i++) {
941
#if 0  // write_denied is never set
936
          if (NULL != sbcontext->write_denied_prefixes[i]) {
942
943
        for (i = 0; i < sbcontext->write_denied.count; i++) {
944
          if (NULL != sbcontext->write_denied.strs[i]) {
937
            if (0 == strncmp(filtered_path,
945
            if (0 == strncmp(filtered_path,
938
                             sbcontext->write_denied_prefixes[i],
946
                             sbcontext->write_denied.strs[i],
939
                             strlen(sbcontext->write_denied_prefixes[i]))) {
947
                             strlen(sbcontext->write_denied.strs[i]))) {
940
              result = 0;
948
              result = 0;
941
              break;
949
              break;
942
            }
950
            }
943
          }
951
          }
944
        }
952
        }
953
#endif
945
954
946
        if (-1 == result) {
955
        if (-1 == result) {
947
          for (i = 0; i < sbcontext->num_write_prefixes; i++) {
956
          for (i = 0; i < sbcontext->write.count; i++) {
948
            if (NULL != sbcontext->write_prefixes[i]) {
957
            if (NULL != sbcontext->write.strs[i]) {
949
              if (0 == strncmp(filtered_path,
958
              if (0 == strncmp(filtered_path,
950
                               sbcontext->write_prefixes[i],
959
                               sbcontext->write.strs[i],
951
                               strlen(sbcontext->write_prefixes[i]))) {
960
                               strlen(sbcontext->write.strs[i]))) {
952
                result = 1;
961
                result = 1;
953
                break;
962
                break;
954
              }
963
              }
Lines 965-975 Link Here
965
            }
974
            }
966
975
967
            if (-1 == result) {
976
            if (-1 == result) {
968
              for (i = 0; i < sbcontext->num_predict_prefixes; i++) {
977
              for (i = 0; i < sbcontext->predict.count; i++) {
969
                if (NULL != sbcontext->predict_prefixes[i]) {
978
                if (NULL != sbcontext->predict.strs[i]) {
970
                  if (0 == strncmp(filtered_path,
979
                  if (0 == strncmp(filtered_path,
971
                                   sbcontext->predict_prefixes[i],
980
                                   sbcontext->predict.strs[i],
972
                                   strlen(sbcontext->predict_prefixes[i]))) {
981
                                   strlen(sbcontext->predict.strs[i]))) {
973
                    sbcontext->show_access_violation = 0;
982
                    sbcontext->show_access_violation = 0;
974
                    result = 0;
983
                    result = 0;
975
                    break;
984
                    break;
Lines 1128-1160 Link Here
1128
{
1137
{
1129
  int old_errno = errno;
1138
  int old_errno = errno;
1130
  int result = 1;
1139
  int result = 1;
1131
  sbcontext_t sbcontext;
1140
  static sbcontext_t* sbcontext = NULL;
1132
1141
1133
  init_context(&sbcontext);
1142
  if (!sbcontext) {
1143
          sbcontext = (sbcontext_t*)malloc(sizeof(sbcontext_t));
1144
          init_context(sbcontext);
1145
  } else {
1146
          /* sometimes this value gets set to 0 */
1147
          sbcontext->show_access_violation = 1;
1148
  }
1134
1149
1135
  init_env_entries(&(sbcontext.deny_prefixes),
1150
  init_env_entries(&sbcontext->deny,    "SANDBOX_DENY");
1136
                   &(sbcontext.num_deny_prefixes),
1151
  init_env_entries(&sbcontext->read,    "SANDBOX_READ");
1137
                   "SANDBOX_DENY", 1);
1152
  init_env_entries(&sbcontext->write,   "SANDBOX_WRITE");
1138
  init_env_entries(&(sbcontext.read_prefixes),
1153
  init_env_entries(&sbcontext->predict, "SANDBOX_PREDICT");
1139
                   &(sbcontext.num_read_prefixes),
1154
1140
                   "SANDBOX_READ", 1);
1155
  result = check_syscall(sbcontext, func, file);
1141
  init_env_entries(&(sbcontext.write_prefixes),
1156
1142
                   &(sbcontext.num_write_prefixes),
1157
  /* don't clean now, the sbcontext is cached
1143
                   "SANDBOX_WRITE", 1);
1158
  clean_env_entries(&sbcontext.deny);
1144
  init_env_entries(&(sbcontext.predict_prefixes),
1159
  clean_env_entries(&sbcontext.read);
1145
                   &(sbcontext.num_predict_prefixes),
1160
  clean_env_entries(&sbcontext.write);
1146
                   "SANDBOX_PREDICT", 1);
1161
  clean_env_entries(&sbcontext.predict);
1147
1162
  */
1148
  result = check_syscall(&sbcontext, func, file);
1149
1150
  clean_env_entries(&(sbcontext.deny_prefixes),
1151
                    &(sbcontext.num_deny_prefixes));
1152
  clean_env_entries(&(sbcontext.read_prefixes),
1153
                    &(sbcontext.num_read_prefixes));
1154
  clean_env_entries(&(sbcontext.write_prefixes),
1155
                    &(sbcontext.num_write_prefixes));
1156
  clean_env_entries(&(sbcontext.predict_prefixes),
1157
                    &(sbcontext.num_predict_prefixes));
1158
1163
1159
  errno = old_errno;
1164
  errno = old_errno;
1160
                    
1165
                    

Return to bug 233