Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/trunk]: src/sys/kern Provide binary compatibility for architectures that...
details: https://anonhg.NetBSD.org/src/rev/8ac7489f8d7c
branches: trunk
changeset: 785880:8ac7489f8d7c
user: martin <martin%NetBSD.org@localhost>
date: Thu Apr 04 12:51:39 2013 +0000
description:
Provide binary compatibility for architectures that (erroneously) had
a larger MAXPARTITIONS value (and thus larger struct disklabel).
diffstat:
sys/kern/sys_generic.c | 45 +++++++++++++++++++++++++++++++++++++++++----
1 files changed, 41 insertions(+), 4 deletions(-)
diffs (95 lines):
diff -r 7816160bdef8 -r 8ac7489f8d7c sys/kern/sys_generic.c
--- a/sys/kern/sys_generic.c Thu Apr 04 12:50:03 2013 +0000
+++ b/sys/kern/sys_generic.c Thu Apr 04 12:51:39 2013 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: sys_generic.c,v 1.128 2012/01/25 00:28:36 christos Exp $ */
+/* $NetBSD: sys_generic.c,v 1.129 2013/04/04 12:51:39 martin Exp $ */
/*-
* Copyright (c) 2007, 2008, 2009 The NetBSD Foundation, Inc.
@@ -70,7 +70,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: sys_generic.c,v 1.128 2012/01/25 00:28:36 christos Exp $");
+__KERNEL_RCSID(0, "$NetBSD: sys_generic.c,v 1.129 2013/04/04 12:51:39 martin Exp $");
#include <sys/param.h>
#include <sys/systm.h>
@@ -526,6 +526,12 @@
void *data, *memp;
#define STK_PARAMS 128
u_long stkbuf[STK_PARAMS/sizeof(u_long)];
+#if __TMPBIGMAXPARTITIONS > MAXPARTITIONS
+ size_t zero_last = 0;
+#define zero_size(SZ) ((SZ)+zero_last)
+#else
+#define zero_size(SZ) (SZ)
+#endif
memp = NULL;
alloc_size = 0;
@@ -563,7 +569,34 @@
* but only copyin/out the smaller amount.
*/
if (IOCGROUP(com) == 'd') {
+#if __TMPBIGMAXPARTITIONS > MAXPARTITIONS
+ u_long ocom = com;
+#endif
u_long ncom = com ^ (DIOCGDINFO ^ DIOCGDINFO32);
+
+#if __TMPBIGMAXPARTITIONS > MAXPARTITIONS
+ /*
+ * Userland might use struct disklabel that is bigger than the
+ * the kernel version (historic accident) - alloc userland
+ * size and zero unused part on copyout.
+ */
+#define DISKLABELLENDIFF (sizeof(struct partition) \
+ *(__TMPBIGMAXPARTITIONS-MAXPARTITIONS))
+#define IOCFIXUP(NIOC) ((NIOC&~(IOCPARM_MASK<<IOCPARM_SHIFT)) | \
+ (IOCPARM_LEN(NIOC)-DISKLABELLENDIFF)<<IOCPARM_SHIFT)
+
+ switch (IOCFIXUP(ocom)) {
+ case DIOCGDINFO:
+ case DIOCWDINFO:
+ case DIOCSDINFO:
+ case DIOCGDEFLABEL:
+ com = ncom = IOCFIXUP(ocom);
+ zero_last = DISKLABELLENDIFF;
+ size -= DISKLABELLENDIFF;
+ goto done;
+ }
+#endif
+
switch (ncom) {
case DIOCGDINFO:
case DIOCWDINFO:
@@ -574,6 +607,9 @@
alloc_size = IOCPARM_LEN(DIOCGDINFO);
break;
}
+#if __TMPBIGMAXPARTITIONS > MAXPARTITIONS
+ done: ;
+#endif
}
if (size > IOCPARM_MAX) {
error = ENOTTY;
@@ -615,7 +651,7 @@
* Zero the buffer so the user always
* gets back something deterministic.
*/
- memset(data, 0, size);
+ memset(data, 0, zero_size(size));
} else if (com&IOC_VOID) {
*(void **)data = SCARG(uap, data);
}
@@ -648,7 +684,8 @@
* already set and checked above.
*/
if (error == 0 && (com&IOC_OUT) && size) {
- error = copyout(data, SCARG(uap, data), size);
+ error = copyout(data, SCARG(uap, data),
+ zero_size(size));
ktrgenio(SCARG(uap, fd), UIO_READ, SCARG(uap, data),
size, error);
}
Home |
Main Index |
Thread Index |
Old Index