Subject: Re: copyinstr() with a zero-length buffer
To: None <tech-kern@netbsd.org>
From: Charles M. Hannum <root@ihack.net>
List: tech-kern
Date: 11/02/1999 12:27:55
There is yet another bug in the SH3 version.  New patch included.
BTW, these patches are untested...

Index: sh3/sh3/Locore.c
===================================================================
RCS file: /cvsroot/syssrc/sys/arch/sh3/sh3/Locore.c,v
retrieving revision 1.1
diff -c -2 -r1.1 Locore.c
*** Locore.c	1999/09/13 10:31:26	1.1
--- Locore.c	1999/11/02 17:26:18
***************
*** 246,277 ****
  	curpcb->pcb_onfault = &&Err999;
  
! 	if ((cnt = (char *)VM_MAXUSER_ADDRESS - to) < maxlen)
! 		maxlen = cnt;
! 	else
! 		cnt = maxlen - 1;
  
  	while (cnt--) {
! 		if ((*to++ = *from++) == 0)
! 			break;
  	}
- 
- 	*lencopied = from - from_top;
  
! 	if (cnt == 0) {
! 		if (to >= (char *)VM_MAXUSER_ADDRESS)
! 			rc = EFAULT;
! 		else
! 			rc = ENAMETOOLONG;
! 	} else
! 		rc = 0;
  
  	curpcb->pcb_onfault = 0;
  	return rc;
  
   Err999:
! 	curpcb->pcb_onfault = 0;
! 	if (lencopied != 0)
  		*lencopied = from - from_top;
! 
  	return EFAULT;
  }
--- 246,274 ----
  	curpcb->pcb_onfault = &&Err999;
  
! 	if ((cnt = (char *)VM_MAXUSER_ADDRESS - to) > maxlen)
! 		cnt = maxlen;
  
  	while (cnt--) {
! 		if ((*to++ = *from++) == 0) {
! 			rc = 0;
! 			goto out;
! 		}
  	}
  
! 	if (to >= (char *)VM_MAXUSER_ADDRESS)
! 		rc = EFAULT;
! 	else
! 		rc = ENAMETOOLONG;
  
+ out:
+ 	if (lencopied)
+ 		*lencopied = from - from_top;
  	curpcb->pcb_onfault = 0;
  	return rc;
  
   Err999:
! 	if (lencopied)
  		*lencopied = from - from_top;
! 	curpcb->pcb_onfault = 0;
  	return EFAULT;
  }
***************
*** 299,332 ****
  	curpcb->pcb_onfault = &&Err999;
  
! 	if ((cnt = (char *)VM_MAXUSER_ADDRESS - from) < maxlen)
! 		maxlen = cnt;
! 	else
! 		cnt = maxlen - 1;
  
  	while (cnt--) {
! 		if ((*to++ = *from++) == 0)
! 			break;
  	}
  
! 	if (lencopied != NULL)
! 		*lencopied = from - from_top;
! 
! 	if (cnt == 0 && *(from - 1) != 0) {
! 		if (to >= (char *)VM_MAXUSER_ADDRESS)
! 			rc = EFAULT;
! 		else
! 			rc = ENAMETOOLONG;
! 	} else
! 		rc = 0;
  
  	curpcb->pcb_onfault = 0;
- 
  	return rc;
  
   Err999:
! 	curpcb->pcb_onfault = 0;
! 	if (lencopied != 0)
  		*lencopied = from - from_top;
! 
  	return EFAULT;
  }
--- 296,324 ----
  	curpcb->pcb_onfault = &&Err999;
  
! 	if ((cnt = (char *)VM_MAXUSER_ADDRESS - to) > maxlen)
! 		cnt = maxlen;
  
  	while (cnt--) {
! 		if ((*to++ = *from++) == 0) {
! 			rc = 0;
! 			goto out;
! 		}
  	}
  
! 	if (to >= (char *)VM_MAXUSER_ADDRESS)
! 		rc = EFAULT;
! 	else
! 		rc = ENAMETOOLONG;
  
+ out:
+ 	if (lencopied)
+ 		*lencopied = from - from_top;
  	curpcb->pcb_onfault = 0;
  	return rc;
  
   Err999:
! 	if (lencopied)
  		*lencopied = from - from_top;
! 	curpcb->pcb_onfault = 0;
  	return EFAULT;
  }
***************
*** 350,365 ****
  
  	for (i = 0; i < maxlen; i++) {
! 		if ((*to++ = *from++) == NULL)
! 			break;
  	}
  
! 	if (i == maxlen) {
  		*lencopied = i;
! 		return ENAMETOOLONG;
! 	} else {
! 		if (lencopied)
! 			*lencopied = i + 1;
! 		return 0;
! 	}
  }
  
--- 342,355 ----
  
  	for (i = 0; i < maxlen; i++) {
! 		if ((*to++ = *from++) == NULL) {
! 			if (lencopied)
! 				*lencopied = i + 1;
! 			return (0);
! 		}
  	}
  
! 	if (lencopied)
  		*lencopied = i;
! 	return (ENAMETOOLONG);
  }