From owner-freebsd-bugs@FreeBSD.ORG Thu Oct 20 16:20:05 2011 Return-Path: Delivered-To: freebsd-bugs@hub.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id A46AF1065678 for ; Thu, 20 Oct 2011 16:20:05 +0000 (UTC) (envelope-from gnats@FreeBSD.org) Received: from freefall.freebsd.org (freefall.freebsd.org [IPv6:2001:4f8:fff6::28]) by mx1.freebsd.org (Postfix) with ESMTP id 7C5FE8FC16 for ; Thu, 20 Oct 2011 16:20:05 +0000 (UTC) Received: from freefall.freebsd.org (localhost [127.0.0.1]) by freefall.freebsd.org (8.14.4/8.14.4) with ESMTP id p9KGK51Z041359 for ; Thu, 20 Oct 2011 16:20:05 GMT (envelope-from gnats@freefall.freebsd.org) Received: (from gnats@localhost) by freefall.freebsd.org (8.14.4/8.14.4/Submit) id p9KGK5hd041358; Thu, 20 Oct 2011 16:20:05 GMT (envelope-from gnats) Resent-Date: Thu, 20 Oct 2011 16:20:05 GMT Resent-Message-Id: <201110201620.p9KGK5hd041358@freefall.freebsd.org> Resent-From: FreeBSD-gnats-submit@FreeBSD.org (GNATS Filer) Resent-To: freebsd-bugs@FreeBSD.org Resent-Reply-To: FreeBSD-gnats-submit@FreeBSD.org, Tim Brody Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id 5FFD3106566C for ; Thu, 20 Oct 2011 16:10:14 +0000 (UTC) (envelope-from nobody@FreeBSD.org) Received: from red.freebsd.org (red.freebsd.org [IPv6:2001:4f8:fff6::22]) by mx1.freebsd.org (Postfix) with ESMTP id 3687C8FC0C for ; Thu, 20 Oct 2011 16:10:14 +0000 (UTC) Received: from red.freebsd.org (localhost [127.0.0.1]) by red.freebsd.org (8.14.4/8.14.4) with ESMTP id p9KGADvp005794 for ; Thu, 20 Oct 2011 16:10:13 GMT (envelope-from nobody@red.freebsd.org) Received: (from nobody@localhost) by red.freebsd.org (8.14.4/8.14.4/Submit) id p9KGADxe005793; Thu, 20 Oct 2011 16:10:13 GMT (envelope-from nobody) Message-Id: <201110201610.p9KGADxe005793@red.freebsd.org> Date: Thu, 20 Oct 2011 16:10:13 GMT From: Tim Brody To: freebsd-gnats-submit@FreeBSD.org X-Send-Pr-Version: www-3.1 Cc: Subject: misc/161837: sysinstall has a 32 disk limit X-BeenThere: freebsd-bugs@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: Bug reports List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Thu, 20 Oct 2011 16:20:05 -0000 >Number: 161837 >Category: misc >Synopsis: sysinstall has a 32 disk limit >Confidential: no >Severity: serious >Priority: low >Responsible: freebsd-bugs >State: open >Quarter: >Keywords: >Date-Required: >Class: sw-bug >Submitter-Id: current-users >Arrival-Date: Thu Oct 20 16:20:05 UTC 2011 >Closed-Date: >Last-Modified: >Originator: Tim Brody >Release: 8.20 >Organization: University of Southampton >Environment: n/a >Description: sysinstall calls libdisk/Disk_Names that has a hard-limit of 32 disk devices. On systems (e.g. Sun X4540) with more disks than this some drives will be silently ignored. On the X4540 the missing drives include the 4 bootable devices, making it impossible to install with sysinstall/fdisk (hence severity=high). This problem was first identified 10 years ago when the number was bumped from 20 to 32 - http://www.cz.freebsd.org/pub/FreeBSD-cvs/gnats/conf/24503. Further (but unpatched), sysinstall/devices.c does not free the contents of the disks array so will cause a memory leak. >How-To-Repeat: >Fix: Apply attached patch to libdisk, recompile/reinstall libdisk and sysinstall. Patch attached with submission follows: Index: libdisk.h =================================================================== --- libdisk.h (revision 226570) +++ libdisk.h (working copy) @@ -17,9 +17,6 @@ /* You can define a particular architecture here if you are debugging. */ /* #define P_DEBUG p_sparc64 */ -#define MAX_NO_DISKS 32 -/* Max # of disks Disk_Names() will return */ - #define MAX_SEC_SIZE 2048 /* maximum sector size that is supported */ #define MIN_SEC_SIZE 512 /* the sector size to end sensing at */ Index: disk.c =================================================================== --- disk.c (revision 226570) +++ disk.c (working copy) @@ -190,7 +190,7 @@ char ** Disk_Names() { - int disk_cnt; + int i, disk_cnt; char **disks; int error; size_t listsize; @@ -205,30 +205,36 @@ if (listsize == 0) return (NULL); - disks = malloc(sizeof *disks * (1 + MAX_NO_DISKS)); - if (disks == NULL) + disk1 = disklist = (char *)calloc(listsize + 1, sizeof *disklist); + if (disklist == NULL) return NULL; - disk1 = disklist = (char *)malloc(listsize + 1); - if (disklist == NULL) { - free(disks); - return NULL; - } - memset(disks,0,sizeof *disks * (1 + MAX_NO_DISKS)); - memset(disklist, 0, listsize + 1); + error = sysctlbyname("kern.disks", disklist, &listsize, NULL, 0); if (error || disklist[0] == 0) { free(disklist); - free(disks); return NULL; } - for (disk_cnt = 0; disk_cnt < MAX_NO_DISKS; disk_cnt++) { + + disk_cnt = 1; + for (i = 0; i < listsize; ++i) { + if (disklist[i] == ' ') + disk_cnt++; + } + + disks = calloc(disk_cnt + 1, sizeof *disks); + if (disks == NULL) { + free(disklist); + return NULL; + } + + for (i = 0; i < disk_cnt; ++i) { disk2 = strsep(&disk1, " "); if (disk2 == NULL) break; - disks[disk_cnt] = strdup(disk2); - if (disks[disk_cnt] == NULL) { - for (disk_cnt--; disk_cnt >= 0; disk_cnt--) - free(disks[disk_cnt]); + disks[i] = strdup(disk2); + if (disks[i] == NULL) { + for (i--; i >= 0; i--) + free(disks[i]); free(disklist); free(disks); return (NULL); >Release-Note: >Audit-Trail: >Unformatted: