uipc_mqueue.c (acb7a4deb21a4cdfbb9bbf703b42a377450b9fdd) uipc_mqueue.c (ddbfb544c6c9726ae97bcaf105d11dec8b292877)
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

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

2002 }
2003 PROC_UNLOCK(p);
2004}
2005
2006static int
2007kern_kmq_open(struct thread *td, const char *upath, int flags, mode_t mode,
2008 const struct mq_attr *attr)
2009{
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

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

2002 }
2003 PROC_UNLOCK(p);
2004}
2005
2006static int
2007kern_kmq_open(struct thread *td, const char *upath, int flags, mode_t mode,
2008 const struct mq_attr *attr)
2009{
2010 char path[MQFS_NAMELEN + 1];
2010 char *path, pathbuf[MQFS_NAMELEN + 1];
2011 struct mqfs_node *pn;
2012 struct pwddesc *pdp;
2013 struct file *fp;
2014 struct mqueue *mq;
2015 int fd, error, len, cmode;
2016
2017 AUDIT_ARG_FFLAGS(flags);
2018 AUDIT_ARG_MODE(mode);
2019
2020 pdp = td->td_proc->p_pd;
2021 cmode = ((mode & ~pdp->pd_cmask) & ALLPERMS) & ~S_ISTXT;
2022 mq = NULL;
2023 if ((flags & O_CREAT) != 0 && attr != NULL) {
2024 if (attr->mq_maxmsg <= 0 || attr->mq_maxmsg > maxmsg)
2025 return (EINVAL);
2026 if (attr->mq_msgsize <= 0 || attr->mq_msgsize > maxmsgsize)
2027 return (EINVAL);
2028 }
2029
2011 struct mqfs_node *pn;
2012 struct pwddesc *pdp;
2013 struct file *fp;
2014 struct mqueue *mq;
2015 int fd, error, len, cmode;
2016
2017 AUDIT_ARG_FFLAGS(flags);
2018 AUDIT_ARG_MODE(mode);
2019
2020 pdp = td->td_proc->p_pd;
2021 cmode = ((mode & ~pdp->pd_cmask) & ALLPERMS) & ~S_ISTXT;
2022 mq = NULL;
2023 if ((flags & O_CREAT) != 0 && attr != NULL) {
2024 if (attr->mq_maxmsg <= 0 || attr->mq_maxmsg > maxmsg)
2025 return (EINVAL);
2026 if (attr->mq_msgsize <= 0 || attr->mq_msgsize > maxmsgsize)
2027 return (EINVAL);
2028 }
2029
2030 path = pathbuf;
2030 error = copyinstr(upath, path, MQFS_NAMELEN + 1, NULL);
2031 if (error)
2032 return (error);
2033
2034 /*
2031 error = copyinstr(upath, path, MQFS_NAMELEN + 1, NULL);
2032 if (error)
2033 return (error);
2034
2035 /*
2035 * The first character of name must be a slash (/) character
2036 * The first character of name may be a slash (/) character
2036 * and the remaining characters of name cannot include any slash
2037 * characters.
2038 */
2039 len = strlen(path);
2037 * and the remaining characters of name cannot include any slash
2038 * characters.
2039 */
2040 len = strlen(path);
2040 if (len < 2 || path[0] != '/' || strchr(path + 1, '/') != NULL)
2041 if (len < 2 || strchr(path + 1, '/') != NULL)
2041 return (EINVAL);
2042 return (EINVAL);
2043 if (path[0] == '/') {
2044 path++;
2045 len--;
2046 }
2042 /*
2043 * "." and ".." are magic directories, populated on the fly, and cannot
2044 * be opened as queues.
2045 */
2047 /*
2048 * "." and ".." are magic directories, populated on the fly, and cannot
2049 * be opened as queues.
2050 */
2046 if (strcmp(path, "/.") == 0 || strcmp(path, "/..") == 0)
2051 if (strcmp(path, ".") == 0 || strcmp(path, "..") == 0)
2047 return (EINVAL);
2052 return (EINVAL);
2048 AUDIT_ARG_UPATH1_CANON(path);
2053 AUDIT_ARG_UPATH1_CANON(pathbuf);
2049
2050 error = falloc(td, &fp, &fd, O_CLOEXEC);
2051 if (error)
2052 return (error);
2053
2054 sx_xlock(&mqfs_data.mi_lock);
2054
2055 error = falloc(td, &fp, &fd, O_CLOEXEC);
2056 if (error)
2057 return (error);
2058
2059 sx_xlock(&mqfs_data.mi_lock);
2055 pn = mqfs_search(mqfs_data.mi_root, path + 1, len - 1, td->td_ucred);
2060 pn = mqfs_search(mqfs_data.mi_root, path, len, td->td_ucred);
2056 if (pn == NULL) {
2057 if (!(flags & O_CREAT)) {
2058 error = ENOENT;
2059 } else {
2060 mq = mqueue_alloc(attr);
2061 if (mq == NULL) {
2062 error = ENFILE;
2063 } else {
2064 pn = mqfs_create_file(mqfs_data.mi_root,
2061 if (pn == NULL) {
2062 if (!(flags & O_CREAT)) {
2063 error = ENOENT;
2064 } else {
2065 mq = mqueue_alloc(attr);
2066 if (mq == NULL) {
2067 error = ENFILE;
2068 } else {
2069 pn = mqfs_create_file(mqfs_data.mi_root,
2065 path + 1, len - 1, td->td_ucred,
2070 path, len, td->td_ucred,
2066 cmode);
2067 if (pn == NULL) {
2068 error = ENOSPC;
2069 mqueue_free(mq);
2070 }
2071 }
2072 }
2073

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

2129}
2130
2131/*
2132 * Syscall to unlink a message queue.
2133 */
2134int
2135sys_kmq_unlink(struct thread *td, struct kmq_unlink_args *uap)
2136{
2071 cmode);
2072 if (pn == NULL) {
2073 error = ENOSPC;
2074 mqueue_free(mq);
2075 }
2076 }
2077 }
2078

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

2134}
2135
2136/*
2137 * Syscall to unlink a message queue.
2138 */
2139int
2140sys_kmq_unlink(struct thread *td, struct kmq_unlink_args *uap)
2141{
2137 char path[MQFS_NAMELEN+1];
2142 char *path, pathbuf[MQFS_NAMELEN + 1];
2138 struct mqfs_node *pn;
2139 int error, len;
2140
2143 struct mqfs_node *pn;
2144 int error, len;
2145
2146 path = pathbuf;
2141 error = copyinstr(uap->path, path, MQFS_NAMELEN + 1, NULL);
2142 if (error)
2143 return (error);
2144
2145 len = strlen(path);
2147 error = copyinstr(uap->path, path, MQFS_NAMELEN + 1, NULL);
2148 if (error)
2149 return (error);
2150
2151 len = strlen(path);
2146 if (len < 2 || path[0] != '/' || strchr(path + 1, '/') != NULL)
2152 if (len < 2 || strchr(path + 1, '/') != NULL)
2147 return (EINVAL);
2153 return (EINVAL);
2148 if (strcmp(path, "/.") == 0 || strcmp(path, "/..") == 0)
2154 if (path[0] == '/') {
2155 path++;
2156 len--;
2157 }
2158 if (strcmp(path, ".") == 0 || strcmp(path, "..") == 0)
2149 return (EINVAL);
2159 return (EINVAL);
2150 AUDIT_ARG_UPATH1_CANON(path);
2160 AUDIT_ARG_UPATH1_CANON(pathbuf);
2151
2152 sx_xlock(&mqfs_data.mi_lock);
2161
2162 sx_xlock(&mqfs_data.mi_lock);
2153 pn = mqfs_search(mqfs_data.mi_root, path + 1, len - 1, td->td_ucred);
2163 pn = mqfs_search(mqfs_data.mi_root, path, len, td->td_ucred);
2154 if (pn != NULL)
2155 error = do_unlink(pn, td->td_ucred);
2156 else
2157 error = ENOENT;
2158 sx_xunlock(&mqfs_data.mi_lock);
2159 return (error);
2160}
2161

--- 781 unchanged lines hidden ---
2164 if (pn != NULL)
2165 error = do_unlink(pn, td->td_ucred);
2166 else
2167 error = ENOENT;
2168 sx_xunlock(&mqfs_data.mi_lock);
2169 return (error);
2170}
2171

--- 781 unchanged lines hidden ---