Nmap Development mailing list archives

Looking at nse_pcrelib.cc file using clang static file analyzer.


From: James Rogers <jamesmrogers () gmail com>
Date: Thu, 31 May 2012 16:12:31 -0400

Examining the Clang output in more detail.  Noticing a few issues
which could be errors.

Logic error     Dereference of null pointer     nse_pcrelib.cc  234     
Logic error     Dereference of null pointer     nse_pcrelib.cc  272     

This does look like an error that could cause a crash.   On line 230
ud is passed as a reference into Lpcre_getargs() to be assigned a
value.  This appears that it can error out and return a NULL in the
function, but this is never checked on return, and ud->ncapt is
dereferenced in that case.

Same thing happens on line 264.


Memory Error    Memory leak     nse_pcrelib.cc  143     

This doesn't appear too bad, because nmap doesn't run very long.

static int Lpcre_match_generic(lua_State *L, Lpcre_push_matches push_matches)
222     {
223     int res;
224     const char *text;
225     pcre2 *ud;
226     size_t elen;
227     int startoffset;
228     int eflags = luaL_optint(L, 4, 0);
229     
230     Lpcre_getargs(L, &ud, &text, &elen);
231     startoffset = get_startoffset(L, 3, elen);
232     
233     res = pcre_exec(ud->pr, ud->extra, text, (int)elen, startoffset, eflags,
234     ud->match, (ud->ncapt + 1) * 3);
        
Access to field 'ncapt' results in a dereference of a null pointer
(loaded from variable 'ud')
235     if (res >= 0) {
236     lua_pushnumber(L, (lua_Number) ud->match[0] + 1);
237     lua_pushnumber(L, (lua_Number) ud->match[1]);
238     (*push_matches)(L, text, ud);
239     return 3;
240     }
241     return 0;
242     }


264     Lpcre_getargs(L, &ud, &text, &len);
265     luaL_checktype(L, 3, LUA_TFUNCTION);
266     
267     if(maxmatch > 0) /* this must be stated in the docs */
        
1-Taking false branch
268     limit = 1;
269     
270     while (!limit || nmatch < maxmatch) {
        
2-Loop condition is true. Entering loop body
271     res = pcre_exec(ud->pr, ud->extra, text, (int)len, startoffset, eflags,
272     ud->match, (ud->ncapt + 1) * 3);
        
3-Access to field 'ncapt' results in a dereference of a null pointer
(loaded from variable 'ud')
273     if (res >= 0) {



Lpcre_getargs
Defined as a function in:

    nse_pcrelib.cc, line 145

Referenced (in 1 files total) in:

    nse_pcrelib.cc:
        line 145
        line 230
        line 264


145 static void Lpcre_getargs(lua_State *L, pcre2 **pud, const char **text,
146                 size_t *text_len)
147 {
148         *pud = (pcre2 *)luaL_checkudata(L, 1, pcre_handle);
149         if(*pud == NULL)
150                 (void)luaL_argerror(L, 1, ("compiled regexp expected"));
151         *text = luaL_checklstring(L, 2, text_len);
152 }


Memory leak:

106     static int Lpcre_comp(lua_State *L)
107     {
108     char buf[256];
109     const char *error;
110     int erroffset;
111     pcre2 *ud;
112     char *pattern = strdup(luaL_checkstring(L, 1));
        
1 - Memory is allocated
113     int cflags = luaL_optint(L, 2, 0);
114     const unsigned char *tables = NULL;
115     
116     if(lua_gettop(L) > 2 && !lua_isnil(L, 3))
        
2 - Taking false branch
117     tables = Lpcre_maketables(L, 3);
118     if(tables == NULL)
        
3 - Taking true branch
119     luaL_error(L, "PCRE compilation failed");
120     
121     ud = (pcre2*)lua_newuserdata(L, sizeof(pcre2));
122     luaL_getmetatable(L, pcre_handle);
123     (void)lua_setmetatable(L, -2);
124     ud->match = NULL;
125     ud->extra = NULL;
126     ud->tables = tables; /* keep this for eventual freeing */
127     
128     ud->pr = pcre_compile(pattern, cflags, &error, &erroffset, tables);
129     if(!ud->pr) {
        
4 - Taking false branch
130     (void)Snprintf(buf, 255, "%s (pattern offset: %d)", error, erroffset+1);
131     /* show offset 1-based as it's common in Lua */
132     luaL_error(L, buf);
133     }
134     
135     ud->extra = pcre_study(ud->pr, 0, &error);
136     if(error) luaL_error(L, error);
        
5 - Taking false branch
137     
138     pcre_fullinfo(ud->pr, ud->extra, PCRE_INFO_CAPTURECOUNT, &ud->ncapt);
139     /* need (2 ints per capture, plus one for substring match) * 3/2 */
140     ud->match = (int *) safe_malloc((ud->ncapt + 1) * 3 * sizeof(int));
141     
142     return 1;
143     }
        
6 - Memory is never released; potential leak of memory pointed to by 'pattern'
_______________________________________________
Sent through the nmap-dev mailing list
http://cgi.insecure.org/mailman/listinfo/nmap-dev
Archived at http://seclists.org/nmap-dev/


Current thread: