Module Name:    src
Committed By:   maxv
Date:           Sat Sep 21 06:56:51 UTC 2019

Modified Files:
        src/sys/compat/netbsd32: netbsd32_fs.c

Log Message:
Fix netbsd32___mount50():

 - zero out fs_args32 to prevent info leaks
 - remove unused and non-functional copyin in NFS (lgtm bot)
 - declare udata, and don't pass kernel pointers to copyout (lgtm bot)
 - make sure data_len is just big enough, to mimic the native behavior
 - don't forget to update *retval with the 32bit value
 - add an XXX for NFS


To generate a diff of this commit:
cvs rdiff -u -r1.82 -r1.83 src/sys/compat/netbsd32/netbsd32_fs.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/compat/netbsd32/netbsd32_fs.c
diff -u src/sys/compat/netbsd32/netbsd32_fs.c:1.82 src/sys/compat/netbsd32/netbsd32_fs.c:1.83
--- src/sys/compat/netbsd32/netbsd32_fs.c:1.82	Wed Dec 26 08:01:40 2018
+++ src/sys/compat/netbsd32/netbsd32_fs.c	Sat Sep 21 06:56:51 2019
@@ -1,4 +1,4 @@
-/*	$NetBSD: netbsd32_fs.c,v 1.82 2018/12/26 08:01:40 mrg Exp $	*/
+/*	$NetBSD: netbsd32_fs.c,v 1.83 2019/09/21 06:56:51 maxv Exp $	*/
 
 /*
  * Copyright (c) 1998, 2001 Matthew R. Green
@@ -27,7 +27,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: netbsd32_fs.c,v 1.82 2018/12/26 08:01:40 mrg Exp $");
+__KERNEL_RCSID(0, "$NetBSD: netbsd32_fs.c,v 1.83 2019/09/21 06:56:51 maxv Exp $");
 
 #include <sys/param.h>
 #include <sys/systm.h>
@@ -809,17 +809,21 @@ netbsd32___mount50(struct lwp *l, const 
 	const char *type = SCARG_P32(uap, type);
 	const char *path = SCARG_P32(uap, path);
 	int flags = SCARG(uap, flags);
-	void *data = SCARG_P32(uap, data);
+	void *data, *udata;
 	size_t data_len = SCARG(uap, data_len);
 	enum uio_seg data_seg;
 	size_t len;
 	int error;
  
+	udata = data = SCARG_P32(uap, data);
+	memset(&fs_args32, 0, sizeof(fs_args32));
+
 	error = copyinstr(type, mtype, sizeof(mtype), &len);
 	if (error)
 		return error;
+
 	if (strcmp(mtype, MOUNT_TMPFS) == 0) {
-		if (data_len != sizeof(fs_args32.tmpfs_args))
+		if (data_len < sizeof(fs_args32.tmpfs_args))
 			return EINVAL;
 		if ((flags & MNT_GETARGS) == 0) {
 			error = copyin(data, &fs_args32.tmpfs_args, 
@@ -843,7 +847,7 @@ netbsd32___mount50(struct lwp *l, const 
 		data = &fs_args.tmpfs_args;
 		data_len = sizeof(fs_args.tmpfs_args);
 	} else if (strcmp(mtype, MOUNT_MFS) == 0) {
-		if (data_len != sizeof(fs_args32.mfs_args))
+		if (data_len < sizeof(fs_args32.mfs_args))
 			return EINVAL;
 		if ((flags & MNT_GETARGS) == 0) {
 			error = copyin(data, &fs_args32.mfs_args, 
@@ -864,7 +868,7 @@ netbsd32___mount50(struct lwp *l, const 
 	} else if ((strcmp(mtype, MOUNT_UFS) == 0) ||
 		   (strcmp(mtype, MOUNT_EXT2FS) == 0) ||
 		   (strcmp(mtype, MOUNT_LFS) == 0)) {
-		if (data_len > sizeof(fs_args32.ufs_args))
+		if (data_len < sizeof(fs_args32.ufs_args))
 			return EINVAL;
 		if ((flags & MNT_GETARGS) == 0) {
 			error = copyin(data, &fs_args32.ufs_args, 
@@ -878,7 +882,7 @@ netbsd32___mount50(struct lwp *l, const 
 		data = &fs_args.ufs_args;
 		data_len = sizeof(fs_args.ufs_args);
 	} else if (strcmp(mtype, MOUNT_CD9660) == 0) {
-		if (data_len != sizeof(fs_args32.iso_args))
+		if (data_len < sizeof(fs_args32.iso_args))
 			return EINVAL;
 		if ((flags & MNT_GETARGS) == 0) {
 			error = copyin(data, &fs_args32.iso_args, 
@@ -895,7 +899,7 @@ netbsd32___mount50(struct lwp *l, const 
 		data = &fs_args.iso_args;
 		data_len = sizeof(fs_args.iso_args);
 	} else if (strcmp(mtype, MOUNT_MSDOS) == 0) {
-		if (data_len != sizeof(fs_args32.msdosfs_args))
+		if (data_len < sizeof(fs_args32.msdosfs_args))
 			return EINVAL;
 		if ((flags & MNT_GETARGS) == 0) {
 			error = copyin(data, &fs_args32.msdosfs_args, 
@@ -925,8 +929,9 @@ netbsd32___mount50(struct lwp *l, const 
 		data = &fs_args.msdosfs_args;
 		data_len = sizeof(fs_args.msdosfs_args);
 	} else if (strcmp(mtype, MOUNT_NFS) == 0) {
-		if (data_len != sizeof(fs_args32.nfs_args))
+		if (data_len < sizeof(fs_args32.nfs_args))
 			return EINVAL;
+		/* XXX: NFS requires copyin even with MNT_GETARGS */
 		if ((flags & MNT_GETARGS) == 0) {
 			error = copyin(data, &fs_args32.nfs_args, 
 			    sizeof(fs_args32.nfs_args));
@@ -952,7 +957,7 @@ netbsd32___mount50(struct lwp *l, const 
 		data = &fs_args.nfs_args;
 		data_len = sizeof(fs_args.nfs_args);
 	} else if (strcmp(mtype, MOUNT_NULL) == 0) {
-		if (data_len > sizeof(fs_args32.null_args))
+		if (data_len < sizeof(fs_args32.null_args))
 			return EINVAL;
 		if ((flags & MNT_GETARGS) == 0) {
 			error = copyin(data, &fs_args32.null_args, 
@@ -968,10 +973,12 @@ netbsd32___mount50(struct lwp *l, const 
 	} else {
 		data_seg = UIO_USERSPACE;
 	}
+
 	error = do_sys_mount(l, mtype, UIO_SYSSPACE, path, flags, data, data_seg,
 	    data_len, retval);
 	if (error)
 		return error;
+
 	if (flags & MNT_GETARGS) {
 		data_len = *retval;
 		if (strcmp(mtype, MOUNT_TMPFS) == 0) {
@@ -989,8 +996,9 @@ netbsd32___mount50(struct lwp *l, const 
 			    fs_args.tmpfs_args.ta_root_gid;
 			fs_args32.tmpfs_args.ta_root_mode =
 			    fs_args.tmpfs_args.ta_root_mode;
-			error = copyout(&fs_args32.tmpfs_args, data,
+			error = copyout(&fs_args32.tmpfs_args, udata,
 				    sizeof(fs_args32.tmpfs_args));
+			*retval = sizeof(fs_args32.tmpfs_args);
 		} else if (strcmp(mtype, MOUNT_MFS) == 0) {
 			if (data_len != sizeof(fs_args.mfs_args))
 				return EINVAL;
@@ -1001,15 +1009,17 @@ netbsd32___mount50(struct lwp *l, const 
 			NETBSD32PTR32(fs_args32.mfs_args.base,
 			    fs_args.mfs_args.base);
 			fs_args32.mfs_args.size = fs_args.mfs_args.size;
-			error = copyout(&fs_args32.mfs_args, data,
+			error = copyout(&fs_args32.mfs_args, udata,
 				    sizeof(fs_args32.mfs_args));
+			*retval = sizeof(fs_args32.mfs_args);
 		} else if (strcmp(mtype, MOUNT_UFS) == 0) {
 			if (data_len != sizeof(fs_args.ufs_args))
 				return EINVAL;
 			NETBSD32PTR32(fs_args32.ufs_args.fspec,
 			    fs_args.ufs_args.fspec);
-			error = copyout(&fs_args32.ufs_args, data, 
+			error = copyout(&fs_args32.ufs_args, udata, 
 			    sizeof(fs_args32.ufs_args));
+			*retval = sizeof(fs_args32.ufs_args);
 		} else if (strcmp(mtype, MOUNT_CD9660) == 0) {
 			if (data_len != sizeof(fs_args.iso_args))
 				return EINVAL;
@@ -1018,16 +1028,12 @@ netbsd32___mount50(struct lwp *l, const 
 			memset(&fs_args32.iso_args._pad1, 0,
 			    sizeof(fs_args32.iso_args._pad1));
 			fs_args32.iso_args.flags = fs_args.iso_args.flags;
-			error = copyout(&fs_args32.iso_args, data,
+			error = copyout(&fs_args32.iso_args, udata,
 				    sizeof(fs_args32.iso_args));
+			*retval = sizeof(fs_args32.iso_args);
 		} else if (strcmp(mtype, MOUNT_NFS) == 0) {
 			if (data_len != sizeof(fs_args.nfs_args))
 				return EINVAL;
-			error = copyin(data, &fs_args32.nfs_args, 
-			    sizeof(fs_args32.nfs_args));
-			if (error)
-				return error;
-			fs_args.nfs_args.version = fs_args32.nfs_args.version;
 			NETBSD32PTR32(fs_args32.nfs_args.addr,
 			    fs_args.nfs_args.addr);
 			memcpy(&fs_args32.nfs_args.addrlen,
@@ -1042,15 +1048,17 @@ netbsd32___mount50(struct lwp *l, const 
 				- offsetof(struct nfs_args, fhsize));
 			NETBSD32PTR32(fs_args32.nfs_args.hostname,
 			    fs_args.nfs_args.hostname);
-			error = copyout(&fs_args32.nfs_args, data,
+			error = copyout(&fs_args32.nfs_args, udata,
 			    sizeof(fs_args32.nfs_args));
+			*retval = sizeof(fs_args32.nfs_args);
 		} else if (strcmp(mtype, MOUNT_NULL) == 0) {
 			if (data_len != sizeof(fs_args.null_args))
 				return EINVAL;
 			NETBSD32PTR32(fs_args32.null_args.la.target,
 			    fs_args.null_args.la.target);
-			error = copyout(&fs_args32.null_args, data, 
+			error = copyout(&fs_args32.null_args, udata, 
 			    sizeof(fs_args32.null_args));
+			*retval = sizeof(fs_args32.null_args);
 		}
 	}
 	return error;

Reply via email to