From: Minero Aoki Date: 2003-03-21T12:46:22+09:00 Subject: [ruby-dev:19865] dl in $SAFE=4 あおきです。 ruby-list のセキュリティのスレッドを読んで穴を探してみたんですが、 dl を経由するとなんでもできることがわかりました。たとえば次の コードで sh が起動できます。 require 'dl' $SAFE = 4 DL.dlopen('libc.so.6').sym('system', 'IS').call("/bin/sh") とりあえず最低限のパッチだけ付けます。セキュリティレベル いくつで拒否するのかという点や、ptr の汚染などはちゃんと 考える必要がありそうです。 ------------------------------------------------------------------- 青木峰郎 Index: dl.c =================================================================== RCS file: /home/aamine/cvs/ruby/ruby/ext/dl/dl.c,v retrieving revision 1.16 diff -u -p -r1.16 dl.c --- dl.c 16 Jan 2003 07:38:40 -0000 1.16 +++ dl.c 21 Mar 2003 03:46:06 -0000 @@ -542,18 +542,21 @@ rb_io_to_ptr(VALUE self) VALUE rb_dl_dlopen(int argc, VALUE argv[], VALUE self) { + rb_secure(2); return rb_class_new_instance(argc, argv, rb_cDLHandle); } VALUE rb_dl_malloc(VALUE self, VALUE size) { + rb_secure(2); return rb_dlptr_malloc(DLNUM2LONG(size), dlfree); } VALUE rb_dl_strdup(VALUE self, VALUE str) { + rb_secure(2); str = rb_String(str); return rb_dlptr_new(strdup(RSTRING(str)->ptr), RSTRING(str)->len, dlfree); } @@ -561,6 +564,7 @@ rb_dl_strdup(VALUE self, VALUE str) static VALUE rb_dl_sizeof(VALUE self, VALUE str) { + rb_secure(2); return INT2NUM(dlsizeof(StringValuePtr(str))); } @@ -571,6 +575,7 @@ rb_dl_callback(int argc, VALUE argv[], V int rettype, entry, i; char fname[127]; + rb_secure(2); proc = Qnil; switch( rb_scan_args(argc, argv, "11", &type, &proc) ){ case 1: @@ -636,9 +641,11 @@ rb_dl_callback(int argc, VALUE argv[], V static VALUE rb_dl_remove_callback(VALUE mod, VALUE sym) { - freefunc_t f = rb_dlsym2csym(sym); + freefunc_t f; int i, j; + rb_secure(2); + f = rb_dlsym2csym(sym); for( i=0; i < CALLBACK_TYPES; i++ ){ for( j=0; j < MAX_CALLBACK; j++ ){ if( rb_dl_callback_table[i][j] == f ){ Index: sym.c =================================================================== RCS file: /home/aamine/cvs/ruby/ruby/ext/dl/sym.c,v retrieving revision 1.16 diff -u -p -r1.16 sym.c --- sym.c 16 Jan 2003 07:38:40 -0000 1.16 +++ sym.c 21 Mar 2003 03:46:39 -0000 @@ -77,6 +77,7 @@ rb_dlsym_new(void (*func)(), const char struct sym_data *data; const char *ptype; + rb_secure(2); if( !type || !type[0] ){ return rb_dlptr_new((void*)func, 0, 0); } @@ -329,6 +330,7 @@ rb_dlsym_call(int argc, VALUE argv[], VA long ftype; void *func; + rb_secure(2); Data_Get_Struct(self, struct sym_data, sym); DEBUG_CODE({ printf("rb_dlsym_call(): type = '%s', func = 0x%x\n", sym->type, sym->func); Index: ptr.c =================================================================== RCS file: /home/aamine/cvs/ruby/ruby/ext/dl/ptr.c,v retrieving revision 1.16 diff -u -p -r1.16 ptr.c --- ptr.c 16 Jan 2003 07:38:40 -0000 1.16 +++ ptr.c 21 Mar 2003 03:49:29 -0000 @@ -26,6 +26,7 @@ rb_hash_delete(VALUE hash, VALUE key) static void rb_dlmem_delete(void *ptr) { + rb_secure(2); rb_hash_delete(DLMemoryTable, DLLONG2NUM(ptr)); } @@ -89,6 +90,7 @@ rb_dlptr_new2(VALUE klass, void *ptr, lo struct ptr_data *data; VALUE val; + rb_secure(2); if( ptr ){ val = rb_dlmem_aref(ptr); if( val == Qnil ){ @@ -130,6 +132,7 @@ rb_dlptr_malloc(long size, freefunc_t fu { void *ptr; + rb_secure(2); ptr = dlmalloc((size_t)size); memset(ptr,0,(size_t)size); return rb_dlptr_new(ptr, size, func); @@ -161,6 +164,7 @@ rb_dlptr_s_allocate(VALUE klass) VALUE obj; struct ptr_data *data; + rb_secure(2); obj = Data_Make_Struct(klass, struct ptr_data, 0, dlptr_free, data); data->ptr = 0; data->free = 0; @@ -850,6 +854,7 @@ rb_dlptr_aset(int argc, VALUE argv[], VA long memsize; void *memimg; + rb_secure(2); switch( rb_scan_args(argc, argv, "21", &key, &num, &val) ){ case 2: val = num;