Cygwin: path_conv: fix mqueue path check

The check for a file or dir within /dev/mqueue is accidentally using
the incoming path, which could be a relative path.  Make sure to
restore the absolute POSIX path in path_copy and only then test the
path.

Also, move the actual check for a valid path below /dev/mqueue into
the fhandler_mqueue class.

Signed-off-by: Corinna Vinschen <corinna@vinschen.de>
This commit is contained in:
Corinna Vinschen 2021-05-25 22:03:36 +02:00
parent 4c09dc4f9c
commit 782b338530
4 changed files with 27 additions and 15 deletions

View File

@ -3111,6 +3111,8 @@ class fhandler_mqueue: public fhandler_disk_file
off_t filesize; off_t filesize;
off_t position; off_t position;
bool valid_path ();
struct mq_info *_mqinfo (SIZE_T, mode_t, int, bool); struct mq_info *_mqinfo (SIZE_T, mode_t, int, bool);
struct mq_info *mqinfo_create (struct mq_attr *, mode_t, int); struct mq_info *mqinfo_create (struct mq_attr *, mode_t, int);

View File

@ -34,9 +34,24 @@ fhandler_mqueue::~fhandler_mqueue ()
cfree (filebuf); cfree (filebuf);
} }
bool
fhandler_mqueue::valid_path ()
{
const char *posix_basename = get_name () + MQ_LEN;
size_t len = strlen (posix_basename);
if (len > 0 && len <= NAME_MAX && !strpbrk (posix_basename, "/\\"))
return true;
return false;
}
int int
fhandler_mqueue::open (int flags, mode_t mode) fhandler_mqueue::open (int flags, mode_t mode)
{ {
if (!valid_path ())
{
set_errno (EINVAL);
return 0;
}
/* FIXME: reopen by handle semantics missing yet */ /* FIXME: reopen by handle semantics missing yet */
flags &= ~(O_NOCTTY | O_PATH | O_BINARY | O_TEXT); flags &= ~(O_NOCTTY | O_PATH | O_BINARY | O_TEXT);
return mq_open (flags, mode, NULL); return mq_open (flags, mode, NULL);

View File

@ -10,6 +10,9 @@ details. */
#define MQI_MAGIC 0x98765432UL #define MQI_MAGIC 0x98765432UL
#define MQ_PATH "/dev/mqueue/"
#define MQ_LEN (sizeof (MQ_PATH) - 1)
/* The mq_attr structure is defined using long datatypes per POSIX. /* The mq_attr structure is defined using long datatypes per POSIX.
The mq_fattr is the in-file representation of the mq_attr struct. The mq_fattr is the in-file representation of the mq_attr struct.
Originally created this way for 32/64 bit interoperability, this Originally created this way for 32/64 bit interoperability, this

View File

@ -1188,6 +1188,10 @@ path_conv::check (const char *src, unsigned opt,
return; return;
} }
/* Restore last path component */
if (tail < path_end && tail > path_copy + 1)
*tail = '/';
if (dev.isfs ()) if (dev.isfs ())
{ {
/* If FS hasn't been checked already in symlink_info::check, /* If FS hasn't been checked already in symlink_info::check,
@ -1227,17 +1231,9 @@ path_conv::check (const char *src, unsigned opt,
set_exec (0); set_exec (0);
/* FIXME: bad hack alert!!! We need a better solution */ /* FIXME: bad hack alert!!! We need a better solution */
if (!strncmp (path_copy, MQ_PATH, MQ_LEN) && path_copy[MQ_LEN])
#define MQ_PATH "/dev/mqueue/"
#define MQ_LEN (sizeof (MQ_PATH) - 1)
if (!strncmp (src, MQ_PATH, MQ_LEN))
{
size_t len = strlen (src + MQ_LEN);
if (len > 0 && len <= NAME_MAX && !strpbrk (src + MQ_LEN, "/\\"))
dev.parse (FH_MQUEUE); dev.parse (FH_MQUEUE);
} }
}
if (opt & PC_NOFULL) if (opt & PC_NOFULL)
{ {
@ -1270,11 +1266,7 @@ path_conv::check (const char *src, unsigned opt,
path_flags |= PATH_CTTY; path_flags |= PATH_CTTY;
if (opt & PC_POSIX) if (opt & PC_POSIX)
{
if (tail < path_end && tail > path_copy + 1)
*tail = '/';
set_posix (path_copy); set_posix (path_copy);
}
#if 0 #if 0
if (!error) if (!error)