git: ddbfb544c6c9 - main - mqueuefs: Relax restriction that path must begin with a slash
- Go to: [ bottom of page ] [ top of archives ] [ this month ]
Date: Thu, 23 May 2024 19:42:08 UTC
The branch main has been updated by imp:
URL: https://cgit.FreeBSD.org/src/commit/?id=ddbfb544c6c9726ae97bcaf105d11dec8b292877
commit ddbfb544c6c9726ae97bcaf105d11dec8b292877
Author: Ricardo Branco <rbranco@suse.de>
AuthorDate: 2024-05-15 20:56:15 +0000
Commit: Warner Losh <imp@FreeBSD.org>
CommitDate: 2024-05-23 19:40:46 +0000
mqueuefs: Relax restriction that path must begin with a slash
This is needed to support Linux implementation which discards the leading slash when calling mq_open(2)
Reviewed by: imp, kib
Pull Request: https://github.com/freebsd/freebsd-src/pull/1248
---
lib/libsys/mq_open.2 | 4 ++--
sys/kern/uipc_mqueue.c | 34 ++++++++++++++++++++++------------
2 files changed, 24 insertions(+), 14 deletions(-)
diff --git a/lib/libsys/mq_open.2 b/lib/libsys/mq_open.2
index 484fe95432da..4800ab18de59 100644
--- a/lib/libsys/mq_open.2
+++ b/lib/libsys/mq_open.2
@@ -35,7 +35,7 @@
.\" the referee document. The original Standard can be obtained online at
.\" http://www.opengroup.org/unix/online.html.
.\"
-.Dd September 26, 2023
+.Dd May 15, 2024
.Dt MQ_OPEN 2
.Os
.Sh NAME
@@ -322,7 +322,7 @@ Support for POSIX message queues first appeared in
.Sh BUGS
This implementation places strict requirements on the value of
.Fa name :
-it must begin with a slash
+it may begin with a slash
.Pq Ql /
and contain no other slash characters.
.Pp
diff --git a/sys/kern/uipc_mqueue.c b/sys/kern/uipc_mqueue.c
index 2efdfc9dd04c..9276c918565f 100644
--- a/sys/kern/uipc_mqueue.c
+++ b/sys/kern/uipc_mqueue.c
@@ -2007,7 +2007,7 @@ static int
kern_kmq_open(struct thread *td, const char *upath, int flags, mode_t mode,
const struct mq_attr *attr)
{
- char path[MQFS_NAMELEN + 1];
+ char *path, pathbuf[MQFS_NAMELEN + 1];
struct mqfs_node *pn;
struct pwddesc *pdp;
struct file *fp;
@@ -2027,32 +2027,37 @@ kern_kmq_open(struct thread *td, const char *upath, int flags, mode_t mode,
return (EINVAL);
}
+ path = pathbuf;
error = copyinstr(upath, path, MQFS_NAMELEN + 1, NULL);
if (error)
return (error);
/*
- * The first character of name must be a slash (/) character
+ * The first character of name may be a slash (/) character
* and the remaining characters of name cannot include any slash
* characters.
*/
len = strlen(path);
- if (len < 2 || path[0] != '/' || strchr(path + 1, '/') != NULL)
+ if (len < 2 || strchr(path + 1, '/') != NULL)
return (EINVAL);
+ if (path[0] == '/') {
+ path++;
+ len--;
+ }
/*
* "." and ".." are magic directories, populated on the fly, and cannot
* be opened as queues.
*/
- if (strcmp(path, "/.") == 0 || strcmp(path, "/..") == 0)
+ if (strcmp(path, ".") == 0 || strcmp(path, "..") == 0)
return (EINVAL);
- AUDIT_ARG_UPATH1_CANON(path);
+ AUDIT_ARG_UPATH1_CANON(pathbuf);
error = falloc(td, &fp, &fd, O_CLOEXEC);
if (error)
return (error);
sx_xlock(&mqfs_data.mi_lock);
- pn = mqfs_search(mqfs_data.mi_root, path + 1, len - 1, td->td_ucred);
+ pn = mqfs_search(mqfs_data.mi_root, path, len, td->td_ucred);
if (pn == NULL) {
if (!(flags & O_CREAT)) {
error = ENOENT;
@@ -2062,7 +2067,7 @@ kern_kmq_open(struct thread *td, const char *upath, int flags, mode_t mode,
error = ENFILE;
} else {
pn = mqfs_create_file(mqfs_data.mi_root,
- path + 1, len - 1, td->td_ucred,
+ path, len, td->td_ucred,
cmode);
if (pn == NULL) {
error = ENOSPC;
@@ -2134,23 +2139,28 @@ sys_kmq_open(struct thread *td, struct kmq_open_args *uap)
int
sys_kmq_unlink(struct thread *td, struct kmq_unlink_args *uap)
{
- char path[MQFS_NAMELEN+1];
+ char *path, pathbuf[MQFS_NAMELEN + 1];
struct mqfs_node *pn;
int error, len;
+ path = pathbuf;
error = copyinstr(uap->path, path, MQFS_NAMELEN + 1, NULL);
if (error)
return (error);
len = strlen(path);
- if (len < 2 || path[0] != '/' || strchr(path + 1, '/') != NULL)
+ if (len < 2 || strchr(path + 1, '/') != NULL)
return (EINVAL);
- if (strcmp(path, "/.") == 0 || strcmp(path, "/..") == 0)
+ if (path[0] == '/') {
+ path++;
+ len--;
+ }
+ if (strcmp(path, ".") == 0 || strcmp(path, "..") == 0)
return (EINVAL);
- AUDIT_ARG_UPATH1_CANON(path);
+ AUDIT_ARG_UPATH1_CANON(pathbuf);
sx_xlock(&mqfs_data.mi_lock);
- pn = mqfs_search(mqfs_data.mi_root, path + 1, len - 1, td->td_ucred);
+ pn = mqfs_search(mqfs_data.mi_root, path, len, td->td_ucred);
if (pn != NULL)
error = do_unlink(pn, td->td_ucred);
else