Subject: kern/28471: Sign extension issue in cd9660
To: None <kern-bug-people@netbsd.org, gnats-admin@netbsd.org,>
From: Rhialto <rhialto@azenomei.knuffel.net>
List: netbsd-bugs
Date: 11/29/2004 23:45:01
>Number:         28471
>Category:       kern
>Synopsis:       Sign extension issue in cd9660
>Confidential:   no
>Severity:       non-critical
>Priority:       medium
>Responsible:    kern-bug-people
>State:          open
>Class:          sw-bug
>Submitter-Id:   net
>Arrival-Date:   Mon Nov 29 23:45:01 +0000 2004
>Originator:     Rhialto
>Release:        NetBSD 2.0_BETA
>Organization:
>Environment:
System: NetBSD loelappie.falu.nl 2.0_BETA NetBSD 2.0_BETA (LOELAPPIE) #8: Wed Aug 11 18:22:58 CEST 2004 root@loelappie.falu.nl:/usr/src/sys/arch/i386/compile/LOELAPPIE i386
Architecture: i386
Machine: i386
>Description:
	If you use a version of mkisofs that can create files between
	2G and 4G (version 2.01 and upwards), the file size gets sign-
	extended on 64-bit archs.

	This is because "ip->i_size = isonum_733(isodir->size);" performs
	sign extension since ip->i_size (unsigned long) is bigger than int.

	I checked that the relevant code in 2.0-release is the same.

>How-To-Repeat:
	As above.
>Fix:
	I propose the following patch to bring the code in line with the
	comments. In principle it should be checked that other uses of 
	isonum_733() are not negatively impacted (pun not intended) but
	if the comments accurately reflect the standard, they should not be.

	Furthermore the source used u_int16t and u_int32t in code that
	was apparently never compiled, but these types were not
	defined. I'm fixing that too.

	I compile-tested this on 2.0_BETA/i386 but the principle was
	tested on 1.6.2/alpha.

--- iso.h.orig	2004-11-30 00:19:48.000000000 +0100
+++ iso.h	2004-11-30 00:16:53.000000000 +0100
@@ -170,12 +170,12 @@
 
 static __inline int isonum_711 __P((u_char *)) __attribute__ ((unused));
 static __inline int isonum_712 __P((char *)) __attribute__ ((unused));
-static __inline int isonum_721 __P((u_char *)) __attribute__ ((unused));
-static __inline int isonum_722 __P((u_char *)) __attribute__ ((unused));
-static __inline int isonum_723 __P((u_char *)) __attribute__ ((unused));
-static __inline int isonum_731 __P((u_char *)) __attribute__ ((unused));
-static __inline int isonum_732 __P((u_char *)) __attribute__ ((unused));
-static __inline int isonum_733 __P((u_char *)) __attribute__ ((unused));
+static __inline u_int16_t isonum_721 __P((u_char *)) __attribute__ ((unused));
+static __inline u_int16_t isonum_722 __P((u_char *)) __attribute__ ((unused));
+static __inline u_int16_t isonum_723 __P((u_char *)) __attribute__ ((unused));
+static __inline u_int32_t isonum_731 __P((u_char *)) __attribute__ ((unused));
+static __inline u_int32_t isonum_732 __P((u_char *)) __attribute__ ((unused));
+static __inline u_int32_t isonum_733 __P((u_char *)) __attribute__ ((unused));
 
 /* 7.1.1: unsigned char */
 static __inline int
@@ -202,31 +202,31 @@
 }
 
 /* 7.2.1: unsigned little-endian 16-bit value.  NOT USED IN KERNEL. */
-static __inline int
+static __inline u_int16_t
 isonum_721(p)
 	u_char *p;
 {
 #if defined(UNALIGNED_ACCESS) && (BYTE_ORDER == LITTLE_ENDIAN)
-	return *(u_int16t *)p;
+	return *(u_int16_t *)p;
 #else
 	return *p|((char)p[1] << 8);
 #endif
 }
 
 /* 7.2.2: unsigned big-endian 16-bit value.  NOT USED IN KERNEL. */
-static __inline int     
+static __inline u_int16_t     
 isonum_722(p)
 	unsigned char *p;
 {
 #if defined(UNALIGNED_ACCESS) && (BYTE_ORDER == BIG_ENDIAN)
-	return *(u_int16t *)p;
+	return *(u_int16_t *)p;
 #else
 	return ((char)*p << 8)|p[1];
 #endif
 } 
 
 /* 7.2.3: unsigned both-endian (little, then big) 16-bit value */
-static __inline int
+static __inline u_int16_t
 #if __STDC__
 isonum_723(u_char *p)
 #else
@@ -237,9 +237,9 @@
 #if defined(UNALIGNED_ACCESS) && \
     ((BYTE_ORDER == LITTLE_ENDIAN) || (BYTE_ORDER == BIG_ENDIAN))
 #if BYTE_ORDER == LITTLE_ENDIAN
-	return *(u_int16t *)p;
+	return *(u_int16_t *)p;
 #else
-	return *(u_int16t *)(p + 2);
+	return *(u_int16_t *)(p + 2);
 #endif
 #else /* !UNALIGNED_ACCESS or weird byte order */
 	return *p|(p[1] << 8);
@@ -247,31 +247,31 @@
 }
 
 /* 7.3.1: unsigned little-endian 32-bit value.  NOT USED IN KERNEL. */
-static __inline int
+static __inline u_int32_t
 isonum_731(p)
 	u_char *p;
 {
 #if defined(UNALIGNED_ACCESS) && (BYTE_ORDER == LITTLE_ENDIAN)
-	return *(u_int32t *)p;
+	return *(u_int32_t *)p;
 #else
 	return *p|(p[1] << 8)|(p[2] << 16)|(p[3] << 24);
 #endif
 }
 
 /* 7.3.2: unsigned big-endian 32-bit value.  NOT USED IN KERNEL. */
-static __inline int
+static __inline u_int32_t
 isonum_732(p)
 	unsigned char *p;
 {
 #if defined(UNALIGNED_ACCESS) && (BYTE_ORDER == BIG_ENDIAN)
-	return *(u_int32t *)p;
+	return *(u_int32_t *)p;
 #else
 	return (*p << 24)|(p[1] << 16)|(p[2] << 8)|p[3];
 #endif
 }
 
 /* 7.3.3: unsigned both-endian (little, then big) 32-bit value */
-static __inline int
+static __inline u_int32_t
 #if __STDC__
 isonum_733(u_char *p)
 #else
@@ -282,9 +282,9 @@
 #if defined(UNALIGNED_ACCESS) && \
     ((BYTE_ORDER == LITTLE_ENDIAN) || (BYTE_ORDER == BIG_ENDIAN))
 #if BYTE_ORDER == LITTLE_ENDIAN
-	return *(u_int32t *)p;
+	return *(u_int32_t *)p;
 #else
-	return *(u_int32t *)(p + 4);
+	return *(u_int32_t *)(p + 4);
 #endif
 #else /* !UNALIGNED_ACCESS or weird byte order */
 	return *p|(p[1] << 8)|(p[2] << 16)|(p[3] << 24);

-Olaf.
-- 
                           -- Ceterum censeo "authored[1]" delendum esse.
___ Olaf 'Rhialto' Seibert -- [1] Ugly English neologism[2].
\X/ rhialto/at/xs4all.nl   -- [2] For lawyers whose English/Latin is below par.