From 35b3c9fdfbd8e466654ebad62b044a7d3c01f3b7 Mon Sep 17 00:00:00 2001 From: phk Date: Sun, 12 Dec 2004 10:09:05 +0000 Subject: 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 --- sys/dev/ata/atapi-cd.c | 4 ++-- sys/dev/fdc/fdc.c | 8 +++++++- sys/geom/geom.h | 5 +++-- sys/geom/geom_bsd.c | 7 ++++++- sys/geom/geom_dev.c | 2 +- sys/geom/geom_disk.c | 4 ++-- sys/geom/geom_mbr.c | 5 ++++- sys/geom/geom_pc98.c | 5 ++++- 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 #include #include +#include #include #include #include @@ -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 #include #include +#include #include #include #include @@ -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 #include #include +#include #include #include #include @@ -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. */ -- cgit v1.1