Ensure that file flags such as schg, sappnd (and others) are honored

by md(4). Before this change, it was possible to by-pass these flags
by creating memory disks which used a file as a backing store and
writing to the device.

This was discussed by the security team, and although this is problematic,
it was decided that it was not critical as we never guarantee that root will
be restricted.

This change implements the following behavior changes:

-If the user specifies the readonly flag, unset write operations before
 opening the file. If the FWRITE mask is unset, the device will be
 created with the MD_READONLY mask set. (readonly)
-Add a check in g_md_access which checks to see if the MD_READONLY mask
 is set, if so return EROFS
-Do not gracefully downgrade access modes without telling the user. Instead
 make the user specify their intentions for the device (assuming the file is
 read only). This seems like the more correct way to handle things.

This is a RELENG_6 candidate.

PR:		kern/84635
Reviewed by:	phk
This commit is contained in:
Christian S.J. Peron 2005-08-17 01:24:55 +00:00
parent 13b302a79f
commit 8677689134
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=149171

View File

@ -361,6 +361,8 @@ g_md_access(struct g_provider *pp, int r, int w, int e)
r += pp->acr;
w += pp->acw;
e += pp->ace;
if ((sc->flags & MD_READONLY) != 0 && w > 0)
return (EROFS);
if ((pp->acr + pp->acw + pp->ace) == 0 && (r + w + e) > 0) {
sc->opencount = 1;
} else if ((pp->acr + pp->acw + pp->ace) > 0 && (r + w + e) == 0) {
@ -880,16 +882,14 @@ mdcreate_vnode(struct md_s *sc, struct md_ioctl *mdio, struct thread *td)
if (error != 0)
return (error);
flags = FREAD|FWRITE;
/*
* If the user specified that this is a read only device, unset the
* FWRITE mask before trying to open the backing store.
*/
if ((mdio->md_options & MD_READONLY) != 0)
flags &= ~FWRITE;
NDINIT(&nd, LOOKUP, FOLLOW, UIO_SYSSPACE, sc->file, td);
error = vn_open(&nd, &flags, 0, -1);
if (error != 0) {
NDFREE(&nd, NDF_ONLY_PNBUF);
if (error != EACCES && error != EPERM && error != EROFS)
return (error);
flags &= ~FWRITE;
NDINIT(&nd, LOOKUP, FOLLOW, UIO_SYSSPACE, sc->file, td);
error = vn_open(&nd, &flags, 0, -1);
}
NDFREE(&nd, NDF_ONLY_PNBUF);
if (error != 0)
return (error);