svn commit: r274366 - in head/sys: dev/null geom kern sys

Pawel Jakub Dawidek pjd at FreeBSD.org
Tue Nov 11 04:48:11 UTC 2014


Author: pjd
Date: Tue Nov 11 04:48:09 2014
New Revision: 274366
URL: https://svnweb.freebsd.org/changeset/base/274366

Log:
  Add missing privilege check when setting the dump device. Before that change it
  was possible for a regular user to setup the dump device if he had write access
  to the given device. In theory it is a security issue as user might get access
  to kernel's memory after provoking kernel crash, but in practise it is not
  recommended to give regular users direct access to storage devices.
  
  Rework the code so that we do privileges check within the set_dumper() function
  to avoid similar problems in the future.
  
  Discussed with:	secteam

Modified:
  head/sys/dev/null/null.c
  head/sys/geom/geom_dev.c
  head/sys/kern/kern_shutdown.c
  head/sys/sys/conf.h

Modified: head/sys/dev/null/null.c
==============================================================================
--- head/sys/dev/null/null.c	Tue Nov 11 04:07:41 2014	(r274365)
+++ head/sys/dev/null/null.c	Tue Nov 11 04:48:09 2014	(r274366)
@@ -37,7 +37,6 @@ __FBSDID("$FreeBSD$");
 #include <sys/kernel.h>
 #include <sys/malloc.h>
 #include <sys/module.h>
-#include <sys/priv.h>
 #include <sys/disk.h>
 #include <sys/bus.h>
 #include <sys/filio.h>
@@ -110,9 +109,7 @@ null_ioctl(struct cdev *dev __unused, u_
 
 	switch (cmd) {
 	case DIOCSKERNELDUMP:
-		error = priv_check(td, PRIV_SETDUMPER);
-		if (error == 0)
-			error = set_dumper(NULL, NULL);
+		error = set_dumper(NULL, NULL, td);
 		break;
 	case FIONBIO:
 		break;

Modified: head/sys/geom/geom_dev.c
==============================================================================
--- head/sys/geom/geom_dev.c	Tue Nov 11 04:07:41 2014	(r274365)
+++ head/sys/geom/geom_dev.c	Tue Nov 11 04:48:09 2014	(r274366)
@@ -127,14 +127,14 @@ g_dev_fini(struct g_class *mp)
 }
 
 static int
-g_dev_setdumpdev(struct cdev *dev)
+g_dev_setdumpdev(struct cdev *dev, struct thread *td)
 {
 	struct g_kerneldump kd;
 	struct g_consumer *cp;
 	int error, len;
 
 	if (dev == NULL)
-		return (set_dumper(NULL, NULL));
+		return (set_dumper(NULL, NULL, td));
 
 	cp = dev->si_drv2;
 	len = sizeof(kd);
@@ -142,7 +142,7 @@ g_dev_setdumpdev(struct cdev *dev)
 	kd.length = OFF_MAX;
 	error = g_io_getattr("GEOM::kerneldump", cp, &len, &kd);
 	if (error == 0) {
-		error = set_dumper(&kd.di, devtoname(dev));
+		error = set_dumper(&kd.di, devtoname(dev), td);
 		if (error == 0)
 			dev->si_flags |= SI_DUMPDEV;
 	}
@@ -157,7 +157,7 @@ init_dumpdev(struct cdev *dev)
 		return;
 	if (strcmp(devtoname(dev), dumpdev) != 0)
 		return;
-	if (g_dev_setdumpdev(dev) == 0) {
+	if (g_dev_setdumpdev(dev, curthread) == 0) {
 		freeenv(dumpdev);
 		dumpdev = NULL;
 	}
@@ -453,9 +453,9 @@ g_dev_ioctl(struct cdev *dev, u_long cmd
 		break;
 	case DIOCSKERNELDUMP:
 		if (*(u_int *)data == 0)
-			error = g_dev_setdumpdev(NULL);
+			error = g_dev_setdumpdev(NULL, td);
 		else
-			error = g_dev_setdumpdev(dev);
+			error = g_dev_setdumpdev(dev, td);
 		break;
 	case DIOCGFLUSH:
 		error = g_io_flush(cp);
@@ -673,7 +673,7 @@ g_dev_orphan(struct g_consumer *cp)
 
 	/* Reset any dump-area set on this device */
 	if (dev->si_flags & SI_DUMPDEV)
-		(void)set_dumper(NULL, NULL);
+		(void)set_dumper(NULL, NULL, curthread);
 
 	/* Destroy the struct cdev *so we get no more requests */
 	destroy_dev_sched_cb(dev, g_dev_callback, cp);

Modified: head/sys/kern/kern_shutdown.c
==============================================================================
--- head/sys/kern/kern_shutdown.c	Tue Nov 11 04:07:41 2014	(r274365)
+++ head/sys/kern/kern_shutdown.c	Tue Nov 11 04:48:09 2014	(r274366)
@@ -827,9 +827,14 @@ SYSCTL_STRING(_kern_shutdown, OID_AUTO, 
 
 /* Registration of dumpers */
 int
-set_dumper(struct dumperinfo *di, const char *devname)
+set_dumper(struct dumperinfo *di, const char *devname, struct thread *td)
 {
 	size_t wantcopy;
+	int error;
+
+	error = priv_check(td, PRIV_SETDUMPER);
+	if (error != 0)
+		return (error);
 
 	if (di == NULL) {
 		bzero(&dumper, sizeof dumper);

Modified: head/sys/sys/conf.h
==============================================================================
--- head/sys/sys/conf.h	Tue Nov 11 04:07:41 2014	(r274365)
+++ head/sys/sys/conf.h	Tue Nov 11 04:48:09 2014	(r274366)
@@ -336,7 +336,7 @@ struct dumperinfo {
 	off_t   mediasize;	/* Space available in bytes. */
 };
 
-int set_dumper(struct dumperinfo *, const char *_devname);
+int set_dumper(struct dumperinfo *, const char *_devname, struct thread *td);
 int dump_write(struct dumperinfo *, void *, vm_offset_t, off_t, size_t);
 int dumpsys(struct dumperinfo *);
 int doadump(boolean_t);


More information about the svn-src-head mailing list