Module Name:    src
Committed By:   kamil
Date:           Wed Jul 25 22:07:59 UTC 2018

Modified Files:
        src/sys/fs/msdosfs: msdosfs_fat.c

Log Message:
Avoid undefined behavior semantics in msdosfs_fat.c

Do not change signedness bit with left shift.
While there avoid signed integer overflow.
Address both issues with using unsigned type.

msdosfs_fat.c:512:42, left shift of 1 by 31 places cannot be represented in 
type 'int'
msdosfs_fat.c:521:44, left shift of 1 by 31 places cannot be represented in 
type 'int'
msdosfs_fat.c:744:14, left shift of 1 by 31 places cannot be represented in 
type 'int'
msdosfs_fat.c:744:24, signed integer overflow: -2147483648 - 1 cannot be 
represented in type 'int [20]'
msdosfs_fat.c:840:13, left shift of 1 by 31 places cannot be represented in 
type 'int'
msdosfs_fat.c:840:36, signed integer overflow: -2147483648 - 1 cannot be 
represented in type 'int [20]'

Detected with micro-UBSan in the user mode.


To generate a diff of this commit:
cvs rdiff -u -r1.32 -r1.33 src/sys/fs/msdosfs/msdosfs_fat.c

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

Modified files:

Index: src/sys/fs/msdosfs/msdosfs_fat.c
diff -u src/sys/fs/msdosfs/msdosfs_fat.c:1.32 src/sys/fs/msdosfs/msdosfs_fat.c:1.33
--- src/sys/fs/msdosfs/msdosfs_fat.c:1.32	Sat Jan 27 03:54:01 2018
+++ src/sys/fs/msdosfs/msdosfs_fat.c	Wed Jul 25 22:07:59 2018
@@ -1,4 +1,4 @@
-/*	$NetBSD: msdosfs_fat.c,v 1.32 2018/01/27 03:54:01 sevan Exp $	*/
+/*	$NetBSD: msdosfs_fat.c,v 1.33 2018/07/25 22:07:59 kamil Exp $	*/
 
 /*-
  * Copyright (C) 1994, 1995, 1997 Wolfgang Solfrank.
@@ -52,7 +52,7 @@
 #endif
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: msdosfs_fat.c,v 1.32 2018/01/27 03:54:01 sevan Exp $");
+__KERNEL_RCSID(0, "$NetBSD: msdosfs_fat.c,v 1.33 2018/07/25 22:07:59 kamil Exp $");
 
 /*
  * kernel include files.
@@ -409,7 +409,7 @@ updatefats(struct msdosfsmount *pmp, str
 
 		if (pmp->pm_freeclustercount
 		    && (pmp->pm_inusemap[cn / N_INUSEBITS]
-			& (1 << (cn % N_INUSEBITS)))) {
+			& (1U << (cn % N_INUSEBITS)))) {
 			/*
 			 * The cluster indicated in FSInfo isn't free
 			 * any longer.  Got get a new free one.
@@ -509,7 +509,7 @@ static inline void
 usemap_alloc(struct msdosfsmount *pmp, u_long cn)
 {
 
-	pmp->pm_inusemap[cn / N_INUSEBITS] |= 1 << (cn % N_INUSEBITS);
+	pmp->pm_inusemap[cn / N_INUSEBITS] |= 1U << (cn % N_INUSEBITS);
 	pmp->pm_freeclustercount--;
 }
 
@@ -518,7 +518,7 @@ usemap_free(struct msdosfsmount *pmp, u_
 {
 
 	pmp->pm_freeclustercount++;
-	pmp->pm_inusemap[cn / N_INUSEBITS] &= ~(1 << (cn % N_INUSEBITS));
+	pmp->pm_inusemap[cn / N_INUSEBITS] &= ~(1U << (cn % N_INUSEBITS));
 }
 
 int
@@ -741,7 +741,7 @@ chainlength(struct msdosfsmount *pmp, u_
 	idx = start / N_INUSEBITS;
 	start %= N_INUSEBITS;
 	map = pmp->pm_inusemap[idx];
-	map &= ~((1 << start) - 1);
+	map &= ~((1U << start) - 1);
 	if (map) {
 		len = ffs(map) - 1 - start;
 		return (len > count ? count : len);
@@ -837,7 +837,7 @@ clusteralloc(struct msdosfsmount *pmp, u
 	for (cn = newst; cn <= pmp->pm_maxcluster;) {
 		idx = cn / N_INUSEBITS;
 		map = pmp->pm_inusemap[idx];
-		map |= (1 << (cn % N_INUSEBITS)) - 1;
+		map |= (1U << (cn % N_INUSEBITS)) - 1;
 		if (map != (u_int)-1) {
 			cn = idx * N_INUSEBITS + ffs(map^(u_int)-1) - 1;
 			if ((l = chainlength(pmp, cn, count)) >= count)
@@ -854,7 +854,7 @@ clusteralloc(struct msdosfsmount *pmp, u
 	for (cn = 0; cn < newst;) {
 		idx = cn / N_INUSEBITS;
 		map = pmp->pm_inusemap[idx];
-		map |= (1 << (cn % N_INUSEBITS)) - 1;
+		map |= (1U << (cn % N_INUSEBITS)) - 1;
 		if (map != (u_int)-1) {
 			cn = idx * N_INUSEBITS + ffs(map^(u_int)-1) - 1;
 			if ((l = chainlength(pmp, cn, count)) >= count)

Reply via email to