safe.c

Go to the documentation of this file.
00001 /**********************************************************************
00002 
00003   safe.c -
00004 
00005   $Author: nobu $
00006   created at: Tue Sep 23 09:44:32 JST 2008
00007 
00008   Copyright (C) 2008 Yukihiro Matsumoto
00009 
00010 **********************************************************************/
00011 
00012 /* safe-level:
00013    0 - strings from streams/environment/ARGV are tainted (default)
00014    1 - no dangerous operation by tainted value
00015    2 - process/file operations prohibited
00016    3 - all generated objects are tainted
00017 */
00018 
00019 #define SAFE_LEVEL_MAX RUBY_SAFE_LEVEL_MAX
00020 
00021 #include "ruby/ruby.h"
00022 #include "vm_core.h"
00023 
00024 /* $SAFE accessor */
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 

Generated on 19 Jul 2016 for Ruby by  doxygen 1.4.7