string.c (rb_str_crypt): fix excessive stack use with crypt_r

"struct crypt_data" is 131232 bytes on x86-64 GNU/Linux,
making it unsafe to use tiny Fiber stack sizes.

git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@58864 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
normal 2017-05-24 03:01:44 +00:00
Родитель 2e87ef8b66
Коммит 144e067007
1 изменённых файлов: 11 добавлений и 3 удалений

Просмотреть файл

@ -8713,7 +8713,7 @@ static VALUE
rb_str_crypt(VALUE str, VALUE salt) rb_str_crypt(VALUE str, VALUE salt)
{ {
#ifdef HAVE_CRYPT_R #ifdef HAVE_CRYPT_R
struct crypt_data data; struct crypt_data *data = ALLOC(struct crypt_data);
#else #else
extern char *crypt(const char *, const char *); extern char *crypt(const char *, const char *);
#endif #endif
@ -8745,16 +8745,24 @@ rb_str_crypt(VALUE str, VALUE salt)
#endif #endif
#ifdef HAVE_CRYPT_R #ifdef HAVE_CRYPT_R
# ifdef HAVE_STRUCT_CRYPT_DATA_INITIALIZED # ifdef HAVE_STRUCT_CRYPT_DATA_INITIALIZED
data.initialized = 0; data->initialized = 0;
# endif # endif
res = crypt_r(s, saltp, &data); res = crypt_r(s, saltp, data);
#else #else
res = crypt(s, saltp); res = crypt(s, saltp);
#endif #endif
if (!res) { if (!res) {
#ifdef HAVE_CRYPT_R
int err = errno;
xfree(data);
errno = err;
#endif
rb_sys_fail("crypt"); rb_sys_fail("crypt");
} }
result = rb_str_new_cstr(res); result = rb_str_new_cstr(res);
#ifdef HAVE_CRYPT_R
xfree(data);
#endif
FL_SET_RAW(result, OBJ_TAINTED_RAW(str) | OBJ_TAINTED_RAW(salt)); FL_SET_RAW(result, OBJ_TAINTED_RAW(str) | OBJ_TAINTED_RAW(salt));
return result; return result;
} }