ruby-changes:34368
From: nagachika <ko1@a...>
Date: Tue, 17 Jun 2014 00:33:23 +0900 (JST)
Subject: [ruby-changes:34368] nagachika:r46449 (ruby_2_1): merge revision(s) r45287, r45288, r45289, r45290: [Backport #9600]
nagachika 2014-06-17 00:33:10 +0900 (Tue, 17 Jun 2014) New Revision: 46449 http://svn.ruby-lang.org/cgi-bin/viewvc.cgi?view=revision&revision=46449 Log: merge revision(s) r45287,r45288,r45289,r45290: [Backport #9600] process.c: tmp buffer instead of alloca * process.c (OBJ2UID1, OBJ2GID1): separate from OBJ2UID and OBJ2GID respectively, need given buffers. * process.c (OBJ2UID, OBJ2GID): no longer need PREPARE_GETPWNAM and PREPARE_GETGRNAM. * process.c (obj2uid, obj2gid): use tmp buffer instead of alloca to get rid of potential stack overflow. * process.c (obj2uid, obj2gid): now getpwnam_r() and getgrnam_r() may need larger buffers than sysconf values, so retry with expanding the buffer when ERANGE is returned. [ruby-core:61325] [Bug #9600] Modified directories: branches/ruby_2_1/ Modified files: branches/ruby_2_1/ChangeLog branches/ruby_2_1/process.c branches/ruby_2_1/version.h Index: ruby_2_1/ChangeLog =================================================================== --- ruby_2_1/ChangeLog (revision 46448) +++ ruby_2_1/ChangeLog (revision 46449) @@ -1,3 +1,10 @@ https://github.com/ruby/ruby/blob/trunk/ruby_2_1/ChangeLog#L1 +Tue Jun 17 00:26:59 2014 Nobuyoshi Nakada <nobu@r...> + + * process.c (obj2uid, obj2gid): now getpwnam_r() and getgrnam_r() + may need larger buffers than sysconf values, so retry with + expanding the buffer when ERANGE is returned. + [ruby-core:61325] [Bug #9600] + Wed Jun 11 22:58:30 2014 Eric Wong <e@8...> * gc.c (ruby_gc_set_params): simplify condition Index: ruby_2_1/process.c =================================================================== --- ruby_2_1/process.c (revision 46448) +++ ruby_2_1/process.c (revision 46449) @@ -151,20 +151,36 @@ static void check_gid_switch(void); https://github.com/ruby/ruby/blob/trunk/ruby_2_1/process.c#L151 #if defined(HAVE_PWD_H) # if defined(HAVE_GETPWNAM_R) && defined(_SC_GETPW_R_SIZE_MAX) # define USE_GETPWNAM_R 1 +# define GETPW_R_SIZE_INIT sysconf(_SC_GETPW_R_SIZE_MAX) +# define GETPW_R_SIZE_DEFAULT 0x1000 +# define GETPW_R_SIZE_LIMIT 0x10000 # endif # ifdef USE_GETPWNAM_R # define PREPARE_GETPWNAM \ - long getpw_buf_len = sysconf(_SC_GETPW_R_SIZE_MAX); \ - char *getpw_buf = ALLOCA_N(char, (getpw_buf_len < 0 ? (getpw_buf_len = 4096) : getpw_buf_len)); -# define OBJ2UID(id) obj2uid((id), getpw_buf, getpw_buf_len) -static rb_uid_t obj2uid(VALUE id, char *getpw_buf, size_t getpw_buf_len); + VALUE getpw_buf = 0 +# define FINISH_GETPWNAM \ + ALLOCV_END(getpw_buf) +# define OBJ2UID1(id) obj2uid((id), &getpw_buf) +# define OBJ2UID(id) obj2uid0(id) +static rb_uid_t obj2uid(VALUE id, VALUE *getpw_buf); +static inline rb_uid_t +obj2uid0(VALUE id) +{ + rb_uid_t uid; + PREPARE_GETPWNAM; + uid = OBJ2UID1(id); + FINISH_GETPWNAM; + return uid; +} # else # define PREPARE_GETPWNAM /* do nothing */ +# define FINISH_GETPWNAM /* do nothing */ # define OBJ2UID(id) obj2uid((id)) static rb_uid_t obj2uid(VALUE id); # endif #else # define PREPARE_GETPWNAM /* do nothing */ +# define FINISH_GETPWNAM /* do nothing */ # define OBJ2UID(id) NUM2UIDT(id) # ifdef p_uid_from_name # undef p_uid_from_name @@ -175,20 +191,37 @@ static rb_uid_t obj2uid(VALUE id); https://github.com/ruby/ruby/blob/trunk/ruby_2_1/process.c#L191 #if defined(HAVE_GRP_H) # if defined(HAVE_GETGRNAM_R) && defined(_SC_GETGR_R_SIZE_MAX) # define USE_GETGRNAM_R +# define GETGR_R_SIZE_INIT sysconf(_SC_GETGR_R_SIZE_MAX) +# define GETGR_R_SIZE_DEFAULT 0x1000 +# define GETGR_R_SIZE_LIMIT 0x10000 # endif # ifdef USE_GETGRNAM_R # define PREPARE_GETGRNAM \ - long getgr_buf_len = sysconf(_SC_GETGR_R_SIZE_MAX); \ - char *getgr_buf = ALLOCA_N(char, (getgr_buf_len < 0 ? (getgr_buf_len = 4096) : getgr_buf_len)); -# define OBJ2GID(id) obj2gid((id), getgr_buf, getgr_buf_len) -static rb_gid_t obj2gid(VALUE id, char *getgr_buf, size_t getgr_buf_len); + VALUE getgr_buf = 0 +# define FINISH_GETGRNAM \ + ALLOCV_END(getgr_buf) +# define OBJ2GID1(id) obj2gid((id), &getgr_buf) +# define OBJ2GID(id) obj2gid0(id) +static rb_gid_t obj2gid(VALUE id, VALUE *getgr_buf); +static inline rb_gid_t +obj2gid0(VALUE id) +{ + rb_gid_t gid; + PREPARE_GETGRNAM; + gid = OBJ2GID1(id); + FINISH_GETGRNAM; + return gid; +} +static rb_gid_t obj2gid(VALUE id, VALUE *getgr_buf); # else # define PREPARE_GETGRNAM /* do nothing */ +# define FINISH_GETGRNAM /* do nothing */ # define OBJ2GID(id) obj2gid((id)) static rb_gid_t obj2gid(VALUE id); # endif #else # define PREPARE_GETGRNAM /* do nothing */ +# define FINISH_GETGRNAM /* do nothing */ # define OBJ2GID(id) NUM2GIDT(id) # ifdef p_gid_from_name # undef p_gid_from_name @@ -1751,7 +1784,6 @@ rb_execarg_addopt(VALUE execarg_obj, VAL https://github.com/ruby/ruby/blob/trunk/ruby_2_1/process.c#L1784 } check_uid_switch(); { - PREPARE_GETPWNAM; eargp->uid = OBJ2UID(val); eargp->uid_given = 1; } @@ -1767,7 +1799,6 @@ rb_execarg_addopt(VALUE execarg_obj, VAL https://github.com/ruby/ruby/blob/trunk/ruby_2_1/process.c#L1799 } check_gid_switch(); { - PREPARE_GETGRNAM; eargp->gid = OBJ2GID(val); eargp->gid_given = 1; } @@ -4821,7 +4852,7 @@ check_gid_switch(void) https://github.com/ruby/ruby/blob/trunk/ruby_2_1/process.c#L4852 static rb_uid_t obj2uid(VALUE id # ifdef USE_GETPWNAM_R - , char *getpw_buf, size_t getpw_buf_len + , VALUE *getpw_tmp # endif ) { @@ -4836,8 +4867,28 @@ obj2uid(VALUE id https://github.com/ruby/ruby/blob/trunk/ruby_2_1/process.c#L4867 struct passwd *pwptr; #ifdef USE_GETPWNAM_R struct passwd pwbuf; - if (getpwnam_r(usrname, &pwbuf, getpw_buf, getpw_buf_len, &pwptr)) - rb_sys_fail("getpwnam_r"); + char *getpw_buf; + long getpw_buf_len; + if (!*getpw_tmp) { + getpw_buf_len = GETPW_R_SIZE_INIT; + if (getpw_buf_len < 0) getpw_buf_len = GETPW_R_SIZE_DEFAULT; + getpw_buf = rb_alloc_tmp_buffer(getpw_tmp, getpw_buf_len); + } + else { + getpw_buf = RSTRING_PTR(*getpw_tmp); + getpw_buf_len = rb_str_capacity(*getpw_tmp); + } + errno = ERANGE; + /* gepwnam_r() on MacOS X doesn't set errno if buffer size is insufficient */ + while (getpwnam_r(usrname, &pwbuf, getpw_buf, getpw_buf_len, &pwptr)) { + if (errno != ERANGE || getpw_buf_len >= GETPW_R_SIZE_LIMIT) { + rb_free_tmp_buffer(getpw_tmp); + rb_sys_fail("getpwnam_r"); + } + rb_str_modify_expand(*getpw_tmp, getpw_buf_len); + getpw_buf = RSTRING_PTR(*getpw_tmp); + getpw_buf_len = rb_str_capacity(*getpw_tmp); + } #else pwptr = getpwnam(usrname); #endif @@ -4870,7 +4921,6 @@ obj2uid(VALUE id https://github.com/ruby/ruby/blob/trunk/ruby_2_1/process.c#L4921 static VALUE p_uid_from_name(VALUE self, VALUE id) { - PREPARE_GETPWNAM return UIDT2NUM(OBJ2UID(id)); } # endif @@ -4880,7 +4930,7 @@ p_uid_from_name(VALUE self, VALUE id) https://github.com/ruby/ruby/blob/trunk/ruby_2_1/process.c#L4930 static rb_gid_t obj2gid(VALUE id # ifdef USE_GETGRNAM_R - , char *getgr_buf, size_t getgr_buf_len + , VALUE *getgr_tmp # endif ) { @@ -4895,8 +4945,28 @@ obj2gid(VALUE id https://github.com/ruby/ruby/blob/trunk/ruby_2_1/process.c#L4945 struct group *grptr; #ifdef USE_GETGRNAM_R struct group grbuf; - if (getgrnam_r(grpname, &grbuf, getgr_buf, getgr_buf_len, &grptr)) - rb_sys_fail("getgrnam_r"); + char *getgr_buf; + long getgr_buf_len; + if (!*getgr_tmp) { + getgr_buf_len = GETGR_R_SIZE_INIT; + if (getgr_buf_len < 0) getgr_buf_len = GETGR_R_SIZE_DEFAULT; + getgr_buf = rb_alloc_tmp_buffer(getgr_tmp, getgr_buf_len); + } + else { + getgr_buf = RSTRING_PTR(*getgr_tmp); + getgr_buf_len = rb_str_capacity(*getgr_tmp); + } + errno = ERANGE; + /* gegrnam_r() on MacOS X doesn't set errno if buffer size is insufficient */ + while (getgrnam_r(grpname, &grbuf, getgr_buf, getgr_buf_len, &grptr)) { + if (errno != ERANGE || getgr_buf_len >= GETGR_R_SIZE_LIMIT) { + rb_free_tmp_buffer(getgr_tmp); + rb_sys_fail("getgrnam_r"); + } + rb_str_modify_expand(*getgr_tmp, getgr_buf_len); + getgr_buf = RSTRING_PTR(*getgr_tmp); + getgr_buf_len = rb_str_capacity(*getgr_tmp); + } #else grptr = getgrnam(grpname); #endif @@ -4929,7 +4999,6 @@ obj2gid(VALUE id https://github.com/ruby/ruby/blob/trunk/ruby_2_1/process.c#L4999 static VALUE p_gid_from_name(VALUE self, VALUE id) { - PREPARE_GETGRNAM; return GIDT2NUM(OBJ2GID(id)); } # endif @@ -4948,7 +5017,6 @@ p_gid_from_name(VALUE self, VALUE id) https://github.com/ruby/ruby/blob/trunk/ruby_2_1/process.c#L5017 static VALUE p_sys_setuid(VALUE obj, VALUE id) { - PREPARE_GETPWNAM; check_uid_switch(); if (setuid(OBJ2UID(id)) != 0) rb_sys_fail(0); return Qnil; @@ -4971,7 +5039,6 @@ p_sys_setuid(VALUE obj, VALUE id) https://github.com/ruby/ruby/blob/trunk/ruby_2_1/process.c#L5039 static VALUE p_sys_setruid(VALUE obj, VALUE id) { - PREPARE_GETPWNAM; check_uid_switch(); if (setruid(OBJ2UID(id)) != 0) rb_sys_fail(0); return Qnil; @@ -4994,7 +5061,6 @@ p_sys_setruid(VALUE obj, VALUE id) https://github.com/ruby/ruby/blob/trunk/ruby_2_1/process.c#L5061 static VALUE p_sys_seteuid(VALUE obj, VALUE id) { - PREPARE_GETPWNAM; check_uid_switch(); if (seteuid(OBJ2UID(id)) != 0) rb_sys_fail(0); return Qnil; @@ -5019,9 +5085,13 @@ p_sys_seteuid(VALUE obj, VALUE id) https://github.com/ruby/ruby/blob/trunk/ruby_2_1/process.c#L5085 static VALUE p_sys_setreuid(VALUE obj, VALUE rid, VALUE eid) { + rb_uid_t ruid, euid; PREPARE_GETPWNAM; check_uid_switch(); - if (setreuid(OBJ2UID(rid), OBJ2UID(eid)) != 0) rb_sys_fail(0); + ruid = OBJ2UID1(rid); + euid = OBJ2UID1(eid); + FINISH_GETPWNAM; + if (setreuid(ruid, euid) != 0) rb_sys_fail(0); return Qnil; } #else @@ -5044,9 +5114,14 @@ p_sys_setreuid(VALUE obj, VALUE rid, VAL https://github.com/ruby/ruby/blob/trunk/ruby_2_1/process.c#L5114 static VALUE p_sys_setresuid(VALUE obj, VALUE rid, VALUE eid, VALUE sid) { + rb_uid_t ruid, euid, suid; PREPARE_GETPWNAM; check_uid_switch(); - if (setresuid(OBJ2UID(rid), OBJ2UID(eid), OBJ2UID(sid)) != 0) rb_sys_fail(0); + ruid = OBJ2UID1(rid); + euid = OBJ2UID1(eid); + suid = OBJ2UID1(sid); + FINISH_GETPWNAM; + if (setresuid(ruid, euid, suid) != 0) rb_sys_fail(0); return Qnil; } #else @@ -5086,7 +5161,6 @@ static VALUE https://github.com/ruby/ruby/blob/trunk/ruby_2_1/process.c#L5161 proc_setuid(VALUE obj, VALUE id) { rb_uid_t uid; - PREPARE_GETPWNAM; check_uid_switch(); @@ -5158,7 +5232,6 @@ static VALUE https://github.com/ruby/ruby/blob/trunk/ruby_2_1/process.c#L5232 p_uid_change_privilege(VALUE obj, VALUE id) { rb_uid_t uid; - PREPARE_GETPWNAM; check_uid_switch(); @@ -5328,7 +5401,6 @@ p_uid_change_privilege(VALUE obj, VALUE https://github.com/ruby/ruby/blob/trunk/ruby_2_1/process.c#L5401 static VALUE p_sys_setgid(VALUE obj, VALUE id) { - PREPARE_GETGRNAM; check_gid_switch(); if (setgid(OBJ2GID(id)) != 0) rb_sys_fail(0); return Qnil; @@ -5351,7 +5423,6 @@ p_sys_setgid(VALUE obj, VALUE id) https://github.com/ruby/ruby/blob/trunk/ruby_2_1/process.c#L5423 static VALUE p_sys_setrgid(VALUE obj, VALUE id) { - PREPARE_GETGRNAM; check_gid_switch(); if (setrgid(OBJ2GID(id)) != 0) rb_sys_fail(0); return Qnil; @@ -5374,7 +5445,6 @@ p_sys_setrgid(VALUE obj, VALUE id) https://github.com/ruby/ruby/blob/trunk/ruby_2_1/process.c#L5445 static VALUE p_sys_setegid(VALUE obj, VALUE id) { - PREPARE_GETGRNAM; check_gid_switch(); if (setegid(OBJ2GID(id)) != 0) rb_sys_fail(0); return Qnil; @@ -5399,9 +5469,13 @@ p_sys_setegid(VALUE obj, VALUE id) https://github.com/ruby/ruby/blob/trunk/ruby_2_1/process.c#L5469 static VALUE p_sys_setregid(VALUE obj, VALUE rid, VALUE eid) { + rb_gid_t rgid, egid; PREPARE_GETGRNAM; check_gid_switch(); - if (setregid(OBJ2GID(rid), OBJ2GID(eid)) != 0) rb_sys_fail(0); + rgid = OBJ2GID(rid); + egid = OBJ2GID(eid); + FINISH_GETGRNAM; + if (setregid(rgid, egid) != 0) rb_sys_fail(0); return Qnil; } #else @@ -5423,9 +5497,14 @@ p_sys_setregid(VALUE obj, VALUE rid, VAL https://github.com/ruby/ruby/blob/trunk/ruby_2_1/process.c#L5497 static VALUE p_sys_setresgid(VALUE obj, VALUE rid, VALUE eid, VALUE sid) { + rb_gid_t rgid, egid, sgid; PREPARE_GETGRNAM; check_gid_switch(); - if (setresgid(OBJ2GID(rid), OBJ2GID(eid), OBJ2GID(sid)) != 0) rb_sys_fail(0); + rgid = OBJ2GID(rid); + egid = OBJ2GID(eid); + sgid = OBJ2GID(sid); + FINISH_GETGRNAM; + if (setresgid(rgid, egid, sgid) != 0) rb_sys_fail(0); return Qnil; } #else @@ -5493,7 +5572,6 @@ static VALUE https://github.com/ruby/ruby/blob/trunk/ruby_2_1/process.c#L5572 proc_setgid(VALUE obj, VALUE id) { rb_gid_t gid; - PREPARE_GETGRNAM; check_gid_switch(); @@ -5641,8 +5719,9 @@ proc_setgroups(VALUE obj, VALUE ary) https://github.com/ruby/ruby/blob/trunk/ruby_2_1/process.c#L5719 for (i = 0; i < ngroups; i++) { VALUE g = RARRAY_AREF(ary, i); - groups[i] = OBJ2GID(g); + groups[i] = OBJ2GID1(g); } + FINISH_GETGRNAM; if (setgroups(ngroups, groups) == -1) /* ngroups <= maxgroups */ rb_sys_fail(0); @@ -5675,7 +5754,6 @@ proc_setgroups(VALUE obj, VALUE ary) https://github.com/ruby/ruby/blob/trunk/ruby_2_1/process.c#L5754 static VALUE proc_initgroups(VALUE obj, VALUE uname, VALUE base_grp) { - PREPARE_GETGRNAM; if (initgroups(StringValuePtr(uname), OBJ2GID(base_grp)) != 0) { rb_sys_fail(0); } @@ -5857,7 +5935,6 @@ static VALUE https://github.com/ruby/ruby/blob/trunk/ruby_2_1/process.c#L5935 p_gid_change_privilege(VALUE obj, VALUE id) { rb_gid_t gid; - PREPARE_GETGRNAM; check_gid_switch(); @@ -6067,7 +6144,6 @@ proc_seteuid(rb_uid_t uid) https://github.com/ruby/ruby/blob/trunk/ruby_2_1/process.c#L6144 static VALUE proc_seteuid_m(VALUE mod, VALUE euid) { - PREPARE_GETPWNAM; check_uid_switch(); proc_seteuid(OBJ2UID(euid)); return euid; @@ -6133,7 +6209,6 @@ rb_seteuid_core(rb_uid_t euid) https://github.com/ruby/ruby/blob/trunk/ruby_2_1/process.c#L6209 static VALUE p_uid_grant_privilege(VALUE obj, VALUE id) { - PREPARE_GETPWNAM; rb_seteuid_core(OBJ2UID(id)); return id; } @@ -6173,7 +6248,6 @@ proc_setegid(VALUE obj, VALUE egid) https://github.com/ruby/ruby/blob/trunk/ruby_2_1/process.c#L6248 { #if defined(HAVE_SETRESGID) || defined(HAVE_SETREGID) || defined(HAVE_SETEGID) || defined(HAVE_SETGID) rb_gid_t gid; - PREPARE_GETGRNAM; #endif check_gid_switch(); @@ -6265,7 +6339,6 @@ rb_setegid_core(rb_gid_t egid) https://github.com/ruby/ruby/blob/trunk/ruby_2_1/process.c#L6339 static VALUE p_gid_grant_privilege(VALUE obj, VALUE id) { - PREPARE_GETGRNAM; rb_setegid_core(OBJ2GID(id)); return id; } Index: ruby_2_1/version.h =================================================================== --- ruby_2_1/version.h (revision 46448) +++ ruby_2_1/version.h (revision 46449) @@ -1,10 +1,10 @@ https://github.com/ruby/ruby/blob/trunk/ruby_2_1/version.h#L1 #define RUBY_VERSION "2.1.2" -#define RUBY_RELEASE_DATE "2014-06-11" -#define RUBY_PATCHLEVEL 129 +#define RUBY_RELEASE_DATE "2014-06-17" +#define RUBY_PATCHLEVEL 130 #define RUBY_RELEASE_YEAR 2014 #define RUBY_RELEASE_MONTH 6 -#define RUBY_RELEASE_DAY 11 +#define RUBY_RELEASE_DAY 17 #include "ruby/version.h" Property changes on: ruby_2_1 ___________________________________________________________________ Modified: svn:mergeinfo Merged /trunk:r45287-45290 -- ML: ruby-changes@q... Info: http://www.atdot.net/~ko1/quickml/