NetBSD Problem Report #43354

From www@NetBSD.org  Tue May 25 19:18:33 2010
Return-Path: <www@NetBSD.org>
Received: from mail.netbsd.org (mail.netbsd.org [204.152.190.11])
	by www.NetBSD.org (Postfix) with ESMTP id 7F32B63B879
	for <gnats-bugs@gnats.NetBSD.org>; Tue, 25 May 2010 19:18:32 +0000 (UTC)
Message-Id: <20100525191831.EAFFB63B873@www.NetBSD.org>
Date: Tue, 25 May 2010 19:18:31 +0000 (UTC)
From: rg@g-pb.de
Reply-To: rg@g-pb.de
To: gnats-bugs@NetBSD.org
Subject: disklabel -i limits partition size to 2**31 on input from terminal
X-Send-Pr-Version: www-1.0

>Number:         43354
>Category:       bin
>Synopsis:       disklabel -i limits partition size to 2**31 on input from terminal
>Confidential:   no
>Severity:       non-critical
>Priority:       medium
>Responsible:    bin-bug-people
>State:          closed
>Class:          sw-bug
>Submitter-Id:   net
>Arrival-Date:   Tue May 25 19:20:00 +0000 2010
>Closed-Date:    Sat Jun 12 04:25:14 +0000 2010
>Last-Modified:  Sat Jun 12 04:25:14 +0000 2010
>Originator:     Rainer Glaschick
>Release:        netbsd 5.1_RC1
>Organization:
>Environment:
NetBSD kerneu 5.1_RC1 NetBSD 5.1_RC1 (GENERIC) #0: Sat Apr 24 23:26:09 UTC 2010  builds@b7.netbsd.org:/home/builds/ab/netbsd-5-1-RC1/i386/201004250032Z-obj/home/builds/ab/netbsd-5-1-RC1/src/sys/arch/i386/compile/GENERIC i386

>Description:
Using disklabel -i for a disk with more than 1 TByte, a partition cannot be set for more than 1 TByte interactively, i.e. the number of sectors is limited to 2**31, whether given as sectors, cylinders or Megabytes.

Here is a (Cyl. removed for readability) sample session:

kerneu: disklabel -i wd1
partition> P
16 partitions:
#        size    offset     fstype [fsize bsize cpg/sgs]
 c: 2930277105        63     unused      0     0        
 d: 2930277168         0     unused      0     0        
partition> a
Filesystem type [?] [4.2BSD]:
Start offset ('x' to start after partition 'x') [0.0625c, 63s, 0.0307617M]:
Partition size ('$' for all remaining) [0c, 0s, 0M]: $
 a: 2930277105        63     4.2BSD      0     0     0  
partition> a
Filesystem type [?] [4.2BSD]:
Start offset ('x' to start after partition 'x') [0.0625c, 63s, 0.0307617M]:
Partition size ('$' for all remaining) [2.90702e+06c, 2930277105s, 1.4308e+06M]: 2200000000s
 a: 2147483648        63     4.2BSD      0     0     0  


>How-To-Repeat:
Use a disk with more than 1TB, allocate all to a partition, and try to enter interactively a size of about 2200000000 sectors.
>Fix:
Write disklabel to disk, edit file, and restore

>Release-Note:

>Audit-Trail:
From: David Holland <dholland-bugs@netbsd.org>
To: gnats-bugs@NetBSD.org
Cc: 
Subject: Re: port-i386/43354: disklabel -i limits partition size to 2**31
	on input from terminal
