From dds@istlab.dmst.aueb.gr  Tue Feb 18 07:19:36 2003
Return-Path: <dds@istlab.dmst.aueb.gr>
Received: from mx1.FreeBSD.org (mx1.freebsd.org [216.136.204.125])
	by hub.freebsd.org (Postfix) with ESMTP id A6ADF37B401
	for <FreeBSD-gnats-submit@freebsd.org>; Tue, 18 Feb 2003 07:19:36 -0800 (PST)
Received: from istlab.dmst.aueb.gr (istlab.dmst.aueb.gr [195.251.253.207])
	by mx1.FreeBSD.org (Postfix) with ESMTP id 864F443FAF
	for <FreeBSD-gnats-submit@freebsd.org>; Tue, 18 Feb 2003 07:19:35 -0800 (PST)
	(envelope-from dds@istlab.dmst.aueb.gr)
Received: from istlab.dmst.aueb.gr (localhost [127.0.0.1])
	by istlab.dmst.aueb.gr (8.12.6/8.12.6) with ESMTP id h1IFJWC8028888
	for <FreeBSD-gnats-submit@freebsd.org>; Tue, 18 Feb 2003 17:19:32 +0200 (EET)
	(envelope-from dds@istlab.dmst.aueb.gr)
Received: (from dds@localhost)
	by istlab.dmst.aueb.gr (8.12.6/8.12.6/Submit) id h1IFJVOR028887;
	Tue, 18 Feb 2003 17:19:31 +0200 (EET)
Message-Id: <200302181519.h1IFJVOR028887@istlab.dmst.aueb.gr>
Date: Tue, 18 Feb 2003 17:19:31 +0200 (EET)
From: "Diomidis D. Spinellis" <dds@aueb.gr>
Reply-To: "Diomidis D. Spinellis" <dds@aueb.gr>
To: FreeBSD-gnats-submit@freebsd.org
Cc:
Subject: Integer overflow in cksum(1) and sum(1) file size reporting
X-Send-Pr-Version: 3.113
X-GNATS-Notify:

>Number:         48424
>Category:       bin
>Synopsis:       Integer overflow in cksum(1) and sum(1) file size reporting
>Confidential:   no
>Severity:       serious
>Priority:       low
>Responsible:    freebsd-bugs
>State:          closed
>Quarter:        
>Keywords:       
>Date-Required:  
>Class:          sw-bug
>Submitter-Id:   current-users
>Arrival-Date:   Tue Feb 18 07:20:13 PST 2003
>Closed-Date:    Mon Sep 18 19:10:33 GMT 2006
>Last-Modified:  Mon Sep 18 19:10:33 GMT 2006
>Originator:     Diomidis D. Spinellis
>Release:        FreeBSD 4.7-RELEASE-p3 i386
>Organization:
Athens University of Economics and Business
>Environment:
System: FreeBSD istlab.dmst.aueb.gr 4.7-RELEASE-p3 FreeBSD 4.7-RELEASE-p3 #7: Wed Jan 8 16:10:05 EET 2003 dds@istlab.dmst.aueb.gr:/usr/obj/usr/src/sys/ISTLAB i386
>Description:
cksum(1) and sum(1) report an incorrect file size for files with more
than 2**32 bytes.  Performing a checksum operation over the raw device
of a modern >10GB hard disk will easilly exceed this limit.
The reason is the use of a 32-bit integer for counting input bytes.
>How-To-Repeat:
dd if=/dev/zero bs=1m count=10240 | cksum 
10240+0 records in
10240+0 records out
10737418240 bytes transferred in 2344.545524 secs (4579744 bytes/sec)
2532515601 2147483648
(The second number should be 10737418240)
>Fix:
Apply the following patch:

