uipc_mqueue.c (b307cfe419ff886ad1bbe15419c5f5604657df7b) uipc_mqueue.c (63f18b37e01ef214de762a091d3c98ae5028c8f4)
1/*-
2 * SPDX-License-Identifier: BSD-2-Clause
3 *
4 * Copyright (c) 2005 David Xu <davidxu@freebsd.org>
5 * Copyright (c) 2016-2017 Robert N. M. Watson
6 * All rights reserved.
7 *
8 * Portions of this software were developed by BAE Systems, the University of

--- 36 unchanged lines hidden (view full) ---

45 * different attributes. Also the file system can be mounted multiple
46 * times at different mount points but shows same contents.
47 *
48 * 2) Standard POSIX message queue API. The syscalls do not use vfs layer,
49 * but directly operate on internal data structure, this allows user to
50 * use the IPC facility without having to mount mqueue file system.
51 */
52
1/*-
2 * SPDX-License-Identifier: BSD-2-Clause
3 *
4 * Copyright (c) 2005 David Xu <davidxu@freebsd.org>
5 * Copyright (c) 2016-2017 Robert N. M. Watson
6 * All rights reserved.
7 *
8 * Portions of this software were developed by BAE Systems, the University of

--- 36 unchanged lines hidden (view full) ---

45 * different attributes. Also the file system can be mounted multiple
46 * times at different mount points but shows same contents.
47 *
48 * 2) Standard POSIX message queue API. The syscalls do not use vfs layer,
49 * but directly operate on internal data structure, this allows user to
50 * use the IPC facility without having to mount mqueue file system.
51 */
52
53#include <sys/cdefs.h>
54#include "opt_capsicum.h"
55
56#include <sys/param.h>
57#include <sys/kernel.h>
58#include <sys/systm.h>
59#include <sys/limits.h>
60#include <sys/malloc.h>
61#include <sys/buf.h>

--- 312 unchanged lines hidden (view full) ---

374 mn->mn_type));
375 break;
376 }
377}
378
379static __inline struct mqfs_node *
380mqnode_alloc(void)
381{
53#include "opt_capsicum.h"
54
55#include <sys/param.h>
56#include <sys/kernel.h>
57#include <sys/systm.h>
58#include <sys/limits.h>
59#include <sys/malloc.h>
60#include <sys/buf.h>

--- 312 unchanged lines hidden (view full) ---

373 mn->mn_type));
374 break;
375 }
376}
377
378static __inline struct mqfs_node *
379mqnode_alloc(void)
380{
382 return uma_zalloc(mqnode_zone, M_WAITOK | M_ZERO);
381 return (uma_zalloc(mqnode_zone, M_WAITOK | M_ZERO));
383}
384
385static __inline void
386mqnode_free(struct mqfs_node *node)
387{
388 uma_zfree(mqnode_zone, node);
389}
390

--- 55 unchanged lines hidden (view full) ---

446 struct mqfs_node *node;
447
448 node = mqnode_alloc();
449 strncpy(node->mn_name, name, namelen);
450 node->mn_pr_root = cred->cr_prison->pr_root;
451 node->mn_type = nodetype;
452 node->mn_refcount = 1;
453 vfs_timestamp(&node->mn_birth);
382}
383
384static __inline void
385mqnode_free(struct mqfs_node *node)
386{
387 uma_zfree(mqnode_zone, node);
388}
389

--- 55 unchanged lines hidden (view full) ---