Date: Thu, 27 May 2010 06:37:17 +0000

 On Tue, May 25, 2010 at 07:20:01PM +0000, rg@g-pb.de wrote:
  > Using disklabel -i for a disk with more than 1 TByte, a partition
  > cannot be set for more than 1 TByte interactively, i.e. the number
  > of sectors is limited to 2**31, whether given as sectors, cylinders
  > or Megabytes.

 Here's a candidate patch. I can't test it as I don't have a disk large
 enough, but it at least compiles. The first patch is for current, the
 second for 5.x.

 Index: interact.c
 ===================================================================
 RCS file: /cvsroot/src/sbin/disklabel/interact.c,v
 retrieving revision 1.33
 diff -u -p -r1.33 interact.c
 --- interact.c	28 Nov 2009 10:52:10 -0000	1.33
 +++ interact.c	27 May 2010 06:15:23 -0000
 @@ -67,7 +67,7 @@ static int	getinput(const char *, const 
  static int	alphacmp(const void *, const void *);
  static void	defnum(struct disklabel *, char *, uint32_t);
  static void	dumpnames(const char *, const char * const *, size_t);
 -static int	getnum(struct disklabel *, char *, int);
 +static intmax_t	getnum(struct disklabel *, char *, intmax_t);

  static int rounding = 0;	/* sector rounding */
  static int chaining = 0;	/* make partitions contiguous */
 @@ -444,6 +444,7 @@ static void
  cmd_part(struct disklabel *lp, char *s, int fd)
  {
  	int	i;
 +	intmax_t im;
  	char	line[BUFSIZ];
  	char	def[BUFSIZ];
  	int	part;
 @@ -503,14 +504,15 @@ cmd_part(struct disklabel *lp, char *s, 
  				    cp[line[0] - 'a'].p_size;
  			}
  		} else {
 -			if ((i = getnum(lp, line, 0)) == -1 || i < 0) {
 +			if ((im = getnum(lp, line, 0)) == -1 || im < 0) {
  				printf("Bad offset `%s'\n", line);
  				continue;
 -			} else if ((uint32_t)i > lp->d_secperunit) {
 +			} else if (im > 0xffffffffLL ||
 +				   (uint32_t)im > lp->d_secperunit) {
  				printf("Offset `%s' out of range\n", line);
  				continue;
  			}
 -			p->p_offset = i;
 +			p->p_offset = (uint32_t)im;
  		}
  		break;
  	}
 @@ -522,16 +524,16 @@ cmd_part(struct disklabel *lp, char *s, 
  			return;
  		else if (i == 0)
  			break;
 -		if ((i = getnum(lp, line, lp->d_secperunit - p->p_offset))
 +		if ((im = getnum(lp, line, lp->d_secperunit - p->p_offset))
  		    == -1) {
  			printf("Bad size `%s'\n", line);
  			continue;
 -		} else if
 -		    ((i + p->p_offset) > lp->d_secperunit) {
 +		} else if (im > 0xffffffffLL ||
 +			   (im + p->p_offset) > lp->d_secperunit) {
  			printf("Size `%s' out of range\n", line);
  			continue;
  		}
 -		p->p_size = i;
 +		p->p_size = im;
  		break;
  	}

 @@ -708,15 +710,15 @@ defnum(struct disklabel *lp, char *buf, 
  }


 -static int
 -getnum(struct disklabel *lp, char *buf, int max)
 +static intmax_t
 +getnum(struct disklabel *lp, char *buf, intmax_t defaultval)
  {
  	char	*ep;
  	double	 d;
 -	int	 rv;
 +	intmax_t rv;

 -	if (max && buf[0] == '$' && buf[1] == 0)
 -		return max;
 +	if (defaultval && buf[0] == '$' && buf[1] == 0)
 +		return defaultval;

  	d = strtod(buf, &ep);
  	if (buf == ep)
 @@ -729,32 +731,32 @@ getnum(struct disklabel *lp, char *buf, 
  	case '\0':
  	case 's':
  	case 'S':
 -		rv = (int) d;
 +		rv = (intmax_t) d;
  		break;

  	case 'c':
  	case 'C':
 -		rv = (int) (d * lp->d_secpercyl);
 +		rv = (intmax_t) (d * lp->d_secpercyl);
  		break;

  	case 'k':
  	case 'K':
 -		rv =  (int) (d * 1024 / lp->d_secsize);
 +		rv =  (intmax_t) (d * 1024 / lp->d_secsize);
  		break;

  	case 'm':
  	case 'M':
 -		rv =  (int) (d * 1024 * 1024 / lp->d_secsize);
 +		rv =  (intmax_t) (d * 1024 * 1024 / lp->d_secsize);
  		break;

  	case 'g':
  	case 'G':
 -		rv =  (int) (d * 1024 * 1024 * 1024 / lp->d_secsize);
 +		rv =  (intmax_t) (d * 1024 * 1024 * 1024 / lp->d_secsize);
  		break;

  	case 't':
  	case 'T':
 -		rv =  (int) (d * 1024 * 1024 * 1024 * 1024 / lp->d_secsize);
 +		rv =  (intmax_t) (d * 1024 * 1024 * 1024 * 1024 / lp->d_secsize);
  		break;

  	default:




    ------------


 Index: interact.c
 ===================================================================
 RCS file: /cvsroot/src/sbin/disklabel/interact.c,v
 retrieving revision 1.30
 diff -u -p -r1.30 interact.c
 --- interact.c	26 Nov 2006 16:16:31 -0000	1.30
 +++ interact.c	27 May 2010 06:35:17 -0000
 @@ -72,7 +72,7 @@ static int	getinput(const char *, const 
  static int	alphacmp(const void *, const void *);
  static void	defnum(struct disklabel *, char *, uint32_t);
  static void	dumpnames(const char *, const char * const *, size_t);
 -static int	getnum(struct disklabel *, char *, int);
 +static intmax_t	getnum(struct disklabel *, char *, intmax_t);

  static int rounding = 0;	/* sector rounding */
  static int chaining = 0;	/* make partitions contiguous */
 @@ -449,6 +449,7 @@ static void
  cmd_part(struct disklabel *lp, char *s, int fd)
  {
  	int	i;
 +	intmax_t im;
  	char	line[BUFSIZ];
  	char	def[BUFSIZ];
  	int	part;
 @@ -508,14 +509,15 @@ cmd_part(struct disklabel *lp, char *s, 
  				    cp[line[0] - 'a'].p_size;
  			}
  		} else {
 -			if ((i = getnum(lp, line, 0)) == -1) {
 +			if ((im = getnum(lp, line, 0)) == -1 || im < 0) {
  				printf("Bad offset `%s'\n", line);
  				continue;
 -			} else if (i > lp->d_secperunit) {
 +			} else if (im > 0xffffffffLL ||
 +				   (uint32_t)im > lp->d_secperunit) {
  				printf("Offset `%s' out of range\n", line);
  				continue;
  			}
 -			p->p_offset = i;
 +			p->p_offset = (uint32_t)im;
  		}
  		break;
  	}
 @@ -527,16 +529,16 @@ cmd_part(struct disklabel *lp, char *s, 
  			return;
  		else if (i == 0)
  			break;
 -		if ((i = getnum(lp, line, lp->d_secperunit - p->p_offset))
 +		if ((im = getnum(lp, line, lp->d_secperunit - p->p_offset))
  		    == -1) {
  			printf("Bad size `%s'\n", line);
  			continue;
 -		} else if
 -		    ((i + p->p_offset) > lp->d_secperunit) {
 +		} else if (im > 0xffffffffLL ||
 +			   (im + p->p_offset) > lp->d_secperunit) {
  			printf("Size `%s' out of range\n", line);
  			continue;
  		}
 -		p->p_size = i;
 +		p->p_size = im;
  		break;
  	}

 @@ -713,15 +715,15 @@ defnum(struct disklabel *lp, char *buf, 
  }


 -static int
 -getnum(struct disklabel *lp, char *buf, int max)
 +static intmax_t
 +getnum(struct disklabel *lp, char *buf, intmax_t defaultval)
  {
  	char	*ep;
  	double	 d;
 -	int	 rv;
 +	intmax_t rv;

 -	if (max && buf[0] == '$' && buf[1] == 0)
 -		return max;
 +	if (defaultval && buf[0] == '$' && buf[1] == 0)
 +		return defaultval;

  	d = strtod(buf, &ep);
  	if (buf == ep)
 @@ -734,32 +736,32 @@ getnum(struct disklabel *lp, char *buf, 
  	case '\0':
  	case 's':
  	case 'S':
 -		rv = (int) d;
 +		rv = (intmax_t) d;
  		break;

  	case 'c':
  	case 'C':
 -		rv = (int) (d * lp->d_secpercyl);
 +		rv = (intmax_t) (d * lp->d_secpercyl);
  		break;

  	case 'k':
  	case 'K':
 -		rv =  (int) (d * 1024 / lp->d_secsize);
 +		rv =  (intmax_t) (d * 1024 / lp->d_secsize);
  		break;

  	case 'm':
  	case 'M':
 -		rv =  (int) (d * 1024 * 1024 / lp->d_secsize);
 +		rv =  (intmax_t) (d * 1024 * 1024 / lp->d_secsize);
  		break;

  	case 'g':
  	case 'G':
 -		rv =  (int) (d * 1024 * 1024 * 1024 / lp->d_secsize);
 +		rv =  (intmax_t) (d * 1024 * 1024 * 1024 / lp->d_secsize);
  		break;

  	case 't':
  	case 'T':
 -		rv =  (int) (d * 1024 * 1024 * 1024 * 1024 / lp->d_secsize);
 +		rv =  (intmax_t) (d * 1024 * 1024 * 1024 * 1024 / lp->d_secsize);
  		break;

  	default:


 -- 
 David A. Holland
 dholland@netbsd.org

Responsible-Changed-From-To: port-i386-maintainer->bin-bug-people
Responsible-Changed-By: dholland@NetBSD.org
Responsible-Changed-When: Thu, 27 May 2010 06:41:06 +0000
Responsible-Changed-Why:
problem is not i386-specific


From: Rainer Glaschick <rg@g-pb.de>
To: gnats-bugs@NetBSD.org
Cc: 
Subject: Re: port-i386/43354: disklabel -i limits partition size to 2**31
 on input from terminal
Date: Fri, 28 May 2010 06:58:52 +0200

 The binary compiled by David for me now does it right;
 tried it interactively with sectors, cylinders and megabyte,
 and re-wrote the disklabel successfully.

 Bug can be closed from my point of view.

 --=20
 Rainer Glaschick
 email: rg@g-pb.de
 Paderborn, Germany
 Pers=F6nliche nicht=F6ffentliche Nachricht / personal private message

From: "David A. Holland" <dholland@netbsd.org>
To: gnats-bugs@gnats.NetBSD.org
Cc: 
Subject: PR/43354 CVS commit: src/sbin/disklabel
Date: Fri, 28 May 2010 07:40:53 +0000

 Module Name:	src
 Committed By:	dholland
 Date:		Fri May 28 07:40:53 UTC 2010

 Modified Files:
 	src/sbin/disklabel: interact.c

 Log Message:
 Change getnum() to use intmax_t instead of int, so it doesn't overflow
 between 2^31 and 2^32. Adjust call sites accordingly. PR 43354.


 To generate a diff of this commit:
 cvs rdiff -u -r1.33 -r1.34 src/sbin/disklabel/interact.c

 Please note that diffs are not public domain; they are subject to the
 copyright notices on the relevant files.

State-Changed-From-To: open->pending-pullups
State-Changed-By: dholland@NetBSD.org
State-Changed-When: Sat, 29 May 2010 18:17:22 +0000
State-Changed-Why:
pullup-5 #1410


From: Jeff Rizzo <riz@netbsd.org>
To: gnats-bugs@gnats.NetBSD.org
Cc: 
Subject: PR/43354 CVS commit: [netbsd-5] src/sbin/disklabel
Date: Sat, 12 Jun 2010 01:11:42 +0000

 Module Name:	src
 Committed By:	riz
 Date:		Sat Jun 12 01:11:42 UTC 2010

 Modified Files:
 	src/sbin/disklabel [netbsd-5]: interact.c

 Log Message:
 Pull up following revision(s) (requested by dholland in ticket #1410):
 	sbin/disklabel/interact.c: revision 1.34
 Change getnum() to use intmax_t instead of int, so it doesn't overflow
 between 2^31 and 2^32. Adjust call sites accordingly. PR 43354.


 To generate a diff of this commit:
 cvs rdiff -u -r1.30 -r1.30.26.1 src/sbin/disklabel/interact.c

 Please note that diffs are not public domain; they are subject to the
 copyright notices on the relevant files.

State-Changed-From-To: pending-pullups->closed
State-Changed-By: dholland@NetBSD.org
State-Changed-When: Sat, 12 Jun 2010 04:25:14 +0000
State-Changed-Why:
Pulled up.


>Unformatted:

NetBSD Home
NetBSD PR Database Search

(Contact us) $NetBSD: query-full-pr,v 1.39 2013/11/01 18:47:49 spz Exp $
$NetBSD: gnats_config.sh,v 1.8 2006/05/07 09:23:38 tsutsui Exp $
Copyright © 1994-2007 The NetBSD Foundation, Inc. ALL RIGHTS RESERVED.