Add the fo_chown and fo_chmod methods to struct fileops and use them

to implement fchown(2) and fchmod(2) support for several file types
that previously lacked it. Add MAC entries for chown/chmod done on
posix shared memory and (old) in-kernel posix semaphores.

Based on the submission by:	glebius
Reviewed by:	rwatson
Approved by:	re (bz)
This commit is contained in:
Konstantin Belousov 2011-08-16 20:07:47 +00:00
parent 985a88e2a6
commit 9c00bb9190
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=224914
24 changed files with 533 additions and 50 deletions

View File

@ -95,7 +95,9 @@ static struct fileops svr4_netops = {
.fo_poll = soo_poll,
.fo_kqfilter = soo_kqfilter,
.fo_stat = soo_stat,
.fo_close = svr4_soo_close
.fo_close = svr4_soo_close,
.fo_chmod = invfo_chmod,
.fo_chown = invfo_chown,
};
static struct cdevsw streams_cdevsw = {

View File

@ -1665,6 +1665,8 @@ static struct fileops devfs_ops_f = {
.fo_kqfilter = devfs_kqfilter_f,
.fo_stat = devfs_stat_f,
.fo_close = devfs_close_f,
.fo_chmod = vn_chmod,
.fo_chown = vn_chown,
.fo_flags = DFLAG_PASSABLE | DFLAG_SEEKABLE
};

View File

@ -72,6 +72,8 @@ struct fileops fifo_ops_f = {
.fo_kqfilter = fifo_kqfilter_f,
.fo_stat = fifo_stat_f,
.fo_close = fifo_close_f,
.fo_chmod = vn_chmod,
.fo_chown = vn_chown,
.fo_flags = DFLAG_PASSABLE
};

View File

@ -3774,6 +3774,22 @@ badfo_close(struct file *fp, struct thread *td)
return (EBADF);
}
static int
badfo_chmod(struct file *fp, mode_t mode, struct ucred *active_cred,
struct thread *td)
{
return (EBADF);
}
static int
badfo_chown(struct file *fp, uid_t uid, gid_t gid, struct ucred *active_cred,
struct thread *td)
{
return (EBADF);
}
struct fileops badfileops = {
.fo_read = badfo_readwrite,
.fo_write = badfo_readwrite,
@ -3783,8 +3799,25 @@ struct fileops badfileops = {
.fo_kqfilter = badfo_kqfilter,
.fo_stat = badfo_stat,
.fo_close = badfo_close,
.fo_chmod = badfo_chmod,
.fo_chown = badfo_chown,
};
int
invfo_chmod(struct file *fp, mode_t mode, struct ucred *active_cred,
struct thread *td)
{
return (EINVAL);
}
int
invfo_chown(struct file *fp, uid_t uid, gid_t gid, struct ucred *active_cred,
struct thread *td)
{
return (EINVAL);
}
/*-------------------------------------------------------------------*/

View File

@ -123,6 +123,8 @@ static struct fileops kqueueops = {
.fo_kqfilter = kqueue_kqfilter,
.fo_stat = kqueue_stat,
.fo_close = kqueue_close,
.fo_chmod = invfo_chmod,
.fo_chown = invfo_chown,
};
static int knote_attach(struct knote *kn, struct kqueue *kq);

View File

@ -161,6 +161,8 @@ static fo_poll_t capability_poll;
static fo_kqfilter_t capability_kqfilter;
static fo_stat_t capability_stat;
static fo_close_t capability_close;
static fo_chmod_t capability_chmod;
static fo_chown_t capability_chown;
static struct fileops capability_ops = {
.fo_read = capability_read,
@ -171,6 +173,8 @@ static struct fileops capability_ops = {
.fo_kqfilter = capability_kqfilter,
.fo_stat = capability_stat,
.fo_close = capability_close,
.fo_chmod = capability_chmod,
.fo_chown = capability_chown,
.fo_flags = DFLAG_PASSABLE,
};
@ -183,6 +187,8 @@ static struct fileops capability_ops_unpassable = {
.fo_kqfilter = capability_kqfilter,
.fo_stat = capability_stat,
.fo_close = capability_close,
.fo_chmod = capability_chmod,
.fo_chown = capability_chown,
.fo_flags = 0,
};
@ -484,6 +490,22 @@ capability_stat(struct file *fp, struct stat *sb, struct ucred *active_cred,
panic("capability_stat");
}
int
capability_chmod(struct file *fp, mode_t mode, struct ucred *active_cred,
struct thread *td)
{
panic("capability_chmod");
}
int
capability_chown(struct file *fp, uid_t uid, gid_t gid,
struct ucred *active_cred, struct thread *td)
{
panic("capability_chown");
}
#else /* !CAPABILITIES */
/*

View File

@ -155,6 +155,8 @@ static struct fileops pipeops = {
.fo_kqfilter = pipe_kqfilter,
.fo_stat = pipe_stat,
.fo_close = pipe_close,
.fo_chmod = invfo_chmod,
.fo_chown = invfo_chown,
.fo_flags = DFLAG_PASSABLE
};

View File

@ -64,6 +64,8 @@ struct fileops socketops = {
.fo_kqfilter = soo_kqfilter,
.fo_stat = soo_stat,
.fo_close = soo_close,
.fo_chmod = invfo_chmod,
.fo_chown = invfo_chown,
.fo_flags = DFLAG_PASSABLE
};

View File

@ -597,6 +597,8 @@ static struct fileops ptsdev_ops = {
.fo_kqfilter = ptsdev_kqfilter,
.fo_stat = ptsdev_stat,
.fo_close = ptsdev_close,
.fo_chmod = invfo_chmod,
.fo_chown = invfo_chown,
.fo_flags = DFLAG_PASSABLE,
};

View File

@ -2469,6 +2469,7 @@ mqf_stat(struct file *fp, struct stat *st, struct ucred *active_cred,
struct mqfs_node *pn = fp->f_data;
bzero(st, sizeof *st);
sx_xlock(&mqfs_data.mi_lock);
st->st_atim = pn->mn_atime;
st->st_mtim = pn->mn_mtime;
st->st_ctim = pn->mn_ctime;
@ -2476,9 +2477,55 @@ mqf_stat(struct file *fp, struct stat *st, struct ucred *active_cred,
st->st_uid = pn->mn_uid;
st->st_gid = pn->mn_gid;
st->st_mode = S_IFIFO | pn->mn_mode;
sx_xunlock(&mqfs_data.mi_lock);
return (0);
}
static int
mqf_chmod(struct file *fp, mode_t mode, struct ucred *active_cred,
struct thread *td)
{
struct mqfs_node *pn;
int error;
error = 0;
pn = fp->f_data;
sx_xlock(&mqfs_data.mi_lock);
error = vaccess(VREG, pn->mn_mode, pn->mn_uid, pn->mn_gid, VADMIN,
active_cred, NULL);
if (error != 0)
goto out;
pn->mn_mode = mode & ACCESSPERMS;
out:
sx_xunlock(&mqfs_data.mi_lock);
return (error);
}
static int
mqf_chown(struct file *fp, uid_t uid, gid_t gid, struct ucred *active_cred,
struct thread *td)
{
struct mqfs_node *pn;
int error;
error = 0;
pn = fp->f_data;
sx_xlock(&mqfs_data.mi_lock);
if (uid == (uid_t)-1)
uid = pn->mn_uid;
if (gid == (gid_t)-1)
gid = pn->mn_gid;
if (((uid != pn->mn_uid && uid != active_cred->cr_uid) ||
(gid != pn->mn_gid && !groupmember(gid, active_cred))) &&
(error = priv_check_cred(active_cred, PRIV_VFS_CHOWN, 0)))
goto out;
pn->mn_uid = uid;
pn->mn_gid = gid;
out:
sx_xunlock(&mqfs_data.mi_lock);
return (error);
}
static int
mqf_kqfilter(struct file *fp, struct knote *kn)
{
@ -2535,6 +2582,8 @@ static struct fileops mqueueops = {
.fo_poll = mqf_poll,
.fo_kqfilter = mqf_kqfilter,
.fo_stat = mqf_stat,
.fo_chmod = mqf_chmod,
.fo_chown = mqf_chown,
.fo_close = mqf_close
};

View File

@ -135,6 +135,8 @@ static fo_poll_t ksem_poll;
static fo_kqfilter_t ksem_kqfilter;
static fo_stat_t ksem_stat;
static fo_close_t ksem_closef;
static fo_chmod_t ksem_chmod;
static fo_chown_t ksem_chown;
/* File descriptor operations. */
static struct fileops ksem_ops = {
@ -146,6 +148,8 @@ static struct fileops ksem_ops = {
.fo_kqfilter = ksem_kqfilter,
.fo_stat = ksem_stat,
.fo_close = ksem_closef,
.fo_chmod = ksem_chmod,
.fo_chown = ksem_chown,
.fo_flags = DFLAG_PASSABLE
};
@ -220,18 +224,74 @@ ksem_stat(struct file *fp, struct stat *sb, struct ucred *active_cred,
* file descriptor.
*/
bzero(sb, sizeof(*sb));
sb->st_mode = S_IFREG | ks->ks_mode; /* XXX */
mtx_lock(&sem_lock);
sb->st_atim = ks->ks_atime;
sb->st_ctim = ks->ks_ctime;
sb->st_mtim = ks->ks_mtime;
sb->st_birthtim = ks->ks_birthtime;
sb->st_birthtim = ks->ks_birthtime;
sb->st_uid = ks->ks_uid;
sb->st_gid = ks->ks_gid;
sb->st_mode = S_IFREG | ks->ks_mode; /* XXX */
mtx_unlock(&sem_lock);
return (0);
}
static int
ksem_chmod(struct file *fp, mode_t mode, struct ucred *active_cred,
struct thread *td)
{
struct ksem *ks;
int error;
error = 0;
ks = fp->f_data;
mtx_lock(&sem_lock);
#ifdef MAC
error = mac_posixsem_check_setmode(active_cred, ks, mode);
if (error != 0)
goto out;
#endif
error = vaccess(VREG, ks->ks_mode, ks->ks_uid, ks->ks_gid, VADMIN,
active_cred, NULL);
if (error != 0)
goto out;
ks->ks_mode = mode & ACCESSPERMS;
out:
mtx_unlock(&sem_lock);
return (error);
}
static int
ksem_chown(struct file *fp, uid_t uid, gid_t gid, struct ucred *active_cred,
struct thread *td)
{
struct ksem *ks;
int error;
ks = fp->f_data;
mtx_lock(&sem_lock);
#ifdef MAC
error = mac_posixsem_check_setowner(active_cred, ks, uid, gid);
if (error != 0)
goto out;
#endif
if (uid == (uid_t)-1)
uid = ks->ks_uid;
if (gid == (gid_t)-1)
gid = ks->ks_gid;
if (((uid != ks->ks_uid && uid != active_cred->cr_uid) ||
(gid != ks->ks_gid && !groupmember(gid, active_cred))) &&
(error = priv_check_cred(active_cred, PRIV_VFS_CHOWN, 0)))
goto out;
ks->ks_uid = uid;
ks->ks_gid = gid;
out:
mtx_unlock(&sem_lock);
return (error);
}
static int
ksem_closef(struct file *fp, struct thread *td)
{

View File

@ -68,6 +68,7 @@ __FBSDID("$FreeBSD$");
#include <sys/malloc.h>
#include <sys/mman.h>
#include <sys/mutex.h>
#include <sys/priv.h>
#include <sys/proc.h>
#include <sys/refcount.h>
#include <sys/resourcevar.h>
@ -123,6 +124,8 @@ static fo_poll_t shm_poll;
static fo_kqfilter_t shm_kqfilter;
static fo_stat_t shm_stat;
static fo_close_t shm_close;
static fo_chmod_t shm_chmod;
static fo_chown_t shm_chown;
/* File descriptor operations. */
static struct fileops shm_ops = {
@ -134,6 +137,8 @@ static struct fileops shm_ops = {
.fo_kqfilter = shm_kqfilter,
.fo_stat = shm_stat,
.fo_close = shm_close,
.fo_chmod = shm_chmod,
.fo_chown = shm_chown,
.fo_flags = DFLAG_PASSABLE
};
@ -218,16 +223,18 @@ shm_stat(struct file *fp, struct stat *sb, struct ucred *active_cred,
* descriptor.
*/
bzero(sb, sizeof(*sb));
sb->st_mode = S_IFREG | shmfd->shm_mode; /* XXX */
sb->st_blksize = PAGE_SIZE;
sb->st_size = shmfd->shm_size;
sb->st_blocks = (sb->st_size + sb->st_blksize - 1) / sb->st_blksize;
mtx_lock(&shm_timestamp_lock);
sb->st_atim = shmfd->shm_atime;
sb->st_ctim = shmfd->shm_ctime;
sb->st_mtim = shmfd->shm_mtime;
sb->st_birthtim = shmfd->shm_birthtime;
sb->st_birthtim = shmfd->shm_birthtime;
sb->st_mode = S_IFREG | shmfd->shm_mode; /* XXX */
sb->st_uid = shmfd->shm_uid;
sb->st_gid = shmfd->shm_gid;
mtx_unlock(&shm_timestamp_lock);
return (0);
}
@ -395,14 +402,18 @@ static int
shm_access(struct shmfd *shmfd, struct ucred *ucred, int flags)
{
accmode_t accmode;
int error;
accmode = 0;
if (flags & FREAD)
accmode |= VREAD;
if (flags & FWRITE)
accmode |= VWRITE;
return (vaccess(VREG, shmfd->shm_mode, shmfd->shm_uid, shmfd->shm_gid,
accmode, ucred, NULL));
mtx_lock(&shm_timestamp_lock);
error = vaccess(VREG, shmfd->shm_mode, shmfd->shm_uid, shmfd->shm_gid,
accmode, ucred, NULL);
mtx_unlock(&shm_timestamp_lock);
return (error);
}
/*
@ -651,3 +662,61 @@ shm_mmap(struct shmfd *shmfd, vm_size_t objsize, vm_ooffset_t foff,
*obj = shmfd->shm_object;
return (0);
}
static int
shm_chmod(struct file *fp, mode_t mode, struct ucred *active_cred,
struct thread *td)
{
struct shmfd *shmfd;
int error;
error = 0;
shmfd = fp->f_data;
mtx_lock(&shm_timestamp_lock);
/*
* SUSv4 says that x bits of permission need not be affected.
* Be consistent with our shm_open there.
*/
#ifdef MAC
error = mac_posixshm_check_setmode(active_cred, shmfd, mode);
if (error != 0)
goto out;
#endif
error = vaccess(VREG, shmfd->shm_mode, shmfd->shm_uid,
shmfd->shm_gid, VADMIN, active_cred, NULL);
if (error != 0)
goto out;
shmfd->shm_mode = mode & ACCESSPERMS;
out:
mtx_unlock(&shm_timestamp_lock);
return (error);
}
static int
shm_chown(struct file *fp, uid_t uid, gid_t gid, struct ucred *active_cred,
struct thread *td)
{
struct shmfd *shmfd;
int error;
shmfd = fp->f_data;
mtx_lock(&shm_timestamp_lock);
#ifdef MAC
error = mac_posixshm_check_setowner(active_cred, shmfd, uid, gid);
if (error != 0)
goto out;
#endif
if (uid == (uid_t)-1)
uid = shmfd->shm_uid;
if (gid == (gid_t)-1)
gid = shmfd->shm_gid;
if (((uid != shmfd->shm_uid && uid != active_cred->cr_uid) ||
(gid != shmfd->shm_gid && !groupmember(gid, active_cred))) &&
(error = priv_check_cred(active_cred, PRIV_VFS_CHOWN, 0)))
goto out;
shmfd->shm_uid = uid;
shmfd->shm_gid = gid;
out:
mtx_unlock(&shm_timestamp_lock);
return (error);
}

View File

@ -96,8 +96,6 @@ SDT_PROBE_ARGTYPE(vfs, , stat, reg, 1, "int");
static int chroot_refuse_vdir_fds(struct filedesc *fdp);
static int getutimes(const struct timeval *, enum uio_seg, struct timespec *);
static int setfown(struct thread *td, struct vnode *, uid_t, gid_t);
static int setfmode(struct thread *td, struct vnode *, int);
static int setfflags(struct thread *td, struct vnode *, int);
static int setutimes(struct thread *td, struct vnode *,
const struct timespec *, int, int);
@ -2865,9 +2863,10 @@ fchflags(td, uap)
/*
* Common implementation code for chmod(), lchmod() and fchmod().
*/
static int
setfmode(td, vp, mode)
int
setfmode(td, cred, vp, mode)
struct thread *td;
struct ucred *cred;
struct vnode *vp;
int mode;
{
@ -2881,10 +2880,10 @@ setfmode(td, vp, mode)
VATTR_NULL(&vattr);
vattr.va_mode = mode & ALLPERMS;
#ifdef MAC
error = mac_vnode_check_setmode(td->td_ucred, vp, vattr.va_mode);
error = mac_vnode_check_setmode(cred, vp, vattr.va_mode);
if (error == 0)
#endif
error = VOP_SETATTR(vp, &vattr, td->td_ucred);
error = VOP_SETATTR(vp, &vattr, cred);
VOP_UNLOCK(vp, 0);
vn_finished_write(mp);
return (error);
@ -2980,7 +2979,7 @@ kern_fchmodat(struct thread *td, int fd, char *path, enum uio_seg pathseg,
return (error);
vfslocked = NDHASGIANT(&nd);
NDFREE(&nd, NDF_ONLY_PNBUF);
error = setfmode(td, nd.ni_vp, mode);
error = setfmode(td, td->td_ucred, nd.ni_vp, mode);
vrele(nd.ni_vp);
VFS_UNLOCK_GIANT(vfslocked);
return (error);
@ -2996,30 +2995,18 @@ struct fchmod_args {
};
#endif
int
fchmod(td, uap)
struct thread *td;
register struct fchmod_args /* {
int fd;
int mode;
} */ *uap;
fchmod(struct thread *td, struct fchmod_args *uap)
{
struct file *fp;
int vfslocked;
int error;
AUDIT_ARG_FD(uap->fd);
AUDIT_ARG_MODE(uap->mode);
if ((error = getvnode(td->td_proc->p_fd, uap->fd, CAP_FCHMOD,
&fp)) != 0)
error = fget(td, uap->fd, CAP_FCHMOD, &fp);
if (error != 0)
return (error);
vfslocked = VFS_LOCK_GIANT(fp->f_vnode->v_mount);
#ifdef AUDIT
vn_lock(fp->f_vnode, LK_SHARED | LK_RETRY);
AUDIT_ARG_VNODE1(fp->f_vnode);
VOP_UNLOCK(fp->f_vnode, 0);
#endif
error = setfmode(td, fp->f_vnode, uap->mode);
VFS_UNLOCK_GIANT(vfslocked);
error = fo_chmod(fp, uap->mode, td->td_ucred, td);
fdrop(fp, td);
return (error);
}
@ -3027,9 +3014,10 @@ fchmod(td, uap)
/*
* Common implementation for chown(), lchown(), and fchown()
*/
static int
setfown(td, vp, uid, gid)
int
setfown(td, cred, vp, uid, gid)
struct thread *td;
struct ucred *cred;
struct vnode *vp;
uid_t uid;
gid_t gid;
@ -3045,11 +3033,11 @@ setfown(td, vp, uid, gid)
vattr.va_uid = uid;
vattr.va_gid = gid;
#ifdef MAC
error = mac_vnode_check_setowner(td->td_ucred, vp, vattr.va_uid,
error = mac_vnode_check_setowner(cred, vp, vattr.va_uid,
vattr.va_gid);
if (error == 0)
#endif
error = VOP_SETATTR(vp, &vattr, td->td_ucred);
error = VOP_SETATTR(vp, &vattr, cred);
VOP_UNLOCK(vp, 0);
vn_finished_write(mp);
return (error);
@ -3124,7 +3112,7 @@ kern_fchownat(struct thread *td, int fd, char *path, enum uio_seg pathseg,
return (error);
vfslocked = NDHASGIANT(&nd);
NDFREE(&nd, NDF_ONLY_PNBUF);
error = setfown(td, nd.ni_vp, uid, gid);
error = setfown(td, td->td_ucred, nd.ni_vp, uid, gid);
vrele(nd.ni_vp);
VFS_UNLOCK_GIANT(vfslocked);
return (error);
@ -3182,22 +3170,14 @@ fchown(td, uap)
} */ *uap;
{
struct file *fp;
int vfslocked;
int error;
AUDIT_ARG_FD(uap->fd);
AUDIT_ARG_OWNER(uap->uid, uap->gid);
if ((error = getvnode(td->td_proc->p_fd, uap->fd, CAP_FCHOWN, &fp))
!= 0)
error = fget(td, uap->fd, CAP_FCHOWN, &fp);
if (error != 0)
return (error);
vfslocked = VFS_LOCK_GIANT(fp->f_vnode->v_mount);
#ifdef AUDIT
vn_lock(fp->f_vnode, LK_SHARED | LK_RETRY);
AUDIT_ARG_VNODE1(fp->f_vnode);
VOP_UNLOCK(fp->f_vnode, 0);
#endif
error = setfown(td, fp->f_vnode, uap->uid, uap->gid);
VFS_UNLOCK_GIANT(vfslocked);
error = fo_chown(fp, uap->uid, uap->gid, td->td_ucred, td);
fdrop(fp, td);
return (error);
}

View File

@ -61,6 +61,7 @@ __FBSDID("$FreeBSD$");
#include <sys/syslog.h>
#include <sys/unistd.h>
#include <security/audit/audit.h>
#include <security/mac/mac_framework.h>
static fo_rdwr_t vn_read;
@ -81,6 +82,8 @@ struct fileops vnops = {
.fo_kqfilter = vn_kqfilter,
.fo_stat = vn_statfile,
.fo_close = vn_closefile,
.fo_chmod = vn_chmod,
.fo_chown = vn_chown,
.fo_flags = DFLAG_PASSABLE | DFLAG_SEEKABLE
};
@ -1357,3 +1360,41 @@ vn_rlimit_fsize(const struct vnode *vp, const struct uio *uio,
PROC_UNLOCK(td->td_proc);
return (0);
}
int
vn_chmod(struct file *fp, mode_t mode, struct ucred *active_cred,
struct thread *td)
{
struct vnode *vp;
int error, vfslocked;
vp = fp->f_vnode;
vfslocked = VFS_LOCK_GIANT(vp->v_mount);
#ifdef AUDIT
vn_lock(vp, LK_SHARED | LK_RETRY);
AUDIT_ARG_VNODE1(vp);
VOP_UNLOCK(vp, 0);
#endif
error = setfmode(td, active_cred, vp, mode);
VFS_UNLOCK_GIANT(vfslocked);
return (error);
}
int
vn_chown(struct file *fp, uid_t uid, gid_t gid, struct ucred *active_cred,
struct thread *td)
{
struct vnode *vp;
int error, vfslocked;
vp = fp->f_vnode;
vfslocked = VFS_LOCK_GIANT(vp->v_mount);
#ifdef AUDIT
vn_lock(vp, LK_SHARED | LK_RETRY);
AUDIT_ARG_VNODE1(vp);
VOP_UNLOCK(vp, 0);
#endif
error = setfown(td, active_cred, vp, uid, gid);
VFS_UNLOCK_GIANT(vfslocked);
return (error);
}

View File

@ -559,7 +559,9 @@ struct fileops linuxfileops = {
.fo_read = linux_file_read,
.fo_poll = linux_file_poll,
.fo_close = linux_file_close,
.fo_ioctl = linux_file_ioctl
.fo_ioctl = linux_file_ioctl,
.fo_chmod = invfo_chmod,
.fo_chown = invfo_chown,
};
/*

View File

@ -301,7 +301,9 @@ static struct fileops cryptofops = {
.fo_poll = cryptof_poll,
.fo_kqfilter = cryptof_kqfilter,
.fo_stat = cryptof_stat,
.fo_close = cryptof_close
.fo_close = cryptof_close,
.fo_chmod = invfo_chmod,
.fo_chown = invfo_chown,
};
static struct csession *csefind(struct fcrypt *, u_int);

View File

@ -225,6 +225,10 @@ int mac_posixsem_check_getvalue(struct ucred *active_cred,
int mac_posixsem_check_open(struct ucred *cred, struct ksem *ks);
int mac_posixsem_check_post(struct ucred *active_cred,
struct ucred *file_cred, struct ksem *ks);
int mac_posixsem_check_setmode(struct ucred *cred, struct ksem *ks,
mode_t mode);
int mac_posixsem_check_setowner(struct ucred *cred, struct ksem *ks,
uid_t uid, gid_t gid);
int mac_posixsem_check_stat(struct ucred *active_cred,
struct ucred *file_cred, struct ksem *ks);
int mac_posixsem_check_unlink(struct ucred *cred, struct ksem *ks);
@ -237,6 +241,10 @@ void mac_posixsem_init(struct ksem *);
int mac_posixshm_check_mmap(struct ucred *cred, struct shmfd *shmfd,
int prot, int flags);
int mac_posixshm_check_open(struct ucred *cred, struct shmfd *shmfd);
int mac_posixshm_check_setmode(struct ucred *cred, struct shmfd *shmfd,
mode_t mode);
int mac_posixshm_check_setowner(struct ucred *cred, struct shmfd *shmfd,
uid_t uid, gid_t gid);
int mac_posixshm_check_stat(struct ucred *active_cred,
struct ucred *file_cred, struct shmfd *shmfd);
int mac_posixshm_check_truncate(struct ucred *active_cred,

View File

@ -336,6 +336,12 @@ typedef int (*mpo_posixsem_check_open_t)(struct ucred *cred,
typedef int (*mpo_posixsem_check_post_t)(struct ucred *active_cred,
struct ucred *file_cred, struct ksem *ks,
struct label *kslabel);
typedef int (*mpo_posixsem_check_setmode_t)(struct ucred *cred,
struct ksem *ks, struct label *shmlabel,
mode_t mode);
typedef int (*mpo_posixsem_check_setowner_t)(struct ucred *cred,
struct ksem *ks, struct label *shmlabel,
uid_t uid, gid_t gid);
typedef int (*mpo_posixsem_check_stat_t)(struct ucred *active_cred,
struct ucred *file_cred, struct ksem *ks,
struct label *kslabel);
@ -354,6 +360,12 @@ typedef int (*mpo_posixshm_check_mmap_t)(struct ucred *cred,
int flags);
typedef int (*mpo_posixshm_check_open_t)(struct ucred *cred,
struct shmfd *shmfd, struct label *shmlabel);
typedef int (*mpo_posixshm_check_setmode_t)(struct ucred *cred,
struct shmfd *shmfd, struct label *shmlabel,
mode_t mode);
typedef int (*mpo_posixshm_check_setowner_t)(struct ucred *cred,
struct shmfd *shmfd, struct label *shmlabel,
uid_t uid, gid_t gid);
typedef int (*mpo_posixshm_check_stat_t)(struct ucred *active_cred,
struct ucred *file_cred, struct shmfd *shmfd,
struct label *shmlabel);
@ -791,6 +803,8 @@ struct mac_policy_ops {
mpo_posixsem_check_getvalue_t mpo_posixsem_check_getvalue;
mpo_posixsem_check_open_t mpo_posixsem_check_open;
mpo_posixsem_check_post_t mpo_posixsem_check_post;
mpo_posixsem_check_setmode_t mpo_posixsem_check_setmode;
mpo_posixsem_check_setowner_t mpo_posixsem_check_setowner;
mpo_posixsem_check_stat_t mpo_posixsem_check_stat;
mpo_posixsem_check_unlink_t mpo_posixsem_check_unlink;
mpo_posixsem_check_wait_t mpo_posixsem_check_wait;
@ -800,6 +814,8 @@ struct mac_policy_ops {
mpo_posixshm_check_mmap_t mpo_posixshm_check_mmap;
mpo_posixshm_check_open_t mpo_posixshm_check_open;
mpo_posixshm_check_setmode_t mpo_posixshm_check_setmode;
mpo_posixshm_check_setowner_t mpo_posixshm_check_setowner;
mpo_posixshm_check_stat_t mpo_posixshm_check_stat;
mpo_posixshm_check_truncate_t mpo_posixshm_check_truncate;
mpo_posixshm_check_unlink_t mpo_posixshm_check_unlink;

View File

@ -198,3 +198,35 @@ mac_posixsem_check_wait(struct ucred *active_cred, struct ucred *file_cred,
return (error);
}
MAC_CHECK_PROBE_DEFINE3(posixsem_check_setmode, "struct ucred *",
"struct ksem *", "mode_t");
int
mac_posixsem_check_setmode(struct ucred *cred, struct ksem *ks, mode_t mode)
{
int error;
MAC_POLICY_CHECK_NOSLEEP(posixsem_check_setmode, cred, ks,
ks->ks_label, mode);
MAC_CHECK_PROBE3(posixsem_check_setmode, error, cred, ks, mode);
return (error);
}
MAC_CHECK_PROBE_DEFINE4(posixsem_check_setowner, "struct ucred *",
"struct ks *", "uid_t", "gid_t");
int
mac_posixsem_check_setowner(struct ucred *cred, struct ksem *ks, uid_t uid,
gid_t gid)
{
int error;
MAC_POLICY_CHECK_NOSLEEP(posixsem_check_setowner, cred, ks,
ks->ks_label, uid, gid);
MAC_CHECK_PROBE4(posixsem_check_setowner, error, cred, ks,
uid, gid);
return (error);
}

View File

@ -181,3 +181,35 @@ mac_posixshm_check_unlink(struct ucred *cred, struct shmfd *shmfd)
return (error);
}
MAC_CHECK_PROBE_DEFINE3(posixshm_check_setmode, "struct ucred *",
"struct shmfd *", "mode_t");
int
mac_posixshm_check_setmode(struct ucred *cred, struct shmfd *shmfd, mode_t mode)
{
int error;
MAC_POLICY_CHECK_NOSLEEP(posixshm_check_setmode, cred, shmfd,
shmfd->shm_label, mode);
MAC_CHECK_PROBE3(posixshm_check_setmode, error, cred, shmfd, mode);
return (error);
}
MAC_CHECK_PROBE_DEFINE4(posixshm_check_setowner, "struct ucred *",
"struct shmfd *", "uid_t", "gid_t");
int
mac_posixshm_check_setowner(struct ucred *cred, struct shmfd *shmfd, uid_t uid,
gid_t gid)
{
int error;
MAC_POLICY_CHECK_NOSLEEP(posixshm_check_setowner, cred, shmfd,
shmfd->shm_label, uid, gid);
MAC_CHECK_PROBE4(posixshm_check_setowner, error, cred, shmfd,
uid, gid);
return (error);
}

View File

@ -686,6 +686,22 @@ stub_posixsem_check_post(struct ucred *active_cred, struct ucred *file_cred,
return (0);
}
static int
stub_posixsem_check_setmode(struct ucred *cred, struct ksem *ks,
struct label *kslabel, mode_t mode)
{
return (0);
}
static int
stub_posixsem_check_setowner(struct ucred *cred, struct ksem *ks,
struct label *kslabel, uid_t uid, gid_t gid)
{
return (0);
}
static int
stub_posixsem_check_stat(struct ucred *active_cred, struct ucred *file_cred,
struct ksem *ks, struct label *kslabel)
@ -733,6 +749,22 @@ stub_posixshm_check_open(struct ucred *cred, struct shmfd *shmfd,
return (0);
}
static int
stub_posixshm_check_setmode(struct ucred *cred, struct shmfd *shmfd,
struct label *shmlabel, mode_t mode)
{
return (0);
}
static int
stub_posixshm_check_setowner(struct ucred *cred, struct shmfd *shmfd,
struct label *shmlabel, uid_t uid, gid_t gid)
{
return (0);
}
static int
stub_posixshm_check_stat(struct ucred *active_cred, struct ucred *file_cred,
struct shmfd *shmfd, struct label *shmlabel)
@ -1731,6 +1763,8 @@ static struct mac_policy_ops stub_ops =
.mpo_posixsem_check_getvalue = stub_posixsem_check_getvalue,
.mpo_posixsem_check_open = stub_posixsem_check_open,
.mpo_posixsem_check_post = stub_posixsem_check_post,
.mpo_posixsem_check_setmode = stub_posixsem_check_setmode,
.mpo_posixsem_check_setowner = stub_posixsem_check_setowner,
.mpo_posixsem_check_stat = stub_posixsem_check_stat,
.mpo_posixsem_check_unlink = stub_posixsem_check_unlink,
.mpo_posixsem_check_wait = stub_posixsem_check_wait,
@ -1740,6 +1774,8 @@ static struct mac_policy_ops stub_ops =
.mpo_posixshm_check_mmap = stub_posixshm_check_mmap,
.mpo_posixshm_check_open = stub_posixshm_check_open,
.mpo_posixshm_check_setmode = stub_posixshm_check_setmode,
.mpo_posixshm_check_setowner = stub_posixshm_check_setowner,
.mpo_posixshm_check_stat = stub_posixshm_check_stat,
.mpo_posixshm_check_truncate = stub_posixshm_check_truncate,
.mpo_posixshm_check_unlink = stub_posixshm_check_unlink,

View File

@ -1297,6 +1297,30 @@ test_posixsem_check_post(struct ucred *active_cred, struct ucred *file_cred,
return (0);
}
COUNTER_DECL(posixsem_check_setmode);
static int
test_posixsem_check_setmode(struct ucred *cred, struct ksem *ks,
struct label *kslabel, mode_t mode)
{
LABEL_CHECK(cred->cr_label, MAGIC_CRED);
LABEL_CHECK(kslabel, MAGIC_POSIX_SHM);
COUNTER_INC(posixsem_check_setmode);
return (0);
}
COUNTER_DECL(posixsem_check_setowner);
static int
test_posixsem_check_setowner(struct ucred *cred, struct ksem *ks,
struct label *kslabel, uid_t uid, gid_t gid)
{
LABEL_CHECK(cred->cr_label, MAGIC_CRED);
LABEL_CHECK(kslabel, MAGIC_POSIX_SHM);
COUNTER_INC(posixsem_check_setowner);
return (0);
}
COUNTER_DECL(posixsem_check_stat);
static int
test_posixsem_check_stat(struct ucred *active_cred,
@ -1390,6 +1414,30 @@ test_posixshm_check_open(struct ucred *cred, struct shmfd *shmfd,
return (0);
}
COUNTER_DECL(posixshm_check_setmode);
static int
test_posixshm_check_setmode(struct ucred *cred, struct shmfd *shmfd,
struct label *shmfdlabel, mode_t mode)
{
LABEL_CHECK(cred->cr_label, MAGIC_CRED);
LABEL_CHECK(shmfdlabel, MAGIC_POSIX_SHM);
COUNTER_INC(posixshm_check_setmode);
return (0);
}
COUNTER_DECL(posixshm_check_setowner);
static int
test_posixshm_check_setowner(struct ucred *cred, struct shmfd *shmfd,
struct label *shmfdlabel, uid_t uid, gid_t gid)
{
LABEL_CHECK(cred->cr_label, MAGIC_CRED);
LABEL_CHECK(shmfdlabel, MAGIC_POSIX_SHM);
COUNTER_INC(posixshm_check_setowner);
return (0);
}
COUNTER_DECL(posixshm_check_stat);
static int
test_posixshm_check_stat(struct ucred *active_cred,
@ -3045,6 +3093,8 @@ static struct mac_policy_ops test_ops =
.mpo_posixsem_check_getvalue = test_posixsem_check_getvalue,
.mpo_posixsem_check_open = test_posixsem_check_open,
.mpo_posixsem_check_post = test_posixsem_check_post,
.mpo_posixsem_check_setmode = test_posixsem_check_setmode,
.mpo_posixsem_check_setowner = test_posixsem_check_setowner,
.mpo_posixsem_check_stat = test_posixsem_check_stat,
.mpo_posixsem_check_unlink = test_posixsem_check_unlink,
.mpo_posixsem_check_wait = test_posixsem_check_wait,
@ -3054,6 +3104,8 @@ static struct mac_policy_ops test_ops =
.mpo_posixshm_check_mmap = test_posixshm_check_mmap,
.mpo_posixshm_check_open = test_posixshm_check_open,
.mpo_posixshm_check_setmode = test_posixshm_check_setmode,
.mpo_posixshm_check_setowner = test_posixshm_check_setowner,
.mpo_posixshm_check_stat = test_posixshm_check_stat,
.mpo_posixshm_check_truncate = test_posixshm_check_truncate,
.mpo_posixshm_check_unlink = test_posixshm_check_unlink,

View File

@ -85,6 +85,10 @@ typedef int fo_kqfilter_t(struct file *fp, struct knote *kn);
typedef int fo_stat_t(struct file *fp, struct stat *sb,
struct ucred *active_cred, struct thread *td);
typedef int fo_close_t(struct file *fp, struct thread *td);
typedef int fo_chmod_t(struct file *fp, mode_t mode,
struct ucred *active_cred, struct thread *td);
typedef int fo_chown_t(struct file *fp, uid_t uid, gid_t gid,
struct ucred *active_cred, struct thread *td);
typedef int fo_flags_t;
struct fileops {
@ -96,6 +100,8 @@ struct fileops {
fo_kqfilter_t *fo_kqfilter;
fo_stat_t *fo_stat;
fo_close_t *fo_close;
fo_chmod_t *fo_chmod;
fo_chown_t *fo_chown;
fo_flags_t fo_flags; /* DFLAG_* below */
};
@ -200,6 +206,9 @@ fo_kqfilter_t soo_kqfilter;
fo_stat_t soo_stat;
fo_close_t soo_close;
fo_chmod_t invfo_chmod;
fo_chown_t invfo_chown;
void finit(struct file *, u_int, short, void *, struct fileops *);
int fgetvp(struct thread *td, int fd, cap_rights_t rights, struct vnode **vpp);
int fgetvp_rights(struct thread *td, int fd, cap_rights_t need,
@ -233,6 +242,8 @@ static __inline fo_poll_t fo_poll;
static __inline fo_kqfilter_t fo_kqfilter;
static __inline fo_stat_t fo_stat;
static __inline fo_close_t fo_close;
static __inline fo_chmod_t fo_chmod;
static __inline fo_chown_t fo_chown;
static __inline int
fo_read(struct file *fp, struct uio *uio, struct ucred *active_cred,
@ -296,6 +307,22 @@ fo_kqfilter(struct file *fp, struct knote *kn)
return ((*fp->f_ops->fo_kqfilter)(fp, kn));
}
static __inline int
fo_chmod(struct file *fp, mode_t mode, struct ucred *active_cred,
struct thread *td)
{
return ((*fp->f_ops->fo_chmod)(fp, mode, active_cred, td));
}
static __inline int
fo_chown(struct file *fp, uid_t uid, gid_t gid, struct ucred *active_cred,
struct thread *td)
{
return ((*fp->f_ops->fo_chown)(fp, uid, gid, active_cred, td));
}
#endif /* _KERNEL */
#endif /* !SYS_FILE_H */

View File

@ -778,7 +778,15 @@ void vfs_mark_atime(struct vnode *vp, struct ucred *cred);
struct dirent;
int vfs_read_dirent(struct vop_readdir_args *ap, struct dirent *dp, off_t off);
int vfs_unixify_accmode(accmode_t *accmode);
int vfs_unixify_accmode(accmode_t *accmode);
int setfmode(struct thread *td, struct ucred *cred, struct vnode *vp, int mode);
int setfown(struct thread *td, struct ucred *cred, struct vnode *vp, uid_t uid,
gid_t gid);
int vn_chmod(struct file *fp, mode_t mode, struct ucred *active_cred,
struct thread *td);
int vn_chown(struct file *fp, uid_t uid, gid_t gid, struct ucred *active_cred,
struct thread *td);
#endif /* _KERNEL */