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>
This commit is contained in:
Poul-Henning Kamp 2004-12-12 10:09:05 +00:00
parent a09345e6cd
commit 2221dbebce
8 changed files with 29 additions and 11 deletions

View File

@ -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;

View File

@ -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 */

View File

@ -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.

View File

@ -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);

View File

@ -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;
}

View File

@ -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);
}

View File

@ -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);

View File

@ -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. */