Index: cksum/cksum.c
===================================================================
RCS file: /home/ncvs/src/usr.bin/cksum/cksum.c,v
retrieving revision 1.16
diff -c -r1.16 cksum.c
*** cksum/cksum.c	28 Jul 2002 15:08:23 -0000	1.16
--- cksum/cksum.c	17 Feb 2003 18:38:03 -0000
***************
*** 65,74 ****
  main(int argc, char **argv)
  {
  	int ch, fd, rval;
! 	u_int32_t len, val;
  	char *fn, *p;
! 	int (*cfncn)(int, u_int32_t *, u_int32_t *);
! 	void (*pfncn)(char *, u_int32_t, u_int32_t);
  
  	if ((p = rindex(argv[0], '/')) == NULL)
  		p = argv[0];
--- 65,75 ----
  main(int argc, char **argv)
  {
  	int ch, fd, rval;
! 	u_int32_t val;
! 	u_quad_t len;
  	char *fn, *p;
! 	int (*cfncn)(int, u_int32_t *, u_quad_t *);
! 	void (*pfncn)(char *, u_int32_t, u_quad_t);
  
  	if ((p = rindex(argv[0], '/')) == NULL)
  		p = argv[0];
Index: cksum/crc.c
===================================================================
RCS file: /home/ncvs/src/usr.bin/cksum/crc.c,v
retrieving revision 1.7
diff -c -r1.7 crc.c
*** cksum/crc.c	28 Jul 2002 15:08:23 -0000	1.7
--- cksum/crc.c	17 Feb 2003 18:38:03 -0000
***************
*** 111,121 ****
  u_int32_t crc_total = ~0;			/* The crc over a number of files. */
  
  int
! crc(int fd, u_int32_t *cval, u_int32_t *clen)
  {
  	u_char *p;
  	int nr;
! 	u_int32_t lcrc, len;
  	u_char buf[16 * 1024];
  
  #define	COMPUTE(var, ch)	(var) = (var) << 8 ^ crctab[(var) >> 24 ^ (ch)]
--- 111,122 ----
  u_int32_t crc_total = ~0;			/* The crc over a number of files. */
  
  int
! crc(int fd, u_int32_t *cval, u_quad_t *clen)
  {
  	u_char *p;
  	int nr;
! 	u_int32_t lcrc;
! 	u_quad_t len;
  	u_char buf[16 * 1024];
  
  #define	COMPUTE(var, ch)	(var) = (var) << 8 ^ crctab[(var) >> 24 ^ (ch)]
Index: cksum/crc32.c
===================================================================
RCS file: /home/ncvs/src/usr.bin/cksum/crc32.c,v
retrieving revision 1.8
diff -c -r1.8 crc32.c
*** cksum/crc32.c	28 Jul 2002 15:08:23 -0000	1.8
--- cksum/crc32.c	17 Feb 2003 18:38:03 -0000
***************
*** 98,108 ****
  u_int32_t crc32_total = 0 ;
  
  int
! crc32(int fd, u_int32_t *cval, u_int32_t *clen)
  {
      u_int32_t lcrc = ~0;
      char buf[BUFSIZ], *p ;
!     int len, nr ;
  	
      len = 0 ;
      crc32_total = ~crc32_total ;
--- 98,109 ----
  u_int32_t crc32_total = 0 ;
  
  int
! crc32(int fd, u_int32_t *cval, u_quad_t *clen)
  {
      u_int32_t lcrc = ~0;
      char buf[BUFSIZ], *p ;
!     int nr ;
!     u_quad_t len ;
  	
      len = 0 ;
      crc32_total = ~crc32_total ;
Index: cksum/extern.h
===================================================================
RCS file: /home/ncvs/src/usr.bin/cksum/extern.h,v
retrieving revision 1.5
diff -c -r1.5 extern.h
*** cksum/extern.h	22 Mar 2002 01:19:26 -0000	1.5
--- cksum/extern.h	17 Feb 2003 18:38:05 -0000
***************
*** 37,47 ****
  #include <sys/cdefs.h>
  
  __BEGIN_DECLS
! int	crc(int, u_int32_t *, u_int32_t *);
! void	pcrc(char *, u_int32_t, u_int32_t);
! void	psum1(char *, u_int32_t, u_int32_t);
! void	psum2(char *, u_int32_t, u_int32_t);
! int	csum1(int, u_int32_t *, u_int32_t *);
! int	csum2(int, u_int32_t *, u_int32_t *);
! int	crc32(int, u_int32_t *, u_int32_t *);
  __END_DECLS
--- 37,47 ----
  #include <sys/cdefs.h>
  
  __BEGIN_DECLS
! int	crc(int, u_int32_t *, u_quad_t *);
! void	pcrc(char *, u_int32_t, u_quad_t);
! void	psum1(char *, u_int32_t, u_quad_t);
! void	psum2(char *, u_int32_t, u_quad_t);
! int	csum1(int, u_int32_t *, u_quad_t *);
! int	csum2(int, u_int32_t *, u_quad_t *);
! int	crc32(int, u_int32_t *, u_quad_t *);
  __END_DECLS
Index: cksum/print.c
===================================================================
RCS file: /home/ncvs/src/usr.bin/cksum/print.c,v
retrieving revision 1.6
diff -c -r1.6 print.c
*** cksum/print.c	28 Jul 2002 15:08:23 -0000	1.6
--- cksum/print.c	17 Feb 2003 18:38:05 -0000
***************
*** 44,70 ****
  #include "extern.h"
  
  void
! pcrc(char *fn, u_int32_t val, u_int32_t len)
  {
! 	(void)printf("%lu %lu", (u_long) val, (u_long) len);
  	if (fn)
  		(void)printf(" %s", fn);
  	(void)printf("\n");
  }
  
  void
! psum1(char *fn, u_int32_t val, u_int32_t len)
  {
! 	(void)printf("%lu %lu", (u_long) val, (u_long) (len + 1023) / 1024);
  	if (fn)
  		(void)printf(" %s", fn);
  	(void)printf("\n");
  }
  
  void
! psum2(char *fn, u_int32_t val, u_int32_t len)
  {
! 	(void)printf("%lu %lu", (u_long) val, (u_long) (len + 511) / 512);
  	if (fn)
  		(void)printf(" %s", fn);
  	(void)printf("\n");
--- 44,70 ----
  #include "extern.h"
  
  void
! pcrc(char *fn, u_int32_t val, u_quad_t len)
  {
! 	(void)printf("%lu %qu", (u_long) val, len);
  	if (fn)
  		(void)printf(" %s", fn);
  	(void)printf("\n");
  }
  
  void
! psum1(char *fn, u_int32_t val, u_quad_t len)
  {
! 	(void)printf("%lu %qu", (u_long) val, (len + 1023) / 1024);
  	if (fn)
  		(void)printf(" %s", fn);
  	(void)printf("\n");
  }
  
  void
! psum2(char *fn, u_int32_t val, u_quad_t len)
  {
! 	(void)printf("%lu %qu", (u_long) val, (len + 511) / 512);
  	if (fn)
  		(void)printf(" %s", fn);
  	(void)printf("\n");
Index: cksum/sum1.c
===================================================================
RCS file: /home/ncvs/src/usr.bin/cksum/sum1.c,v
retrieving revision 1.7
diff -c -r1.7 sum1.c
*** cksum/sum1.c	28 Jul 2002 15:08:23 -0000	1.7
--- cksum/sum1.c	17 Feb 2003 18:38:05 -0000
***************
*** 45,53 ****
  #include "extern.h"
  
  int
! csum1(int fd, u_int32_t *cval, u_int32_t *clen)
  {
! 	u_int32_t total;
  	int nr;
  	u_int lcrc;
  	u_char *p;
--- 45,53 ----
  #include "extern.h"
  
  int
! csum1(int fd, u_int32_t *cval, u_quad_t *clen)
  {
! 	u_quad_t total;
  	int nr;
  	u_int lcrc;
  	u_char *p;
Index: cksum/sum2.c
===================================================================
RCS file: /home/ncvs/src/usr.bin/cksum/sum2.c,v
retrieving revision 1.7
diff -c -r1.7 sum2.c
*** cksum/sum2.c	28 Jul 2002 15:08:23 -0000	1.7
--- cksum/sum2.c	17 Feb 2003 18:38:05 -0000
***************
*** 45,53 ****
  #include "extern.h"
  
  int
! csum2(int fd, u_int32_t *cval, u_int32_t *clen)
  {
! 	u_int32_t lcrc, total;
  	int nr;
  	u_char *p;
  	u_char buf[8192];
--- 45,54 ----
  #include "extern.h"
  
  int
! csum2(int fd, u_int32_t *cval, u_quad_t *clen)
  {
! 	u_int32_t lcrc;
! 	u_quad_t total;
  	int nr;
  	u_char *p;
  	u_char buf[8192];
>Release-Note:
>Audit-Trail:
State-Changed-From-To: open->patched 
State-Changed-By: tjr 
State-Changed-When: Thu Mar 27 03:23:48 PST 2003 
State-Changed-Why:  
This has been fixed in -current. 

http://www.freebsd.org/cgi/query-pr.cgi?pr=48424 
State-Changed-From-To: patched->closed 
State-Changed-By: maxim 
State-Changed-When: Mon Sep 18 19:10:15 UTC 2006 
State-Changed-Why:  
Fixed ages ago. 

http://www.freebsd.org/cgi/query-pr.cgi?pr=48424 
>Unformatted:
