00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019 #define SAFE_LEVEL_MAX RUBY_SAFE_LEVEL_MAX
00020
00021 #include "ruby/ruby.h"
00022 #include "vm_core.h"
00023
00024
00025
00026 #undef rb_secure
00027 #undef rb_set_safe_level
00028 #undef ruby_safe_level_4_warning
00029
00030 int
00031 ruby_safe_level_4_warning(void)
00032 {
00033 return 4;
00034 }
00035
00036 int
00037 rb_safe_level(void)
00038 {
00039 return GET_THREAD()->safe_level;
00040 }
00041
00042 void
00043 rb_set_safe_level_force(int safe)
00044 {
00045 GET_THREAD()->safe_level = safe;
00046 }
00047
00048 void
00049 rb_set_safe_level(int level)
00050 {
00051 rb_thread_t *th = GET_THREAD();
00052
00053 if (level > th->safe_level) {
00054 if (level > SAFE_LEVEL_MAX) {
00055 rb_raise(rb_eArgError, "$SAFE=4 is obsolete");
00056 }
00057 th->safe_level = level;
00058 }
00059 }
00060
00061 static VALUE
00062 safe_getter(void)
00063 {
00064 return INT2NUM(rb_safe_level());
00065 }
00066
00067 static void
00068 safe_setter(VALUE val)
00069 {
00070 int level = NUM2INT(val);
00071 rb_thread_t *th = GET_THREAD();
00072
00073 if (level < th->safe_level) {
00074 rb_raise(rb_eSecurityError,
00075 "tried to downgrade safe level from %d to %d",
00076 th->safe_level, level);
00077 }
00078 if (level == 3) {
00079 rb_warning("$SAFE=3 does no sandboxing");
00080 }
00081 if (level > SAFE_LEVEL_MAX) {
00082 rb_raise(rb_eArgError, "$SAFE=4 is obsolete");
00083 }
00084 th->safe_level = level;
00085 }
00086
00087 void
00088 rb_secure(int level)
00089 {
00090 if (level <= rb_safe_level()) {
00091 ID caller_name = rb_frame_callee();
00092 if (caller_name) {
00093 rb_raise(rb_eSecurityError, "Insecure operation `%s' at level %d",
00094 rb_id2name(caller_name), rb_safe_level());
00095 }
00096 else {
00097 rb_raise(rb_eSecurityError, "Insecure operation at level %d",
00098 rb_safe_level());
00099 }
00100 }
00101 }
00102
00103 void
00104 rb_secure_update(VALUE obj)
00105 {
00106 }
00107
00108 void
00109 rb_insecure_operation(void)
00110 {
00111 ID caller_name = rb_frame_callee();
00112 if (caller_name) {
00113 rb_raise(rb_eSecurityError, "Insecure operation - %s",
00114 rb_id2name(caller_name));
00115 }
00116 else {
00117 rb_raise(rb_eSecurityError, "Insecure operation: -r");
00118 }
00119 }
00120
00121 void
00122 rb_check_safe_obj(VALUE x)
00123 {
00124 if (rb_safe_level() > 0 && OBJ_TAINTED(x)) {
00125 rb_insecure_operation();
00126 }
00127 }
00128
00129 void
00130 rb_check_safe_str(VALUE x)
00131 {
00132 rb_check_safe_obj(x);
00133 if (!RB_TYPE_P(x, T_STRING)) {
00134 rb_raise(rb_eTypeError, "wrong argument type %s (expected String)",
00135 rb_obj_classname(x));
00136 }
00137 }
00138
00139 void
00140 Init_safe(void)
00141 {
00142 rb_define_virtual_variable("$SAFE", safe_getter, safe_setter);
00143 }
00144