mirror of
https://github.com/freebsd/freebsd-src
synced 2024-07-03 08:49:22 +00:00
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
This commit is contained in:
parent
04d3f8e539
commit
ddbfb544c6
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in New Issue
Block a user