近期由於工作的原因接觸到了openldap的開源庫,在一次偶然的代碼review的情況下發現了一個內存泄漏的bug。對,不是測試發現的,是代碼審覈看出來的。
問題代碼
該項目github源碼路徑爲:https://github.com/openldap/openldap/blob/OPENLDAP_REL_ENG_2_4_49/libraries/liblunicode/ucstr.c
爲方便看這裏貼出來關鍵部分代碼:
struct berval * UTF8bvnormalize(
struct berval *bv,
struct berval *newbv,
unsigned flags,
void *ctx )
{
int i, j, len, clen, outpos, ucsoutlen, outsize, last;
char *out, *outtmp, *s;
ac_uint4 *ucs, *p, *ucsout;
static unsigned char mask[] = {
0, 0x7f, 0x1f, 0x0f, 0x07, 0x03, 0x01 };
unsigned casefold = flags & LDAP_UTF8_CASEFOLD;
unsigned approx = flags & LDAP_UTF8_APPROX;
if ( bv == NULL ) {
return NULL;
}
s = bv->bv_val;
len = bv->bv_len;
if ( len == 0 ) {
return ber_dupbv_x( newbv, bv, ctx );
}
/* 當newbv爲NULL時動態分配了內存 */
if ( !newbv ) {
newbv = ber_memalloc_x( sizeof(struct berval), ctx );
if ( !newbv ) return NULL;
}
/* Should first check to see if string is already in proper
* normalized form. This is almost as time consuming as
* the normalization though.
*/
/* finish off everything up to character before first non-ascii */
if ( LDAP_UTF8_ISASCII( s ) ) {
if ( casefold ) {
outsize = len + 7;
out = (char *) ber_memalloc_x( outsize, ctx );
if ( out == NULL ) {
return NULL; /* 異常退出未釋放newbv */
}
...
}
...
}
...
}
如註釋中所描述的,UTF8bvnormalize()函數中類似的異常return還有好幾處!
創建bug
作爲一名基於百度開發的程序員,熟練的鍵入ldap並打開openldap的官網:https://www.openldap.org/,憑藉着未過四級的優異英文水平,很快在首頁上找到了bug跟蹤入口:
進去之後按提示,依次【File a Bug】,選擇問題庫【Open LDAP】,填寫title Bug 9198 - libraries: memory leak in UTF8bvnormalize()及一些詳細信息。
提交patch
從github上面clone下來openldap的源碼,checkout到發現問題的最新版OPENLDAP_REL_ENG_2_4_49,修改之後commit一下。
使用如下命令生成一個補丁:
git format-patch HEAD^
意爲用當前最新的一次commit id的代碼生成了補丁,生成的補丁就在當前目錄下,名字類似這樣的:0001-fix-Bug-9198-libraries-memory-leak-in-UTF8bvnormaliz.patch 。
再回到之前創建bug的頁面,點【Add an attachment】將自己做好的補丁提交上去,備註必要信息,bug狀態改成FIX即可。
在bug頁面:https://bugs.openldap.org/show_bug.cgi?id=9198 可以查看我到提交的補丁。
如果審覈通過的話,大概會被合入到最新分支吧。