1
0
Fork 0
mirror of https://github.com/ruby/ruby.git synced 2022-11-09 12:17:21 -05:00

string.c: fix memory leak in String#crypt

Use ALLOCV to allocate struct crypt_data for slightly cleaner and less
error-prone code. It is currently possible it leaks when an invalid
argument is passed to String#crypt or rb_str_new_cstr() fails to
allocate memory.

SIZEOF_CRYPT_DATA macro in missing/crypt.h is removed since it is not
used any longer.

git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@60748 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
rhe 2017-11-12 15:55:04 +00:00
parent 4eb3457076
commit 0b845a8458
2 changed files with 6 additions and 14 deletions

View file

@ -237,8 +237,6 @@ struct crypt_data {
char cryptresult[1+4+4+11+1]; /* encrypted result */ char cryptresult[1+4+4+11+1]; /* encrypted result */
}; };
#define SIZEOF_CRYPT_DATA (KS_SIZE*8+(1+4+4+11+1))
char *crypt(const char *key, const char *setting); char *crypt(const char *key, const char *setting);
void setkey(const char *key); void setkey(const char *key);
void encrypt(char *block, int flag); void encrypt(char *block, int flag);

View file

@ -8839,14 +8839,9 @@ rb_str_oct(VALUE str)
static VALUE static VALUE
rb_str_crypt(VALUE str, VALUE salt) rb_str_crypt(VALUE str, VALUE salt)
{ {
#undef LARGE_CRYPT_DATA
#ifdef HAVE_CRYPT_R #ifdef HAVE_CRYPT_R
# if defined SIZEOF_CRYPT_DATA && SIZEOF_CRYPT_DATA <= 256 VALUE databuf;
struct crypt_data cdata, *const data = &cdata; struct crypt_data *data;
# else
# define LARGE_CRYPT_DATA
struct crypt_data *data = ALLOC(struct crypt_data);
# endif
#else #else
extern char *crypt(const char *, const char *); extern char *crypt(const char *, const char *);
#endif #endif
@ -8877,6 +8872,7 @@ rb_str_crypt(VALUE str, VALUE salt)
} }
#endif #endif
#ifdef HAVE_CRYPT_R #ifdef HAVE_CRYPT_R
data = ALLOCV(databuf, sizeof(struct crypt_data));
# ifdef HAVE_STRUCT_CRYPT_DATA_INITIALIZED # ifdef HAVE_STRUCT_CRYPT_DATA_INITIALIZED
data->initialized = 0; data->initialized = 0;
# endif # endif
@ -8885,17 +8881,15 @@ rb_str_crypt(VALUE str, VALUE salt)
res = crypt(s, saltp); res = crypt(s, saltp);
#endif #endif
if (!res) { if (!res) {
#ifdef LARGE_CRYPT_DATA #ifdef HAVE_CRYPT_R
int err = errno; int err = errno;
xfree(data); ALLOCV_END(databuf);
errno = err; errno = err;
#endif #endif
rb_sys_fail("crypt"); rb_sys_fail("crypt");
} }
result = rb_str_new_cstr(res); result = rb_str_new_cstr(res);
#ifdef LARGE_CRYPT_DATA ALLOCV_END(databuf);
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;
} }