summaryrefslogtreecommitdiff
path: root/string.c
diff options
context:
space:
mode:
authornormal <normal@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2017-05-24 03:01:44 +0000
committernormal <normal@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2017-05-24 03:01:44 +0000
commit144e06700705a3f067582682567bc77b429c4fca (patch)
tree86b1f8c16e0f9698ee62078d59e8b0e126f44f5f /string.c
parent2e87ef8b66e4b89fa39e10043a32f37e6ae35ae1 (diff)
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
Diffstat (limited to 'string.c')
-rw-r--r--string.c14
1 files changed, 11 insertions, 3 deletions
diff --git a/string.c b/string.c
index c0483c9471..4bd519787c 100644
--- a/string.c
+++ b/string.c
@@ -8713,7 +8713,7 @@ static VALUE
rb_str_crypt(VALUE str, VALUE salt)
{
#ifdef HAVE_CRYPT_R
- struct crypt_data data;
+ struct crypt_data *data = ALLOC(struct crypt_data);
#else
extern char *crypt(const char *, const char *);
#endif
@@ -8745,16 +8745,24 @@ rb_str_crypt(VALUE str, VALUE salt)
#endif
#ifdef HAVE_CRYPT_R
# ifdef HAVE_STRUCT_CRYPT_DATA_INITIALIZED
- data.initialized = 0;
+ data->initialized = 0;
# endif
- res = crypt_r(s, saltp, &data);
+ res = crypt_r(s, saltp, data);
#else
res = crypt(s, saltp);
#endif
if (!res) {
+#ifdef HAVE_CRYPT_R
+ int err = errno;
+ xfree(data);
+ errno = err;
+#endif
rb_sys_fail("crypt");
}
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));
return result;
}