Subject: kern/33198: getsysinfo(2) incorrect behaviour under compat_osf1
To: None <kern-bug-people@netbsd.org, gnats-admin@netbsd.org,>
From: None <njoly@pasteur.fr>
List: netbsd-bugs
Date: 04/05/2006 10:10:00
>Number:         33198
>Category:       kern
>Synopsis:       getsysinfo(2) incorrect behaviour under compat_osf1
>Confidential:   no
>Severity:       non-critical
>Priority:       low
>Responsible:    kern-bug-people
>State:          open
>Class:          sw-bug
>Submitter-Id:   net
>Arrival-Date:   Wed Apr 05 10:10:00 +0000 2006
>Originator:     Nicolas Joly
>Release:        NetBSD 3.99.17
>Organization:
Institut Pasteur, Paris.
>Environment:
System: NetBSD thanos.sis.pasteur.fr 3.99.17 NetBSD 3.99.17 (THANOS) #8: Wed Apr 5 11:52:18 CEST 2006 njoly@thanos.sis.pasteur.fr:/local/src/NetBSD/obj/alpha/sys/arch/alpha/compile/THANOS alpha
Architecture: alpha
Machine: alpha
>Description:
getsysinfo(2) behaviour, at least with GSI_PLATFORM_NAME operation, is not
the same between Tru64/alpha and NetBSD/alpha (with COMPAT_OSF1):

1) Tru64 return a NULL terminated string, where NetBSD do not.

njoly@medusa [tmp]> cat getsysinfo.c
#include <errno.h>
#include <stdio.h>
#include <string.h>
#include <sys/sysinfo.h>
#include <machine/hal_sysinfo.h>

int main() {
  char buf[50];
  int i;

  memset(buf, 0x30, 49); buf[49] = 0x0;
  i = getsysinfo(GSI_PLATFORM_NAME, buf, 50, 0);
  printf("nbytes=50 ret=%d, errno=%d\n", i, errno);
  if (i <= 0) { return 1; }
  printf(">>%s<<\n", buf);

  return 0; }

njoly@medusa [tmp]> uname -a
OSF1 medusa.sis.pasteur.fr V5.1 2650 alpha
njoly@medusa [tmp]> ./a.out
nbytes=50 ret=1, errno=0
>>Digital Personal WorkStation 500au<<

njoly@thanos [~]> uname -a
NetBSD thanos.sis.pasteur.fr 3.99.17 NetBSD 3.99.17 (THANOS) #6: Wed Apr  5 11:3
1:06 CEST 2006  njoly@thanos.sis.pasteur.fr:/local/src/NetBSD/obj/alpha/sys/arch
/alpha/compile/THANOS alpha
njoly@thanos [~]> ./a.out
nbytes=50 ret=1, errno=0
>>Digital Personal WorkStation 500au000000000000000<<



2) Tru64 check that the specified buffer size is large enough to store the
   results, NetBSD do not.

njoly@medusa [tmp]> cat getsysinfo.c
#include <errno.h>
#include <stdio.h>
#include <string.h>
#include <sys/sysinfo.h>
#include <machine/hal_sysinfo.h>

int main() {
  char buf[50];
  int i;

  memset(buf, 0x0, 50);
  i = getsysinfo(GSI_PLATFORM_NAME, buf, 20, 0);
  printf("nbytes=20 ret=%d, errno=%d\n", i, errno);
  if (i <= 0) { return 1; }
  printf(">>%s<<\n", buf);

  return 0; }

njoly@medusa [tmp]> uname -a
OSF1 medusa.sis.pasteur.fr V5.1 2650 alpha
njoly@medusa [tmp]> ./a.out
nbytes=20 ret=-1, errno=22

njoly@thanos [~]> uname -a
NetBSD thanos.sis.pasteur.fr 3.99.17 NetBSD 3.99.17 (THANOS) #6: Wed Apr  5 11:3
1:06 CEST 2006  njoly@thanos.sis.pasteur.fr:/local/src/NetBSD/obj/alpha/sys/arch
/alpha/compile/THANOS alpha
njoly@thanos [~]> ./a.out
nbytes=20 ret=1, errno=0
>>Digital Personal WorkStation 500au<<


>How-To-Repeat:
Compare `getsysinfo(GSI_PLATFORM_NAME, ...)' behaviour between Tru64 and
NetBSD+COMPAT_OSF1 hosts.
>Fix:
The follwing patch fix the problem for me.

Index: sys/compat/osf1/osf1_misc.c
===================================================================
RCS file: /cvsroot/src/sys/compat/osf1/osf1_misc.c,v
retrieving revision 1.71
diff -u -r1.71 osf1_misc.c
--- sys/compat/osf1/osf1_misc.c	11 Dec 2005 12:20:23 -0000	1.71
+++ sys/compat/osf1/osf1_misc.c	5 Apr 2006 09:50:28 -0000
@@ -169,6 +169,7 @@
 	int unit;
 	long percpu;
 	long proctype;
+	unsigned long size;
 	u_int64_t fpflags;
 	struct osf1_cpu_info cpuinfo;
 
@@ -254,9 +255,15 @@
 	}
 		break;
 	case OSF_GET_PLATFORM_NAME:
-		error = copyout(platform.model, SCARG(uap, buffer),
-		    strlen(platform.model));
-		retval[0] = 1;
+		size = strlen(platform.model) + 1;
+		if (SCARG(uap, nbytes) < size) {
+			error = EINVAL;
+		}
+		else {
+			error = copyout(platform.model, SCARG(uap, buffer),
+			    size);
+			retval[0] = 1;
+		}
 		break;
 	default:
 		printf("osf1_getsysinfo called with unknown op=%ld\n",