From: sheepman Date: 2007-03-18T13:02:38+09:00 Subject: [ruby-dev:30622] dl when $SAFE = 1 This is a multi-part message in MIME format. --Multipart=_Sun__18_Mar_2007_13_02_42_+0900_sxoPGs6.ad2xGwuG Content-Type: text/plain; charset=ISO-2022-JP Content-Transfer-Encoding: 7bit こんにちは、sheepman です。 $SAFE=1のときの dl ライブラリの振る舞いに関してです。 require 'dl' $SAFE = 1 h = DL.dlopen(nil) sys = h.sym('system', 'IP') uname = 'uname -rs'.taint sys[uname] という感じで、汚染されている文字列を引数として system を呼べてしまいます。 というわけで、パッチを書いてみました。 DL.dlopen の引数も SafeStringValue でチェックするようにしました。 dl のコードを読むと、String#to_ptr はもとの文字列が汚染されていなくても、常に汚染された PtrData を返すので、 PtrData.new も常に汚染されたオブジェクトを返すようにしています。 このパッチは後方互換がないので、検討が必要だと思います。 -- sheepman / TAMURA Takashi sheepman@sheepman.sakura.ne.jp --Multipart=_Sun__18_Mar_2007_13_02_42_+0900_sxoPGs6.ad2xGwuG Content-Type: text/plain; name="dl_safe.pacth.txt" Content-Disposition: attachment; filename="dl_safe.pacth.txt" Content-Transfer-Encoding: 7bit Index: ptr.c =================================================================== --- ptr.c (revision 12089) +++ ptr.c (working copy) @@ -176,7 +176,8 @@ data->size = 0; data->ids = NULL; data->ids_num = 0; - + OBJ_TAINT(obj); + return obj; } Index: sym.c =================================================================== --- sym.c (revision 12089) +++ sym.c (working copy) @@ -470,7 +470,8 @@ for( i = sym->len - 2; i >= 0; i-- ){ dtypes[i] = 0; - + rb_check_safe_obj(argv[i]); + switch( sym->type[i+1] ){ case 'p': dtypes[i] = 'p'; Index: handle.c =================================================================== --- handle.c (revision 12089) +++ handle.c (working copy) @@ -52,10 +52,14 @@ switch (rb_scan_args(argc, argv, "11", &lib, &flag)) { case 1: + if(!NIL_P(lib)) + SafeStringValue(lib); clib = NIL_P(lib) ? NULL : StringValuePtr(lib); cflag = RTLD_LAZY | RTLD_GLOBAL; break; case 2: + if(!NIL_P(lib)) + SafeStringValue(lib); clib = NIL_P(lib) ? NULL : StringValuePtr(lib); cflag = NUM2INT(flag); break; --Multipart=_Sun__18_Mar_2007_13_02_42_+0900_sxoPGs6.ad2xGwuG--