summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorphk <phk@FreeBSD.org>2004-12-12 10:09:05 +0000
committerphk <phk@FreeBSD.org>2004-12-12 10:09:05 +0000
commit35b3c9fdfbd8e466654ebad62b044a7d3c01f3b7 (patch)
treec331a8f51b025987771bf29e5baf7455e29185d9
parentcfac934dde18f8d08432e5509b2dd827eb77be2c (diff)
downloadFreeBSD-src-35b3c9fdfbd8e466654ebad62b044a7d3c01f3b7.zip
FreeBSD-src-35b3c9fdfbd8e466654ebad62b044a7d3c01f3b7.tar.gz
Pass the file->flags down to geom ioctl handlers.
Reject certain ioctls if write permission is not indicated. Bump geom API version. Reported by: Ruben de Groot <mail25@bzerk.org>
-rw-r--r--sys/dev/ata/atapi-cd.c4
-rw-r--r--sys/dev/fdc/fdc.c8
-rw-r--r--sys/geom/geom.h5
-rw-r--r--sys/geom/geom_bsd.c7
-rw-r--r--sys/geom/geom_dev.c2
-rw-r--r--sys/geom/geom_disk.c4
-rw-r--r--sys/geom/geom_mbr.c5
-rw-r--r--sys/geom/geom_pc98.c5
8 files changed, 29 insertions, 11 deletions
diff --git a/sys/dev/ata/atapi-cd.c b/sys/dev/ata/atapi-cd.c
index 6c36f99..9b86948 100644
--- a/sys/dev/ata/atapi-cd.c
+++ b/sys/dev/ata/atapi-cd.c
@@ -63,7 +63,7 @@ static void acd_describe(struct acd_softc *);
static void lba2msf(u_int32_t, u_int8_t *, u_int8_t *, u_int8_t *);
static u_int32_t msf2lba(u_int8_t, u_int8_t, u_int8_t);
static int acd_geom_access(struct g_provider *, int, int, int);
-static int acd_geom_ioctl(struct g_provider *, u_long, void *, struct thread *);
+static g_ioctl_t acd_geom_ioctl;
static void acd_geom_start(struct bio *);
static void acd_done(struct ata_request *);
static void acd_read_toc(struct acd_softc *);
@@ -550,7 +550,7 @@ acd_geom_access(struct g_provider *pp, int dr, int dw, int de)
}
static int
-acd_geom_ioctl(struct g_provider *pp, u_long cmd, void *addr, struct thread *td)
+acd_geom_ioctl(struct g_provider *pp, u_long cmd, void *addr, int fflag, struct thread *td)
{
struct acd_softc *cdp = pp->geom->softc;
int error = 0;
diff --git a/sys/dev/fdc/fdc.c b/sys/dev/fdc/fdc.c
index 5846b0a..7c51590 100644
--- a/sys/dev/fdc/fdc.c
+++ b/sys/dev/fdc/fdc.c
@@ -1407,7 +1407,7 @@ fd_start(struct bio *bp)
}
static int
-fd_ioctl(struct g_provider *pp, u_long cmd, void *data, struct thread *td)
+fd_ioctl(struct g_provider *pp, u_long cmd, void *data, int fflag, struct thread *td)
{
struct fd_data *fd;
struct fdc_status *fsp;
@@ -1422,6 +1422,8 @@ fd_ioctl(struct g_provider *pp, u_long cmd, void *data, struct thread *td)
return (0);
case FD_STYPE: /* set drive type */
+ if (!fflag & FWRITE)
+ return (EPERM);
/*
* Allow setting drive type temporarily iff
* currently unset. Used for fdformat so any
@@ -1443,6 +1445,8 @@ fd_ioctl(struct g_provider *pp, u_long cmd, void *data, struct thread *td)
return (0);
case FD_SOPTS: /* set drive options */
+ if (!fflag & FWRITE)
+ return (EPERM);
fd->options = *(int *)data;
return (0);
@@ -1464,6 +1468,8 @@ fd_ioctl(struct g_provider *pp, u_long cmd, void *data, struct thread *td)
return (0);
case FD_FORM:
+ if (!fflag & FWRITE)
+ return (EPERM);
if (((struct fd_formb *)data)->format_version !=
FD_FORMAT_VERSION)
return (EINVAL); /* wrong version of formatting prog */
diff --git a/sys/geom/geom.h b/sys/geom/geom.h
index 3ae296b..c93053a 100644
--- a/sys/geom/geom.h
+++ b/sys/geom/geom.h
@@ -65,7 +65,7 @@ typedef int g_ctl_config_geom_t (struct gctl_req *, struct g_geom *gp, const cha
typedef void g_init_t (struct g_class *mp);
typedef void g_fini_t (struct g_class *mp);
typedef struct g_geom * g_taste_t (struct g_class *, struct g_provider *, int flags);
-typedef int g_ioctl_t(struct g_provider *pp, u_long cmd, void *data, struct thread *td);
+typedef int g_ioctl_t(struct g_provider *pp, u_long cmd, void *data, int fflag, struct thread *td);
#define G_TF_NORMAL 0
#define G_TF_INSIST 1
#define G_TF_TRANSPARENT 2
@@ -111,7 +111,8 @@ struct g_class {
};
#define G_VERSION_00 0x19950323
-#define G_VERSION G_VERSION_00
+#define G_VERSION_01 0x20041207 /* add fflag to g_ioctl_t */
+#define G_VERSION G_VERSION_01
/*
* The g_geom is an instance of a g_class.
diff --git a/sys/geom/geom_bsd.c b/sys/geom/geom_bsd.c
index 0f880a3..eaddb98 100644
--- a/sys/geom/geom_bsd.c
+++ b/sys/geom/geom_bsd.c
@@ -44,6 +44,7 @@ __FBSDID("$FreeBSD$");
#include <sys/endian.h>
#include <sys/systm.h>
#include <sys/kernel.h>
+#include <sys/fcntl.h>
#include <sys/conf.h>
#include <sys/bio.h>
#include <sys/malloc.h>
@@ -315,7 +316,7 @@ g_bsd_hotwrite(void *arg, int flag)
* * Don't call biowait, g_getattr(), g_setattr() or g_read_data()
*/
static int
-g_bsd_ioctl(struct g_provider *pp, u_long cmd, void * data, struct thread *td)
+g_bsd_ioctl(struct g_provider *pp, u_long cmd, void *data, int fflag, struct thread *td)
{
struct g_geom *gp;
struct g_bsd_softc *ms;
@@ -339,6 +340,8 @@ g_bsd_ioctl(struct g_provider *pp, u_long cmd, void * data, struct thread *td)
int error, i;
uint64_t sum;
+ if (!(fflag & FWRITE))
+ return (EPERM);
/* The disklabel to set is the ioctl argument. */
buf = g_malloc(BBSIZE, M_WAITOK);
p = *(void **)data;
@@ -369,6 +372,8 @@ g_bsd_ioctl(struct g_provider *pp, u_long cmd, void * data, struct thread *td)
case DIOCWDINFO: {
label = g_malloc(LABELSIZE, M_WAITOK);
+ if (!(fflag & FWRITE))
+ return (EPERM);
/* The disklabel to set is the ioctl argument. */
bsd_disklabel_le_enc(label, data);
diff --git a/sys/geom/geom_dev.c b/sys/geom/geom_dev.c
index e4efbc6..621631d 100644
--- a/sys/geom/geom_dev.c
+++ b/sys/geom/geom_dev.c
@@ -307,7 +307,7 @@ g_dev_ioctl(struct cdev *dev, u_long cmd, caddr_t data, int fflag, struct thread
default:
if (cp->provider->geom->ioctl != NULL) {
- error = cp->provider->geom->ioctl(cp->provider, cmd, data, td);
+ error = cp->provider->geom->ioctl(cp->provider, cmd, data, fflag, td);
} else {
error = ENOIOCTL;
}
diff --git a/sys/geom/geom_disk.c b/sys/geom/geom_disk.c
index bf101e6..38f73d3 100644
--- a/sys/geom/geom_disk.c
+++ b/sys/geom/geom_disk.c
@@ -212,7 +212,7 @@ g_disk_done(struct bio *bp)
}
static int
-g_disk_ioctl(struct g_provider *pp, u_long cmd, void * data, struct thread *td)
+g_disk_ioctl(struct g_provider *pp, u_long cmd, void * data, int fflag, struct thread *td)
{
struct g_geom *gp;
struct disk *dp;
@@ -224,7 +224,7 @@ g_disk_ioctl(struct g_provider *pp, u_long cmd, void * data, struct thread *td)
if (dp->d_ioctl == NULL)
return (ENOIOCTL);
g_disk_lock_giant(dp);
- error = dp->d_ioctl(dp, cmd, data, 0, td);
+ error = dp->d_ioctl(dp, cmd, data, fflag, td);
g_disk_unlock_giant(dp);
return(error);
}
diff --git a/sys/geom/geom_mbr.c b/sys/geom/geom_mbr.c
index 2e19757..bedfa0c 100644
--- a/sys/geom/geom_mbr.c
+++ b/sys/geom/geom_mbr.c
@@ -38,6 +38,7 @@ __FBSDID("$FreeBSD$");
#include <sys/endian.h>
#include <sys/systm.h>
#include <sys/kernel.h>
+#include <sys/fcntl.h>
#include <sys/malloc.h>
#include <sys/bio.h>
#include <sys/lock.h>
@@ -153,7 +154,7 @@ g_mbr_modify(struct g_geom *gp, struct g_mbr_softc *ms, u_char *sec0)
}
static int
-g_mbr_ioctl(struct g_provider *pp, u_long cmd, void *data, struct thread *td)
+g_mbr_ioctl(struct g_provider *pp, u_long cmd, void *data, int fflag, struct thread *td)
{
struct g_geom *gp;
struct g_mbr_softc *ms;
@@ -169,6 +170,8 @@ g_mbr_ioctl(struct g_provider *pp, u_long cmd, void *data, struct thread *td)
error = 0;
switch(cmd) {
case DIOCSMBR: {
+ if (!(fflag & FWRITE))
+ return (EPERM);
DROP_GIANT();
g_topology_lock();
cp = LIST_FIRST(&gp->consumer);
diff --git a/sys/geom/geom_pc98.c b/sys/geom/geom_pc98.c
index f30cb9d..d887b25 100644
--- a/sys/geom/geom_pc98.c
+++ b/sys/geom/geom_pc98.c
@@ -37,6 +37,7 @@ __FBSDID("$FreeBSD$");
#include <sys/endian.h>
#include <sys/systm.h>
#include <sys/kernel.h>
+#include <sys/fcntl.h>
#include <sys/malloc.h>
#include <sys/bio.h>
#include <sys/lock.h>
@@ -148,7 +149,7 @@ g_pc98_modify(struct g_geom *gp, struct g_pc98_softc *ms, u_char *sec)
}
static int
-g_pc98_ioctl(struct g_provider *pp, u_long cmd, void *data, struct thread *td)
+g_pc98_ioctl(struct g_provider *pp, u_long cmd, void *data, int fflag, struct thread *td)
{
struct g_geom *gp;
struct g_pc98_softc *ms;
@@ -162,6 +163,8 @@ g_pc98_ioctl(struct g_provider *pp, u_long cmd, void *data, struct thread *td)
switch(cmd) {
case DIOCSPC98: {
+ if (!(fflag & FWRITE))
+ return (EPERM);
DROP_GIANT();
g_topology_lock();
/* Validate and modify our slicer instance to match. */
OpenPOWER on IntegriCloud