1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14: #define SAFE_LEVEL_MAX 4
15:
16:
17:
18: int
19: rb_safe_level(void)
20: {
21: return GET_THREAD()->safe_level;
22: }
23:
24: void
25: rb_set_safe_level_force(int safe)
26: {
27: GET_THREAD()->safe_level = safe;
28: }
29:
30: void
31: rb_set_safe_level(int level)
32: {
33: rb_thread_t *th = GET_THREAD();
34:
35: if (level > th->safe_level) {
36: if (level > SAFE_LEVEL_MAX) {
37: level = SAFE_LEVEL_MAX;
38: }
39: th->safe_level = level;
40: }
41: }
42:
43: static VALUE
44: safe_getter(void)
45: {
46: return INT2NUM(rb_safe_level());
47: }
48:
49: static void
50: safe_setter(VALUE val)
51: {
52: int level = NUM2INT(val);
53: rb_thread_t *th = GET_THREAD();
54:
55: if (level < th->safe_level) {
56: rb_raise(rb_eSecurityError,
57: "tried to downgrade safe level from %d to %d",
58: th->safe_level, level);
59: }
60: if (level > SAFE_LEVEL_MAX) {
61: level = SAFE_LEVEL_MAX;
62: }
63: th->safe_level = level;
64: }
65:
66: void
67: rb_secure(int level)
68: {
69: if (level <= rb_safe_level()) {
70: if (rb_frame_callee()) {
71: rb_raise(rb_eSecurityError, "Insecure operation `%s' at level %d",
72: rb_id2name(rb_frame_callee()), rb_safe_level());
73: }
74: else {
75: rb_raise(rb_eSecurityError, "Insecure operation at level %d",
76: rb_safe_level());
77: }
78: }
79: }
80:
81: void
82: rb_secure_update(VALUE obj)
83: {
84: if (!OBJ_TAINTED(obj))
85: rb_secure(4);
86: }
87:
88: void
89: rb_check_safe_obj(VALUE x)
90: {
91: if (rb_safe_level() > 0 && OBJ_TAINTED(x)) {
92: if (rb_frame_callee()) {
93: rb_raise(rb_eSecurityError, "Insecure operation - %s",
94: rb_id2name(rb_frame_callee()));
95: }
96: else {
97: rb_raise(rb_eSecurityError, "Insecure operation: -r");
98: }
99: }
100: rb_secure(4);
101: }
102:
103: void
104: rb_check_safe_str(VALUE x)
105: {
106: rb_check_safe_obj(x);
107: if (TYPE(x) != T_STRING) {
108: rb_raise(rb_eTypeError, "wrong argument type %s (expected String)",
109: rb_obj_classname(x));
110: }
111: }