[ruby-trunk - Bug #5615][Open] A memory leak in hash.c on Solaris (and every environment which defin

Issue #5615 has been reported by Daisuke Ikegami.


Bug #5615: A memory leak in hash.c on Solaris (and every environment
which defines __sun)
http://redmine.ruby-lang.org/issues/5615

Author: Daisuke Ikegami
Status: Open
Priority: Normal
Assignee:
Category:
Target version: 2.0.0
ruby -v: ruby 2.0.0dev (2011-11-11 trunk 33704) [i686-linux]

Reproducing steps: I didn’t test the patch. Please do.
Result of ruby -v: ruby 2.0.0dev (2011-11-11 trunk 33704) [i686-linux]
What you expected: ruby should not have any memory leak.
What you happened: It seems to have a memory leak of ruby on Solaris.
The bug is in the function ruby_setenv() in hash.c.

Here is the code snippet around the bug:
2287 #elif defined __sun
2288 size_t len;
2289 char **env_ptr, *str;
2290 if (strchr(name, ‘=’)) {
2291 errno = EINVAL;
2292 rb_sys_fail(“ruby_setenv”);
2293 }
2294 len = strlen(name);
2295 for (env_ptr = GET_ENVIRON(environ); (str = env_ptr) != 0;
++env_ptr) {
2296 if (!strncmp(str, name, len) && str[len] == ‘=’) {
2297 if (!in_origenv(str)) free(str);
2298 while ((env_ptr[0] = env_ptr[1]) != 0) env_ptr++;
2299 break;
2300 }
2301 }
2302 if (value) {
2303 str = malloc(len += strlen(value) + 2);
2304 snprintf(str, len, “%s=%s”, name, value);
2305 if (putenv(str))
2306 rb_sys_fail(“putenv”);
2307 }
2308 #else /
WIN32 */

In line 2303, a variable ‘str’ is malloc-ed, but, seems never to free.
Therefore it seems a memory leak.

This bug is found by using cppcheck technically.
Here is URL of cppcheck:

The result of cppcheck is following:
% cppcheck -f -I. hash.c
Checking hash.c…
Checking hash.c: ENV_IGNORECASE…
Checking hash.c: HAVE_SETENV;HAVE_UNSETENV…
Checking hash.c: _WIN32…
Checking hash.c: APPLE
Checking hash.c: __sun…
[hash.c:2351]: (error) Memory leak: str
(information) Cppcheck cannot find all the include files (use
–check-config for details)

I’ll attach a patch to fix this bug. After applying this patch, cppcheck
does not warn.

Issue #5615 has been updated by Usaku NAKAMURA.

Status changed from Open to Rejected

putenv(3)は引数で与えたポインタをそのまま使うので、この時点では解放することができません。
ちなみに、該当部分の少し上で(現時点のtrunkなら2297行目)
if (!in_origenv(str)) free(str);
というコードがありますが、これが不要になったら解放するコードになります。

ということを、私も今回初めて知りました。


Bug #5615: A memory leak in hash.c on Solaris (and every environment
which defines __sun)
http://redmine.ruby-lang.org/issues/5615

Author: Daisuke Ikegami
Status: Rejected
Priority: Normal
Assignee:
Category:
Target version: 2.0.0
ruby -v: ruby 2.0.0dev (2011-11-11 trunk 33704) [i686-linux]

Reproducing steps: I didn’t test the patch. Please do.
Result of ruby -v: ruby 2.0.0dev (2011-11-11 trunk 33704) [i686-linux]
What you expected: ruby should not have any memory leak.
What you happened: It seems to have a memory leak of ruby on Solaris.
The bug is in the function ruby_setenv() in hash.c.

Here is the code snippet around the bug:
2287 #elif defined __sun
2288 size_t len;
2289 char **env_ptr, *str;
2290 if (strchr(name, ‘=’)) {
2291 errno = EINVAL;
2292 rb_sys_fail(“ruby_setenv”);
2293 }
2294 len = strlen(name);
2295 for (env_ptr = GET_ENVIRON(environ); (str = env_ptr) != 0;
++env_ptr) {
2296 if (!strncmp(str, name, len) && str[len] == ‘=’) {
2297 if (!in_origenv(str)) free(str);
2298 while ((env_ptr[0] = env_ptr[1]) != 0) env_ptr++;
2299 break;
2300 }
2301 }
2302 if (value) {
2303 str = malloc(len += strlen(value) + 2);
2304 snprintf(str, len, “%s=%s”, name, value);
2305 if (putenv(str))
2306 rb_sys_fail(“putenv”);
2307 }
2308 #else /
WIN32 */

In line 2303, a variable ‘str’ is malloc-ed, but, seems never to free.
Therefore it seems a memory leak.

This bug is found by using cppcheck technically.
Here is URL of cppcheck:
http://sourceforge.net/projects/cppcheck/

The result of cppcheck is following:
% cppcheck -f -I. hash.c
Checking hash.c…
Checking hash.c: ENV_IGNORECASE…
Checking hash.c: HAVE_SETENV;HAVE_UNSETENV…
Checking hash.c: _WIN32…
Checking hash.c: APPLE
Checking hash.c: __sun…
[hash.c:2351]: (error) Memory leak: str
(information) Cppcheck cannot find all the include files (use
–check-config for details)

I’ll attach a patch to fix this bug. After applying this patch, cppcheck
does not warn.