summaryrefslogtreecommitdiffstats
path: root/sys/geom
diff options
context:
space:
mode:
authorsam <sam@FreeBSD.org>2009-03-11 01:12:52 +0000
committersam <sam@FreeBSD.org>2009-03-11 01:12:52 +0000
commit827e98884ff946f81179cc54d66e082e4f976a71 (patch)
treea10343f8b3b01851b847a0f754da86cda1e6001b /sys/geom
parentfae6f1ab823ff29d6165da7eb2dcae9534b1428c (diff)
downloadFreeBSD-src-827e98884ff946f81179cc54d66e082e4f976a71.zip
FreeBSD-src-827e98884ff946f81179cc54d66e082e4f976a71.tar.gz
o disallow write to RedBoot and FIS directory partitions; these are painful
to resurrect (maybe honor foot shooting bit in kern.geom_debugflags) o fix match macro so we now recognize we want to merge FIS dir with RedBoot config parameters even if we don't actually do it
Diffstat (limited to 'sys/geom')
-rw-r--r--sys/geom/geom_redboot.c25
1 files changed, 23 insertions, 2 deletions
diff --git a/sys/geom/geom_redboot.c b/sys/geom/geom_redboot.c
index 8ab8920..0314fe7 100644
--- a/sys/geom/geom_redboot.c
+++ b/sys/geom/geom_redboot.c
@@ -62,6 +62,7 @@ struct fis_image_desc {
#define FISDIR_NAME "FIS directory"
#define REDBCFG_NAME "RedBoot config"
+#define REDBOOT_NAME "RedBoot"
#define REDBOOT_MAXSLICE 64
#define REDBOOT_MAXOFF \
@@ -70,6 +71,8 @@ struct fis_image_desc {
struct g_redboot_softc {
uint32_t entry[REDBOOT_MAXSLICE];
uint32_t dsize[REDBOOT_MAXSLICE];
+ uint8_t readonly[REDBOOT_MAXSLICE];
+ g_access_t *parent_access;
};
static void
@@ -90,6 +93,18 @@ g_redboot_ioctl(struct g_provider *pp, u_long cmd, void *data, int fflag, struct
}
static int
+g_redboot_access(struct g_provider *pp, int dread, int dwrite, int dexcl)
+{
+ struct g_geom *gp = pp->geom;
+ struct g_slicer *gsp = gp->softc;
+ struct g_redboot_softc *sc = gsp->softc;
+
+ if (dwrite > 0 && sc->readonly[pp->index])
+ return (EPERM);
+ return (sc->parent_access(pp, dread, dwrite, dexcl));
+}
+
+static int
g_redboot_start(struct bio *bp)
{
struct g_provider *pp;
@@ -155,8 +170,7 @@ nameok(const char name[16])
static struct fis_image_desc *
parse_fis_directory(u_char *buf, size_t bufsize, off_t offset, uint32_t offmask)
{
-#define match(a,b) \
- (bcmp(fd->name, FISDIR_NAME, sizeof(FISDIR_NAME)-1) == 0)
+#define match(a,b) (bcmp(a, b, sizeof(b)-1) == 0)
struct fis_image_desc *fd, *efd;
struct fis_image_desc *fisdir, *redbcfg;
struct fis_image_desc *head, **tail;
@@ -242,6 +256,10 @@ g_redboot_taste(struct g_class *mp, struct g_provider *pp, int insist)
g_redboot_start);
if (gp == NULL)
return (NULL);
+ /* interpose our access method */
+ sc->parent_access = gp->access;
+ gp->access = g_redboot_access;
+
sectorsize = cp->provider->sectorsize;
blksize = cp->provider->stripesize;
if (powerof2(cp->provider->mediasize))
@@ -287,6 +305,9 @@ again:
__func__, error, fd->name);
sc->entry[i] = fd->entry;
sc->dsize[i] = fd->dsize;
+ /* disallow writing hard-to-recover entries */
+ sc->readonly[i] = (strcmp(fd->name, FISDIR_NAME) == 0) ||
+ (strcmp(fd->name, REDBOOT_NAME) == 0);
i++;
}
g_free(buf);
OpenPOWER on IntegriCloud