CVE:CVE-2009-2404
CNNVD:CNNVD-200908-533
网络安全服务(NSS)是一套用于跨平台开发启用了安全功能的客户端和服务器应用的库，用NSS编译的应用可以支持SSLv2、SSLv3、TLS等安全标准。
Firefox等浏览器所使用的用于匹配证书中公用名的NSS库正则表达式解析器中存在堆溢出。恶意网站可以提供特制的证书触发堆溢出，导致崩溃或以运行浏览器用户的权限执行任意指令。
以下是NSS库中的有漏洞代码段：
security/nss/lib/util/portreg.c:
141 static int
142 _handle_union(const char *str， const char *exp， PRBool case_insensitive)
143 {
144  char *e2 = (char *) PORT_Alloc(sizeof(char)*strlen(exp));
145  register int t，p2，p1 = 1;
146  int cp;
147
148  while(1) {
149   for(cp=1;exp[cp] != ')';cp++)
150    if(exp[cp] == '\\')
151     ++cp;
152   for(p2 = 0;(exp[p1] != '|') & & (p1 != cp);p1++，p2++) {
153    if(exp[p1] == '\\')
154     e2[p2++] = exp[p1++];
155    e2[p2] = exp[p1];
156   }
157   for (t=cp+1; ((e2[p2] = exp[t]) != 0); ++t，++p2) {}
158   if(_shexp_match(str，e2， case_insensitive) == MATCH) {
159    PORT_Free(e2);
160    return MATCH;
161   }
162   if(p1 == cp) {
163    PORT_Free(e2);
164    return NOMATCH;
165   }
166   else ++p1;
167  }
168 }
基于144行的strlen()执行malloc，但在154行")"之前一直进行拷贝。可通过在传送给两级之上父函数的字符串中包含"~"来替换这个字符串中的"\0"字符：
263 static int
264 port_RegExpMatch(const char *str， const char *xp， PRBool case_insensitive)
{
265  register int x;
266  char *exp = 0;
267
268  exp = PORT_Strdup(xp);
269
270  if(!exp)
271   return 1;
272
273  for(x=strlen(exp)-1;x;--x) {
274   if((exp[x] == '~') & & (exp[x-1] != '\\')) {
275    exp[x] = '\0';
276    if(_shexp_match(str， &exp[++x]， case_insensitive) == MATCH)
277     goto punt;
278    break;
279   }
280  }
281  if(_shexp_match(str，exp， case_insensitive) == MATCH) {
282   PORT_Free(exp);
283   return 0;
284  }
285
286 punt:
287  PORT_Free(exp);
288  return 1;
289 }
类似于(foo~bar)的字符串会分配strlen(foo)，然后在所分配的内存后覆盖bar个字节。
solution:Upgrade mozilla network_security_services to a higher version than 3.12.3,and avoid the version 3.12.3