# Can't start ruby with RUBYOPT=-T4

**URL:** <https://www.ruby-forum.com/t/cant-start-ruby-with-rubyopt-t4/134849>\
**Category:** Development\
**Created:** [April 15, 2008, 5:02pm UTC](https://www.ruby-forum.com/t/cant-start-ruby-with-rubyopt-t4/134849 "2008-04-15T17:02:16Z")\
**Posts on this page:** 3\
**Page:** 1

<div class="post-metadata">

**Author:** ![Yusuke\_ENDOH](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/y/c89c15/32.png) [@Yusuke\_ENDOH](https://www.ruby-forum.com/u/Yusuke_ENDOH)\
**Post date:** [April 15, 2008, 5:02pm UTC](https://www.ruby-forum.com/t/cant-start-ruby-with-rubyopt-t4/134849/1 "2008-04-15T17:02:16Z")

</div>

e$B1sF#$H?=$7$^$9!#e(B

e$B0J2\<$N5sF0$O0U?^E\*$G$7$g$&$+!#e(B

$ RUBYOPT=-T4 ./ruby  
./ruby: Insecure: can’t set constant (SecurityError)

$ ./ruby -v  
ruby 1.9.0 (2008-04-15 revision 16040) [i686-linux]

e$B\<B32$O$J$$5$$b$7$^$9$,!"$4Js9p$^$G!#e(B

---

<div class="post-metadata">

**Author:** ![Yusuke\_ENDOH](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/y/c89c15/32.png) [@Yusuke\_ENDOH](https://www.ruby-forum.com/u/Yusuke_ENDOH)\
**Post date:** [April 16, 2008, 5:50am UTC](https://www.ruby-forum.com/t/cant-start-ruby-with-rubyopt-t4/134849/2 "2008-04-16T05:50:57Z")

</div>

e$B1sF#$G$9!#e(B

2008/04/16 0:00 Yusuke ENDOH [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid):

> e$B0J2\<$N5sF0$O0U?^E\*$G$7$g$&$+!#e(B
> 
> $ RUBYOPT=-T4 ./ruby  
> ./ruby: Insecure: can’t set constant (SecurityError)
> 
> $ ./ruby -v  
> ruby 1.9.0 (2008-04-15 revision 16040) [i686-linux]

r16050 e$B$G=$@5$7$F$$$?$@$$$?$h$&$G$9$,!"$=$NI{:nMQ$Ge(B RUBYOPT=-T1  
e$B$G$bI8=`F~NO$+$i%W%m%0%i%`$rN.$79~$a$k$h$&$K$J$C$?$h$&$G$9!#e(B

$ RUBYOPT=-T1 ./ruby  
p 1  
1

$ ./ruby -v  
ruby 1.9.0 (2008-04-16 revision 16050) [i686-linux]

1.8 e$B$G$Oe(B SecurityError e$B$K$J$j$^$9!#e(B

$ RUBYOPT=-T1 ruby  
ruby: no program input from stdin allowed in tainted mode  
(SecurityError)

$ ruby -v  
ruby 1.8.5 (2006-08-25) [i486-linux]

---

<div class="post-metadata">

**Author:** ![Yusuke\_ENDOH](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/y/c89c15/32.png) [@Yusuke\_ENDOH](https://www.ruby-forum.com/u/Yusuke_ENDOH)\
**Post date:** [April 16, 2008, 11:26am UTC](https://www.ruby-forum.com/t/cant-start-ruby-with-rubyopt-t4/134849/3 "2008-04-16T11:26:53Z")

</div>

e$B$J$+$@$G$9!#e(B

At Wed, 16 Apr 2008 12:49:39 +0900,  
Yusuke ENDOH wrote in [ruby-dev:34421]:

> r16050 e$B$G=$@5$7$F$$$?$@$$$?$h$&$G$9$,!"$=$NI{:nMQ$Ge(B RUBYOPT=-T1  
> e$B$G$bI8=`F~NO$+$i%W%m%0%i%`$rN.$79~$a$k$h$&$K$J$C$?$h$&$G$9!#e(B
> 
> $ RUBYOPT=-T1 ./ruby  
> p 1  
> 1

encodinge$B$O\>o$Ke(B$SAFE=0e$B$G%m!\<%I$9$k$h$&$K$7$h$&$+$H$b;W$$$^$7$?$,!"e(B  
e$B$=$N\>l9g$ODL\>o$N%i%$%V%i%j$H$OJ,$1$J$$$H$^$:$$$+$J$H$$$&5$$b$7$^e(B  
e$B$9!#e(B

e$B$b$&0l$D9M$($?$N$,!“e(B-Te$B$N1F6A$re(B  
process\_optionse$B$NCf$KJD$8$F$7$^$Ce(B  
e$B$F!”\<B:]$Ke(B$SAFEe$B$K%;%C%H$9$k$N$O:G8e$K2s$9!"$H$$$&J}K!$G$9!#e(B

# Index: parse.y

— parse.y (revision 16050)  
+++ parse.y (working copy)  
@@ -8691,4 +8691,24 @@ rb\_gc\_mark\_parser(void)

NODE\*  
+rb\_parser\_add\_prelude(VALUE vparser, NODE \*node, NODE \*prelude)  
+{

- NODE \*scope = node;
- struct parser\_params \*parser;
- 
- Data\_Get\_Struct(vparser, struct parser\_params, parser);
- 
- node = node-\>nd\_body;
- 
- if (nd\_type(node) == NODE\_PRELUDE) {
- node-\>nd\_head = block\_append(prelude, node-\>nd\_head);
- }
- else {
- scope-\>nd\_body = NEW\_PRELUDE(prelude, scope-\>nd\_body);
- }
- 
- return scope;  
+}
- 

# +NODE\* rb\_parser\_append\_print(VALUE vparser, NODE \*node) { Index: ruby.c

— ruby.c (revision 16050)  
+++ ruby.c (working copy)  
@@ -84,4 +95,6 @@ struct cmdline\_options {  
int verbose;  
int yydebug;

- int safe\_level;
- unsigned int setids;  
char \*script;  
VALUE script\_name;  
@@ -93,6 +107,12 @@ struct cmdline\_options {  
} enc;  
} src, ext;  
};

+static void init\_ids(struct cmdline\_options \*);  
+  
+#define cmdline\_options\_init(opt) (MEMZERO((opt), \*(opt), 1), \

- 

```
      init_ids(opt), \

```

- 

```
      (opt)->src.enc.index = src_encoding_index)

```

- 

struct cmdline\_arguments {  
int argc;  
@@ -102,5 +126,6 @@ struct cmdline\_arguments {

static NODE \*load\_file(VALUE, const char \*, int, struct cmdline\_options  
\*);  
-static void forbid\_setid(const char \*);  
+static void forbid\_setid(const char \*, struct cmdline\_options \*);  
+#define forbid\_setid(s) forbid\_setid(s, opt)

static struct {  
@@ -328,5 +353,5 @@ DllMain(HINSTANCE dll, DWORD reason, LPV

void  
-ruby\_init\_loadpath(void)  
+ruby\_init\_loadpath\_safe(int safe\_level)  
{  
#if defined LOAD\_RELATIVE  
@@ -378,5 +404,5 @@ ruby\_init\_loadpath(void)  
#define incpush(path) rb\_ary\_push(rb\_load\_path,  
rubylib\_mangled\_path2(path))

- if (rb\_safe\_level() == 0) {

- if (safe\_level == 0) {  
ruby\_incpush(getenv(“RUBYLIB”));  
}  
@@ -406,8 +432,14 @@ ruby\_init\_loadpath(void)  
incpush(RUBY\_RELATIVE(RUBY\_ARCHLIB));

- if (rb\_safe\_level() == 0) {

- if (safe\_level == 0) {  
incpush(".");  
}  
}
- 

+void  
+ruby\_init\_loadpath(void)  
+{

- ruby\_init\_loadpath\_safe(rb\_safe\_level());  
+}

struct req\_list {  
@@ -793,5 +825,5 @@ proc\_options(int argc, char \*\*argv, stru  
s += numlen;  
}

- rb\_set\_safe\_level(v);

- if (v \> opt-\>safe\_level) opt-\>safe\_level = v;  
}  
goto reswitch;  
@@ -939,4 +975,5 @@ VALUE rb\_progname;  
VALUE rb\_argv0;  
static int src\_encoding\_index = -1; /\* TODO: VM private \*/  
+NODE \*rb\_parser\_add\_prelude(VALUE vparser, NODE \*node, NODE \*prelude);

static VALUE  
@@ -949,8 +986,8 @@ process\_options(VALUE arg)  
NODE \*tree = 0;  
VALUE parser;

- VALUE iseq;  
rb\_encoding \*enc;  
const char \*s;  
int i = proc\_options(argc, argv, opt);

- int safe;

- rb\_safe\_level() == 0 && (s = getenv(“RUBYOPT”))) {

- opt-\>safe\_level == 0 && (s = getenv(“RUBYOPT”))) {  
VALUE src\_enc\_name = opt-\>src.enc.name;  
VALUE ext\_enc\_name = opt-\>ext.enc.name;  
@@ -975,5 +1012,5 @@ process\_options(VALUE arg)  
v = 1;  
}

- 

```
 rb_set_safe_level(v);

```

- 

```
 if (v > opt->safe_level) opt->safe_level = v;

```

}  
else {  
@@ -1010,5 +1047,5 @@ process\_options(VALUE arg)  
}

- if (rb\_safe\_level() \>= 4) {

- if (opt-\>safe\_level \>= 4) {  
OBJ\_TAINT(rb\_argv);  
OBJ\_TAINT(rb\_load\_path);  
@@ -1053,7 +1090,5 @@ process\_options(VALUE arg)  
process\_sflag(opt);

- ruby\_init\_loadpath();
- safe = rb\_safe\_level();
- rb\_set\_safe\_level\_force(0);

- ruby\_init\_loadpath\_safe(opt-\>safe\_level);  
ruby\_init\_gems(!(opt-\>disable & DISABLE\_BIT(gems)));  
parser = rb\_parser\_new();  
@@ -1092,5 +1127,4 @@ process\_options(VALUE arg)  
tree = load\_file(parser, opt-\>script, 1, opt);  
}

- rb\_set\_safe\_level\_force(safe);

- if (rb\_safe\_level() \>= 4) {

- if (opt-\>safe\_level \>= 4) {  
FL\_UNSET(rb\_argv, FL\_TAINT);  
FL\_UNSET(rb\_load\_path, FL\_TAINT);  
@@ -1116,6 +1150,10 @@ process\_options(VALUE arg)  
}

- return rb\_iseq\_new(tree, rb\_str\_new2(""),

- iseq = rb\_iseq\_new(tree, rb\_str\_new2(""),  
opt-\>script\_name, Qfalse, ISEQ\_TYPE\_TOP);
- 
- rb\_set\_safe\_level(opt-\>safe\_level);
- 
- return iseq;  
}

@@ -1274,6 +1318,5 @@ rb\_load\_file(const char \*fname)  
struct cmdline\_options opt;

- MEMZERO(&opt, opt, 1);
- opt.src.enc.index = src\_encoding\_index;

- cmdline\_options\_init(&opt);  
return load\_file(rb\_parser\_new(), fname, 0, &opt);  
}  
@@ -1379,30 +1422,31 @@ ruby\_script(const char \*name)  
}

## -static int uid, euid, gid, egid;

static void  
-init\_ids(void)  
+init\_ids(struct cmdline\_options \*opt)  
{

- uid = (int)getuid();
- euid = (int)geteuid();
- gid = (int)getgid();
- egid = (int)getegid();

- rb\_uid\_t uid = getuid();
- rb\_uid\_t euid = geteuid();
- rb\_gid\_t gid = getgid();
- rb\_gid\_t egid = getegid();  
#ifdef VMS  
uid |= gid \<\< 16;  
euid |= egid \<\< 16;  
#endif

- if (uid && (euid != uid || egid != gid)) {
- rb\_set\_safe\_level(1);

- if (euid != uid) opt-\>setids |= 1;
- if (egid != gid) opt-\>setids |= 2;
- if (uid && opt-\>setids) {
- opt-\>safe\_level = 1;  
}  
}

+#undef forbid\_setid  
static void  
-forbid\_setid(const char \*s)  
+forbid\_setid(const char \*s, struct cmdline\_options \*opt)  
{

- if (euid != uid)

- if (opt-\>setids & 1)  
rb\_raise(rb\_eSecurityError, “no %s allowed while running  
setuid”, s);

- if (egid != gid)

- if (opt-\>setids & 2)  
rb\_raise(rb\_eSecurityError, “no %s allowed while running  
setgid”, s);

- if (rb\_safe\_level() \> 0)

- if (opt-\>safe\_level \> 0)  
rb\_raise(rb\_eSecurityError, “no %s allowed in tainted mode”,  
s);  
}  
@@ -1429,6 +1473,4 @@ void  
ruby\_prog\_init(void)  
{

- init\_ids();

- rb\_define\_hooked\_variable("$VERBOSE", &ruby\_verbose, 0,  
verbose\_setter);  
rb\_define\_hooked\_variable("$-v", &ruby\_verbose, 0, verbose\_setter);  
@@ -1497,5 +1539,5 @@ ruby\_process\_options(int argc, char \*\*ar  
NODE \*tree;

- MEMZERO(&opt, opt, 1);

- cmdline\_options\_init(&opt);  
ruby\_script(argv[0]); /\* for the time being \*/  
rb\_argv0 = rb\_progname;  
@@ -1503,5 +1545,4 @@ ruby\_process\_options(int argc, char \*\*ar  
args.argv = argv;  
args.opt = &opt;

- opt.src.enc.index = src\_encoding\_index;  
opt.ext.enc.index = -1;  
tree = (NODE \*)rb\_vm\_call\_cfunc(rb\_vm\_top\_self(),