445 struct mqfs_node *node;
446
447 node = mqnode_alloc();
448 strncpy(node->mn_name, name, namelen);
449 node->mn_pr_root = cred->cr_prison->pr_root;
450 node->mn_type = nodetype;
451 node->mn_refcount = 1;
452 vfs_timestamp(&node->mn_birth);
454 node->mn_ctime = node->mn_atime = node->mn_mtime
455 = node->mn_birth;
453 node->mn_ctime = node->mn_atime = node->mn_mtime =
454 node->mn_birth;
456 node->mn_uid = cred->cr_uid;
457 node->mn_gid = cred->cr_gid;
458 node->mn_mode = mode;
459 return (node);
460}
461
462/*
463 * Create a file

--- 548 unchanged lines hidden (view full) ---

1012 if (error)
1013 mqueue_free(mq);
1014 return (error);
1015}
1016
1017/*
1018 * Remove an entry
1019 */
455 node->mn_uid = cred->cr_uid;
456 node->mn_gid = cred->cr_gid;
457 node->mn_mode = mode;
458 return (node);
459}
460
461/*
462 * Create a file

--- 548 unchanged lines hidden (view full) ---

1011 if (error)
1012 mqueue_free(mq);
1013 return (error);
1014}
1015
1016/*
1017 * Remove an entry
1018 */
1020static
1021int do_unlink(struct mqfs_node *pn, struct ucred *ucred)
1019static int
1020do_unlink(struct mqfs_node *pn, struct ucred *ucred)
1022{
1023 struct mqfs_node *parent;
1024 struct mqfs_vdata *vd;
1025 int error = 0;
1026
1027 sx_assert(&pn->mn_info->mi_lock, SX_LOCKED);
1028
1029 if (ucred->cr_uid != pn->mn_uid &&

--- 209 unchanged lines hidden (view full) ---

1239 struct thread *td;
1240 int c, error;
1241 uid_t uid;
1242 gid_t gid;
1243
1244 td = curthread;
1245 vap = ap->a_vap;
1246 vp = ap->a_vp;
1021{
1022 struct mqfs_node *parent;
1023 struct mqfs_vdata *vd;
1024 int error = 0;
1025
1026 sx_assert(&pn->mn_info->mi_lock, SX_LOCKED);
1027
1028 if (ucred->cr_uid != pn->mn_uid &&

--- 209 unchanged lines hidden (view full) ---

1238 struct thread *td;
1239 int c, error;
1240 uid_t uid;
1241 gid_t gid;
1242
1243 td = curthread;
1244 vap = ap->a_vap;
1245 vp = ap->a_vp;
1247 if ((vap->va_type != VNON) ||
1248 (vap->va_nlink != VNOVAL) ||
1249 (vap->va_fsid != VNOVAL) ||
1250 (vap->va_fileid != VNOVAL) ||
1251 (vap->va_blocksize != VNOVAL) ||
1246 if (vap->va_type != VNON ||
1247 vap->va_nlink != VNOVAL ||
1248 vap->va_fsid != VNOVAL ||
1249 vap->va_fileid != VNOVAL ||
1250 vap->va_blocksize != VNOVAL ||
1252 (vap->va_flags != VNOVAL && vap->va_flags != 0) ||
1251 (vap->va_flags != VNOVAL && vap->va_flags != 0) ||
1253 (vap->va_rdev != VNOVAL) ||
1254 ((int)vap->va_bytes != VNOVAL) ||
1255 (vap->va_gen != VNOVAL)) {
1252 vap->va_rdev != VNOVAL ||
1253 (int)vap->va_bytes != VNOVAL ||
1254 vap->va_gen != VNOVAL) {
1256 return (EINVAL);
1257 }
1258
1259 pn = VTON(vp);
1260
1261 error = c = 0;
1262 if (vap->va_uid == (uid_t)VNOVAL)
1263 uid = pn->mn_uid;

--- 12 unchanged lines hidden (view full) ---

1276 if ((error = VOP_ACCESS(vp, VADMIN, ap->a_cred, td)))
1277 return (error);
1278
1279 /*
1280 * XXXRW: Why is there a privilege check here: shouldn't the
1281 * check in VOP_ACCESS() be enough? Also, are the group bits
1282 * below definitely right?
1283 */
1255 return (EINVAL);
1256 }
1257
1258 pn = VTON(vp);
1259
1260 error = c = 0;
1261 if (vap->va_uid == (uid_t)VNOVAL)
1262 uid = pn->mn_uid;

--- 12 unchanged lines hidden (view full) ---

1275 if ((error = VOP_ACCESS(vp, VADMIN, ap->a_cred, td)))
1276 return (error);
1277
1278 /*
1279 * XXXRW: Why is there a privilege check here: shouldn't the
1280 * check in VOP_ACCESS() be enough? Also, are the group bits
1281 * below definitely right?
1282 */
1284 if (((ap->a_cred->cr_uid != pn->mn_uid) || uid != pn->mn_uid ||
1283 if ((ap->a_cred->cr_uid != pn->mn_uid || uid != pn->mn_uid ||
1285 (gid != pn->mn_gid && !groupmember(gid, ap->a_cred))) &&
1286 (error = priv_check(td, PRIV_MQ_ADMIN)) != 0)
1287 return (error);
1288 pn->mn_uid = uid;
1289 pn->mn_gid = gid;
1290 c = 1;
1291 }
1292
1293 if (vap->va_mode != (mode_t)VNOVAL) {
1284 (gid != pn->mn_gid && !groupmember(gid, ap->a_cred))) &&
1285 (error = priv_check(td, PRIV_MQ_ADMIN)) != 0)
1286 return (error);
1287 pn->mn_uid = uid;
1288 pn->mn_gid = gid;
1289 c = 1;
1290 }
1291
1292 if (vap->va_mode != (mode_t)VNOVAL) {
1294 if ((ap->a_cred->cr_uid != pn->mn_uid) &&
1293 if (ap->a_cred->cr_uid != pn->mn_uid &&
1295 (error = priv_check(td, PRIV_MQ_ADMIN)))
1296 return (error);
1297 pn->mn_mode = vap->va_mode;
1298 c = 1;
1299 }
1300
1301 if (vap->va_atime.tv_sec != VNOVAL || vap->va_mtime.tv_sec != VNOVAL) {
1302 /* See the comment in ufs_vnops::ufs_setattr(). */

--- 37 unchanged lines hidden (view full) ---

1340 struct mqueue *mq;
1341 int len, error;
1342
1343 if (vp->v_type != VREG)
1344 return (EINVAL);
1345
1346 mq = VTOMQ(vp);
1347 snprintf(buf, sizeof(buf),
1294 (error = priv_check(td, PRIV_MQ_ADMIN)))
1295 return (error);
1296 pn->mn_mode = vap->va_mode;
1297 c = 1;
1298 }
1299
1300 if (vap->va_atime.tv_sec != VNOVAL || vap->va_mtime.tv_sec != VNOVAL) {
1301 /* See the comment in ufs_vnops::ufs_setattr(). */

--- 37 unchanged lines hidden (view full) ---

1339 struct mqueue *mq;
1340 int len, error;
1341
1342 if (vp->v_type != VREG)
1343 return (EINVAL);
1344
1345 mq = VTOMQ(vp);
1346 snprintf(buf, sizeof(buf),
1348 "QSIZE:%-10ld MAXMSG:%-10ld CURMSG:%-10ld MSGSIZE:%-10ld\n",
1349 mq->mq_totalbytes,
1350 mq->mq_maxmsg,
1351 mq->mq_curmsgs,
1352 mq->mq_msgsize);
1347 "QSIZE:%-10ld MAXMSG:%-10ld CURMSG:%-10ld MSGSIZE:%-10ld\n",
1348 mq->mq_totalbytes,
1349 mq->mq_maxmsg,
1350 mq->mq_curmsgs,
1351 mq->mq_msgsize);
1353 buf[sizeof(buf)-1] = '\0';
1354 len = strlen(buf);
1355 error = uiomove_frombuf(buf, len, uio);
1356 return (error);
1357}
1358
1359#if 0
1360struct vop_readdir_args {

--- 648 unchanged lines hidden (view full) ---

2009 struct file *fp;
2010 struct mqueue *mq;
2011 int fd, error, len, cmode;
2012
2013 AUDIT_ARG_FFLAGS(flags);
2014 AUDIT_ARG_MODE(mode);
2015
2016 pdp = td->td_proc->p_pd;
1352 buf[sizeof(buf)-1] = '\0';
1353 len = strlen(buf);
1354 error = uiomove_frombuf(buf, len, uio);
1355 return (error);
1356}
1357
1358#if 0
1359struct vop_readdir_args {

--- 648 unchanged lines hidden (view full) ---

2008 struct file *fp;
2009 struct mqueue *mq;
2010 int fd, error, len, cmode;
2011
2012 AUDIT_ARG_FFLAGS(flags);
2013 AUDIT_ARG_MODE(mode);
2014
2015 pdp = td->td_proc->p_pd;
2017 cmode = (((mode & ~pdp->pd_cmask) & ALLPERMS) & ~S_ISTXT);
2016 cmode = ((mode & ~pdp->pd_cmask) & ALLPERMS) & ~S_ISTXT;
2018 mq = NULL;
2019 if ((flags & O_CREAT) != 0 && attr != NULL) {
2020 if (attr->mq_maxmsg <= 0 || attr->mq_maxmsg > maxmsg)
2021 return (EINVAL);
2022 if (attr->mq_msgsize <= 0 || attr->mq_msgsize > maxmsgsize)
2023 return (EINVAL);
2024 }
2025

--- 778 unchanged lines hidden (view full) ---

2804 goto out;
2805 CP(ets32, ets, tv_sec);
2806 CP(ets32, ets, tv_nsec);
2807 abs_timeout = &ets;
2808 } else
2809 abs_timeout = NULL;
2810 waitok = !(fp->f_flag & O_NONBLOCK);
2811 error = mqueue_send(mq, uap->msg_ptr, uap->msg_len,
2017 mq = NULL;
2018 if ((flags & O_CREAT) != 0 && attr != NULL) {
2019 if (attr->mq_maxmsg <= 0 || attr->mq_maxmsg > maxmsg)
2020 return (EINVAL);
2021 if (attr->mq_msgsize <= 0 || attr->mq_msgsize > maxmsgsize)
2022 return (EINVAL);
2023 }
2024

--- 778 unchanged lines hidden (view full) ---

2803 goto out;
2804 CP(ets32, ets, tv_sec);
2805 CP(ets32, ets, tv_nsec);
2806 abs_timeout = &ets;
2807 } else
2808 abs_timeout = NULL;
2809 waitok = !(fp->f_flag & O_NONBLOCK);
2810 error = mqueue_send(mq, uap->msg_ptr, uap->msg_len,
2812 uap->msg_prio, waitok, abs_timeout);
2811 uap->msg_prio, waitok, abs_timeout);
2813out:
2814 fdrop(fp, td);
2815 return (error);
2816}
2817
2818int
2819freebsd32_kmq_timedreceive(struct thread *td,
2820 struct freebsd32_kmq_timedreceive_args *uap)

--- 14 unchanged lines hidden (view full) ---

2835 goto out;
2836 CP(ets32, ets, tv_sec);
2837 CP(ets32, ets, tv_nsec);
2838 abs_timeout = &ets;
2839 } else
2840 abs_timeout = NULL;
2841 waitok = !(fp->f_flag & O_NONBLOCK);
2842 error = mqueue_receive(mq, uap->msg_ptr, uap->msg_len,
2812out:
2813 fdrop(fp, td);
2814 return (error);
2815}
2816
2817int
2818freebsd32_kmq_timedreceive(struct thread *td,
2819 struct freebsd32_kmq_timedreceive_args *uap)

--- 14 unchanged lines hidden (view full) ---

2834 goto out;
2835 CP(ets32, ets, tv_sec);
2836 CP(ets32, ets, tv_nsec);
2837 abs_timeout = &ets;
2838 } else
2839 abs_timeout = NULL;
2840 waitok = !(fp->f_flag & O_NONBLOCK);
2841 error = mqueue_receive(mq, uap->msg_ptr, uap->msg_len,
2843 uap->msg_prio, waitok, abs_timeout);
2842 uap->msg_prio, waitok, abs_timeout);
2844out:
2845 fdrop(fp, td);
2846 return (error);
2847}
2848
2849int
2850freebsd32_kmq_notify(struct thread *td, struct freebsd32_kmq_notify_args *uap)
2851{

--- 87 unchanged lines hidden ---
2843out:
2844 fdrop(fp, td);
2845 return (error);
2846}
2847
2848int
2849freebsd32_kmq_notify(struct thread *td, struct freebsd32_kmq_notify_args *uap)
2850{

--- 87 unchanged lines hidden ---