https://bugs.ruby-lang.org/https://bugs.ruby-lang.org/favicon.ico?17113305112012-04-16T15:34:06ZRuby Issue Tracking SystemRuby master - Bug #6303: dln_load and rb_w32_check_imported cause segfault in Ruby 1.9.3 for some extensionhttps://bugs.ruby-lang.org/issues/6303?journal_id=259252012-04-16T15:34:06Zphasis68 (Heesob Park)phasis@gmail.com
<ul></ul><p>The segfault is due to the invalid pointer reference in getting PIMAGE_IMPORT_BY_NAME pointer like this:</p>
<p>PIMAGE_IMPORT_BY_NAME pii = (PIMAGE_IMPORT_BY_NAME)((char *)ext + (size_t)pint->u1.AddressOfData);</p>
<p>Consider the following imports dump list of ibm_db.so</p>
<pre><code>DB2CLI.dll
63317274 Import Address Table
63317078 Import Name Table
0 time date stamp
0 Index of first forwarder reference
Ordinal 1300
Ordinal 1301
6C SQLDriverConnectW@32
52 SQLConnectW@28
Ordinal 9
Ordinal 1303
Ordinal 58
64 SQLDescribeColW@36
Ordinal 4
4A SQLColumnPrivilegesW@36
4E SQLColumnsW@36
FB SQLPrimaryKeysW@28
98 SQLForeignKeysW@52
FF SQLProcedureColumnsW@36
103 SQLProceduresW@28
133 SQLSpecialColumnsW@40
137 SQLStatisticsW@36
13B SQLTablePrivilegesW@28
13F SQLTablesW@36
7A SQLExecDirectW@12
F7 SQLPrepareW@12
</code></pre>
<p>...</p>
<p>As you can see, the name table entry has two types: ordinal type and name type.<br>
But, the rb_w32_check_imported function overlooked ordinal case.</p>
<p>Refer to <a href="http://nienie.com/~masapico/api_ImageDirectoryEntryToData.html" class="external">http://nienie.com/~masapico/api_ImageDirectoryEntryToData.html</a></p>
<p>Here is a patch:</p>
<p>diff --git a/dln.c b/dln.c.new<br>
index e3dff9b..58042e1 100644<br>
--- a/dln.c<br>
+++ b/dln.c.new<br>
@@ -1215,12 +1215,14 @@ rb_w32_check_imported(HMODULE ext, HMODULE mine)<br>
PIMAGE_THUNK_DATA pint = (PIMAGE_THUNK_DATA)((char *)ext + desc->Characteristics);<br>
PIMAGE_THUNK_DATA piat = (PIMAGE_THUNK_DATA)((char *)ext + desc->FirstThunk);<br>
while (piat->u1.Function) {</p>
<ul>
<li>
<pre><code> PIMAGE_IMPORT_BY_NAME pii = (PIMAGE_IMPORT_BY_NAME)((char *)ext + (size_t)pint->u1.AddressOfData);
</code></pre>
</li>
<li>
<pre><code> static const char prefix[] = "rb_";
</code></pre>
</li>
<li>
<pre><code> const char *name = (const char *)pii->Name;
</code></pre>
</li>
<li>
<pre><code> if (strncmp(name, prefix, sizeof(prefix) - 1) == 0) {
</code></pre>
</li>
<li>
<pre><code> FARPROC addr = GetProcAddress(mine, name);
</code></pre>
</li>
<li>
<pre><code> if (addr) return (FARPROC)piat->u1.Function == addr;
</code></pre>
</li>
</ul>
<ul>
<li>
<pre><code> if(!IMAGE_SNAP_BY_ORDINAL(pint->u1.Ordinal)) {
</code></pre>
</li>
<li>
<pre><code> PIMAGE_IMPORT_BY_NAME pii = (PIMAGE_IMPORT_BY_NAME)((char *)ext + (size_t)pint->u1.AddressOfData);
</code></pre>
</li>
<li>
<pre><code> static const char prefix[] = "rb_";
</code></pre>
</li>
<li>
<pre><code> const char *name = (const char *)pii->Name;
</code></pre>
</li>
<li>
<pre><code> if (strncmp(name, prefix, sizeof(prefix) - 1) == 0) {
</code></pre>
</li>
<li>
<pre><code> FARPROC addr = GetProcAddress(mine, name);
</code></pre>
</li>
<li>
<pre><code> if (addr) return (FARPROC)piat->u1.Function == addr;
</code></pre>
</li>
<li>
<pre><code> }
}
piat++;
pint++;
</code></pre>
</li>
</ul> Ruby master - Bug #6303: dln_load and rb_w32_check_imported cause segfault in Ruby 1.9.3 for some extensionhttps://bugs.ruby-lang.org/issues/6303?journal_id=259332012-04-16T21:25:31Znobu (Nobuyoshi Nakada)nobu@ruby-lang.org
<ul><li><strong>Status</strong> changed from <i>Open</i> to <i>Closed</i></li><li><strong>% Done</strong> changed from <i>0</i> to <i>100</i></li></ul><p>This issue was solved with changeset r35352.<br>
Luis, thank you for reporting this issue.<br>
Your contribution to Ruby is greatly appreciated.<br>
May Ruby be with you.</p>
<hr>
<ul>
<li>dln.c (rb_w32_check_imported): skip ordinal entries. patched by<br>
phasis68 (Heesob Park) at <a href="/issues/6303">[ruby-core:44381]</a>. [Bug <a class="issue tracker-1 status-5 priority-4 priority-default closed" title="Bug: dln_load and rb_w32_check_imported cause segfault in Ruby 1.9.3 for some extension (Closed)" href="https://bugs.ruby-lang.org/issues/6303">#6303</a>]</li>
</ul> Ruby master - Bug #6303: dln_load and rb_w32_check_imported cause segfault in Ruby 1.9.3 for some extensionhttps://bugs.ruby-lang.org/issues/6303?journal_id=259352012-04-16T22:27:36Zphasis68 (Heesob Park)phasis@gmail.com
<ul></ul><p>The changeset r35352 is not same to my patch and the bug <a class="issue tracker-1 status-5 priority-4 priority-default closed" title="Bug: dln_load and rb_w32_check_imported cause segfault in Ruby 1.9.3 for some extension (Closed)" href="https://bugs.ruby-lang.org/issues/6303">#6303</a> is not fixed.</p>
<p>After applying r35352,<br>
require 'mswin32/ibm_db'<br>
falls into infinite loop and runs forever.</p>
<p>The line<br>
if (IMAGE_SNAP_BY_ORDINAL(pint->u1.Ordinal)) continue;</p>
<p>should be</p>
<p>if (IMAGE_SNAP_BY_ORDINAL(pint->u1.Ordinal)) {pint++;piat++;continue;}</p> Ruby master - Bug #6303: dln_load and rb_w32_check_imported cause segfault in Ruby 1.9.3 for some extensionhttps://bugs.ruby-lang.org/issues/6303?journal_id=259362012-04-16T22:34:06Zluislavena (Luis Lavena)luislavena@gmail.com
<ul><li><strong>Category</strong> set to <i>core</i></li><li><strong>Status</strong> changed from <i>Closed</i> to <i>Assigned</i></li><li><strong>Assignee</strong> set to <i>nobu (Nobuyoshi Nakada)</i></li><li><strong>Target version</strong> set to <i>1.9.3</i></li><li><strong>% Done</strong> changed from <i>100</i> to <i>80</i></li><li><strong>ruby -v</strong> set to <i>1.9.3</i></li></ul> Ruby master - Bug #6303: dln_load and rb_w32_check_imported cause segfault in Ruby 1.9.3 for some extensionhttps://bugs.ruby-lang.org/issues/6303?journal_id=259492012-04-17T13:11:20Znobu (Nobuyoshi Nakada)nobu@ruby-lang.org
<ul><li><strong>Status</strong> changed from <i>Assigned</i> to <i>Closed</i></li><li><strong>% Done</strong> changed from <i>80</i> to <i>100</i></li></ul><p>This issue was solved with changeset r35354.<br>
Luis, thank you for reporting this issue.<br>
Your contribution to Ruby is greatly appreciated.<br>
May Ruby be with you.</p>
<hr>
<ul>
<li>dln.c (rb_w32_check_imported): skip ordinal entries. based on a<br>
patch by phasis68 (Heesob Park) at <a href="/issues/6303">[ruby-core:44381]</a>.<br>
<a href="/issues/6303">[ruby-core:44371]</a>[Bug <a class="issue tracker-1 status-5 priority-4 priority-default closed" title="Bug: dln_load and rb_w32_check_imported cause segfault in Ruby 1.9.3 for some extension (Closed)" href="https://bugs.ruby-lang.org/issues/6303">#6303</a>]</li>
</ul>