漏洞信息详情
FreeBSD I386_Set_LDT()多个本地拒绝服务漏洞
- CNNVD编号:CNNVD-200609-428
- 危害等级: 中危
- CVE编号:
CVE-2006-4178
- 漏洞类型:
边界条件错误
- 发布时间:
2006-09-25
- 威胁类型:
本地
- 更新时间:
2006-09-27
- 厂 商:
freebsd - 漏洞来源:
Adriano Lima adria… -
漏洞简介
FreeBSD就是一种运行在Intel平台上、可以自由使用的开放源码Unix类系统。
FreeBSD中的i386_set_ldt()调用允许用户系统的程序动态管理每个进程的本地描述符表。由于使用了有符号的整数且缺少输入验证,内核中bzero可能会被要求处理很大的参数,漏洞代码如下:
415 int error = 0, i;
416 int largest_ld;
..
449 largest_ld = uap->start + uap->num;
450 if (largest_ld > pldt->ldt_len)
451 largest_ld = pldt->ldt_len;
452 i = largest_ld – uap->start;
453 bzero( &((union descriptor *)(pldt->ldt_base))[uap->start],
454 sizeof(union descriptor) * i);
在415和416行,\”i\”和\”largest_ld\”变量都是有符的整数。在449行,同时添加了uap->start和uap->num,这两个变量都是用户控制的且没有经过正确的检查。在452行,可以将\”i\”设置为很大的负值,导致在453行以很大的长度参数调用bzero。无效的内存访问会导致内核忙碌。
i386_set_ldt()系统调用会在LDT中设置当前进程的i386描述符列表。该调用接受一个开始选择器数(start)、包含有将要设置描述符的内存数组(descs),以及将要设置的条目数(num)。用户在通过sysarch()调用i386_set_ldt()时,如果将start参数设置为很低的整数值、将descs设置为非空的值,并将num设置为很高的无符整数值,就会触发largest_ld和descs_size(533和540行)中的整数溢出,导致耗尽所有可用的系统资源(541行)。此外还可以将start参数设置为低整数值、descs设置为空、num设置为很高的无符整数值触发largest_ld(515行)中的整数溢出,导致删除系统中的敏感数据(519和520行)。有漏洞的函数如下:
476 static int
477 i386_set_ldt(td, args)
478 struct thread *td;
479 char *args;
480 {
481 int error = 0, i;
482 int largest_ld;
483 struct mdproc *mdp = &td->td_proc->p_md;
484 struct proc_ldt *pldt = 0;
485 struct i386_ldt_args ua, *uap = &ua;
486 union descriptor *descs, *dp;
487 int descs_size;
488
489 if ((error = copyin(args, uap, sizeof(struct
i386_ldt_args))) < 0)
490 return(error);
491
492 #ifdef DEBUG
493 printf(\”i386_set_ldt: start=\\%d num=\\%d descs=\\%p\n\”,
494 uap->start, uap->num, (void *)uap->descs);
495 #endif
496
497 if (uap->descs == NULL) {
498 /* Free descriptors */
499 if (uap->start == 0 & & uap->num == 0) {
500 /*
501 * Treat this as a special case, so userland
needn\’\’t
502 * know magic number NLDT.
503 */
504 uap->start = NLDT;
505 uap->num = MAX_LD – NLDT;
506 }
507 if (uap->start <= LUDATA_SEL || uap->num <= 0)508 return (EINVAL);
509 mtx_lock_spin( &sched_lock);
510 pldt = mdp->md_ldt;
511 if (pldt == NULL || uap->start >= pldt->ldt_len) {
512 mtx_unlock_spin( &sched_lock);
513 return (0);
514 }
515 largest_ld = uap->start + uap->num;
516 if (largest_ld > pldt->ldt_len)
517 largest_ld = pldt->ldt_len;
518 i = largest_ld – uap->start;
519 bzero( &((union descriptor
*)(pldt->ldt_base))[uap->start],
520 sizeof(union descriptor) * i);
521 mtx_unlock_spin( &sched_lock);
522 return (0);
523 }
524
525 if (!(uap->start == LDT_AUTO_ALLOC & & uap->num == 1)) {
526 /* complain a for a while if using old methods */
527 if (ldt_warnings++ < NUM_LDT_WARNINGS) {
528 printf(\”Warning: pid \\%d used static ldt
allocation.\n\”,
529 td->td_proc->p_pid);
530 printf(\”See the i386_set_ldt man page for
more info\n\”);
531 }
532 /* verify range of descriptors to modify */
533 largest_ld = uap->start + uap->num;
534 if (uap->start >= MAX_LD ||
535 uap->num < 0 || largest_ld > MAX_LD) {
536 return (EINVAL);
537 }
538 }
539
540 descs_size = uap->num * sizeof(union descriptor);
541 descs = (union descriptor *)kmem_alloc(kernel_map, descs_size);
542 if (descs == NULL)
543 return (ENOMEM);
544 error = copyin(uap->descs
参考网址
来源: IDEFENSE
名称: 20060923 FreeBSD i386_set_ldt Integer Signedness Vulnerability
链接:http://www.idefense.com/intelligence/vulnerabilities/display.php?id=415
来源: BID
名称: 20158
链接:http://www.securityfocus.com/bid/20158
来源: BUGTRAQ
名称: 20060925 iDefense Security Advisory 09.23.06: FreeBSD i386_set_ldt Integer Signedness Vulnerability
链接:http://www.securityfocus.com/archive/1/archive/1/446946/100/0/threaded
来源: SECTRACK
名称: 1016927
链接:http://securitytracker.com/id?1016927
来源: SECUNIA
名称: 22064