Hi,

At Fri, 1 Sep 2006 17:15:49 +0900,
Yukihiro Matsumoto wrote in [ruby-talk:211948]:
> It's better, but this warning can be caused by both $PATH and
> $LOAD_PATH, and currently has no clue to distinguish in this function.

I guess fpath_check() to be check for LOAD_PATH but not for
PATH.  Though I' not sure rb_loadpath_check() is really
necessary, when the required file is found in safe path.


Index: file.c =================================================================== RCS file: /cvs/ruby/src/ruby/file.c,v retrieving revision 1.246 diff -p -u -2 -r1.246 file.c --- file.c 31 Aug 2006 11:24:44 -0000 1.246 +++ file.c 2 Sep 2006 06:51:28 -0000 @@ -4074,5 +4074,6 @@ path_check_0(VALUE path, int loadpath) #endif && !access(p0, W_OK)) { - rb_warn("Insecure world writable dir %s, mode 0%o", p0, st.st_mode); + rb_warn("Insecure world writable dir %s, mode 0%o in %s", + p0, st.st_mode, loadpath ? "$LOAD_PATH" : "PATH"); if (p) *p = '/'; return 0; @@ -4091,5 +4092,5 @@ fpath_check(const char *path) { #ifndef DOSISH - return path_check_0(rb_str_new2(path), Qfalse); + return path_check_0(rb_str_new2(path), Qtrue); #else return 1; @@ -4097,6 +4098,6 @@ fpath_check(const char *path) } -int -rb_path_check(const char *path) +static int +rb_pathlist_check(const char *path, int loadpath) { #ifndef DOSISH @@ -4112,5 +4113,5 @@ rb_path_check(const char *path) for (;;) { - if (!path_check_0(rb_str_new(p0, p - p0), Qtrue)) { + if (!path_check_0(rb_str_new(p0, p - p0), loadpath)) { return 0; /* not safe */ } @@ -4124,4 +4125,16 @@ rb_path_check(const char *path) } +int +rb_path_check(const char *path) +{ + return rb_pathlist_check(path, Qfalse); +} + +int +rb_loadpath_check(const char *path) +{ + return rb_pathlist_check(path, Qtrue); +} + #if defined(__MACOS__) || defined(riscos) static int @@ -4203,6 +4216,8 @@ rb_find_file(VALUE path) if (f[0] == '~') { + volatile VALUE prevent_from_gc = path; path = rb_file_expand_path(path, Qnil); if (rb_safe_level() >= 1 && OBJ_TAINTED(path)) { + (void)prevent_from_gc; rb_raise(rb_eSecurityError, "loading from unsafe path %s", f); } @@ -4249,7 +4264,9 @@ rb_find_file(VALUE path) else { lpath = RSTRING_PTR(tmp); - if (rb_safe_level() >= 1 && !rb_path_check(lpath)) { +#if 0 + if (rb_safe_level() >= 1 && !rb_loadpath_check(lpath)) { rb_raise(rb_eSecurityError, "loading from unsafe path %s", lpath); } +#endif } } Index: intern.h =================================================================== RCS file: /cvs/ruby/src/ruby/intern.h,v retrieving revision 1.199 diff -p -u -2 -r1.199 intern.h --- intern.h 31 Aug 2006 08:24:36 -0000 1.199 +++ intern.h 2 Sep 2006 06:48:03 -0000 @@ -326,4 +326,5 @@ VALUE rb_hash_delete_if(VALUE); VALUE rb_hash_delete(VALUE,VALUE); int rb_path_check(const char*); +int rb_loadpath_check(const char*); int rb_env_path_tainted(void); /* io.c */
-- Nobu Nakada