socsvn commit: r286815 - soc2013/def/crashdump-head/sys/kern

def at FreeBSD.org def at FreeBSD.org
Sun Jun 7 23:00:10 UTC 2015


Author: def
Date: Sun Jun  7 23:00:09 2015
New Revision: 286815
URL: http://svnweb.FreeBSD.org/socsvn/?view=rev&rev=286815

Log:
  ddb(4) writes textdumps backwards. Assume that data have to be aligned to block size. Assume that the last call to dump_write and the current one write data chunks next to each other.

Modified:
  soc2013/def/crashdump-head/sys/kern/kern_shutdown.c

Modified: soc2013/def/crashdump-head/sys/kern/kern_shutdown.c
==============================================================================
--- soc2013/def/crashdump-head/sys/kern/kern_shutdown.c	Sun Jun  7 21:59:43 2015	(r286814)
+++ soc2013/def/crashdump-head/sys/kern/kern_shutdown.c	Sun Jun  7 23:00:09 2015	(r286815)
@@ -148,9 +148,9 @@
 	uint8_t		kdc_iv[KERNELDUMP_IV_SIZE];
 	keyInstance	kdc_ki;
 	cipherInstance	kdc_ci;
-	off_t		kdc_offset;
+	off_t		kdc_lastoffset;
+	size_t		kdc_lastlength;
 	uint8_t		kdc_buf[KERNELDUMP_BUFFER_SIZE];
-	size_t		kdc_bufused;
 } dumpcrypto;
 
 static struct kerneldumpkey *dumpkey = NULL;
@@ -878,8 +878,8 @@
 	if (error <= 0)
 		return (EINVAL);
 
-	kdc->kdc_offset = 0;
-	kdc->kdc_bufused = 0;
+	kdc->kdc_lastoffset = 0;
+	kdc->kdc_lastlength = 0;
 
 	di->kdc = kdc;
 	di->kdk = kdk;
@@ -1010,44 +1010,49 @@
 	struct kerneldumpcrypto *kdc;
 	struct kerneldumpkey *kdk;
 	int error;
-	size_t len;
+	size_t nbytes;
 
 	kdc = di->kdc;
 	kdk = di->kdk;
 
+	/* Data have to be aligned to block size. */
+	if ((length % KERNELDUMP_BLOCK_SIZE) != 0)
+		return (EINVAL);
+
 	/* Data have to be written continuously. */
-	if (kdc->kdc_offset != 0 && kdc->kdc_offset != offset &&
-	    kdc->kdc_offset + kdc->kdc_bufused != offset) {
+	if (kdc->kdc_lastoffset != 0 &&
+	    kdc->kdc_lastoffset + kdc->kdc_lastlength != offset &&
+	    offset + length != kdc->kdc_lastoffset) {
 		return (EINVAL);
 	}
 
-	while (kdc->kdc_bufused + length >= KERNELDUMP_BUFFER_SIZE) {
-		len = KERNELDUMP_BUFFER_SIZE - kdc->kdc_bufused;
-		memcpy(kdc->kdc_buf + kdc->kdc_bufused, virtual, len);
-		kdc->kdc_bufused += len;
+	kdc->kdc_lastoffset = offset;
+	kdc->kdc_lastlength = length;
+
+	while (length > 0) {
+		if (length >= KERNELDUMP_BUFFER_SIZE)
+			nbytes = KERNELDUMP_BUFFER_SIZE;
+		else
+			nbytes = length;
+		memcpy(kdc->kdc_buf, virtual, nbytes);
 
 		error = rijndael_blockEncrypt(&kdc->kdc_ci, &kdc->kdc_ki,
-		    kdc->kdc_buf, 8 * KERNELDUMP_BUFFER_SIZE, kdc->kdc_buf);
+		    kdc->kdc_buf, 8 * nbytes, kdc->kdc_buf);
 		if (error <= 0)
 			return (EIO);
 		error = rijndael_cipherInit(&kdc->kdc_ci, MODE_CBC,
-		    kdc->kdc_buf + KERNELDUMP_BUFFER_SIZE - KERNELDUMP_IV_SIZE);
+		    kdc->kdc_buf + nbytes - KERNELDUMP_IV_SIZE);
 		if (error <= 0)
 			return (EIO);
 
 		error = di->dumper(di->priv, kdc->kdc_buf, physical,
-		    kdc->kdc_offset, KERNELDUMP_BUFFER_SIZE);
+		    offset, nbytes);
 		if (error != 0)
 			return (error);
 
-		kdc->kdc_bufused = 0;
-		kdc->kdc_offset += KERNELDUMP_BUFFER_SIZE;
-		virtual = (void *)((char *)virtual + len);
-		length -= len;
-	}
-	if (length > 0) {
-		memcpy(kdc->kdc_buf + kdc->kdc_bufused, virtual, length);
-		kdc->kdc_bufused += length;
+		offset += nbytes;
+		virtual = (void *)((uint8_t *)virtual + nbytes);
+		length -= nbytes;
 	}
 
 	return (0);
@@ -1106,8 +1111,10 @@
 		return (error);
 
 #ifdef EKCD
-	if (di->kdc->kdc_enable == 1)
-		di->kdc->kdc_offset = offset + sizeof(*kdh);
+	if (di->kdc->kdc_enable == 1) {
+		di->kdc->kdc_lastoffset = offset;
+		di->kdc->kdc_lastlength = sizeof(*kdh);
+	}
 #endif
 
 	return (0);
@@ -1129,8 +1136,10 @@
 		return (error);
 
 #ifdef EKCD
-	if (di->kdc->kdc_enable == 1)
-		di->kdc->kdc_offset = offset + kerneldumpkey_size(kdk);
+	if (di->kdc->kdc_enable == 1) {
+		di->kdc->kdc_lastoffset = offset;
+		di->kdc->kdc_lastlength = kerneldumpkey_size(kdk);
+	}
 #endif
 
 	return (0);


More information about the svn-soc-all mailing list