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