Cygwin: fix regression in O_TMPFILE | O_EXCL case
The new proc fd code accidentally allowed to linkat an O_TMPFILE even if the file has been opened with O_EXCL. This patch fixes it. Signed-off-by: Corinna Vinschen <corinna@vinschen.de>
This commit is contained in:
parent
8a17b1b2bf
commit
9dae73edb8
@ -2578,7 +2578,7 @@ class fhandler_process: public fhandler_proc
|
|||||||
|
|
||||||
class fhandler_process_fd : public fhandler_process
|
class fhandler_process_fd : public fhandler_process
|
||||||
{
|
{
|
||||||
fhandler_base *fetch_fh (HANDLE &);
|
fhandler_base *fetch_fh (HANDLE &, uint32_t);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
fhandler_process_fd () : fhandler_process () {}
|
fhandler_process_fd () : fhandler_process () {}
|
||||||
|
@ -29,7 +29,7 @@ details. */
|
|||||||
|
|
||||||
|
|
||||||
fhandler_base *
|
fhandler_base *
|
||||||
fhandler_process_fd::fetch_fh (HANDLE &out_hdl)
|
fhandler_process_fd::fetch_fh (HANDLE &out_hdl, uint32_t flags)
|
||||||
{
|
{
|
||||||
const char *path;
|
const char *path;
|
||||||
char *e;
|
char *e;
|
||||||
@ -49,6 +49,12 @@ fhandler_process_fd::fetch_fh (HANDLE &out_hdl)
|
|||||||
cygheap_fdget cfd (fd, true);
|
cygheap_fdget cfd (fd, true);
|
||||||
if (cfd < 0)
|
if (cfd < 0)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
if ((flags & FFH_LINKAT)
|
||||||
|
&& (cfd->get_flags () & (O_TMPFILE | O_EXCL)) == (O_TMPFILE | O_EXCL))
|
||||||
|
{
|
||||||
|
set_errno (ENOENT);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
proc = GetCurrentProcess ();
|
proc = GetCurrentProcess ();
|
||||||
pc << cfd->pc;
|
pc << cfd->pc;
|
||||||
hdl = cfd->get_handle ();
|
hdl = cfd->get_handle ();
|
||||||
@ -68,10 +74,10 @@ fhandler_process_fd::fetch_fh (HANDLE &out_hdl)
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
size_t size;
|
size_t size;
|
||||||
void *buf = p->file_pathconv (fd, size);
|
void *buf = p->file_pathconv (fd, FFH_LINKAT, size);
|
||||||
if (size == 0)
|
if (size == 0)
|
||||||
{
|
{
|
||||||
set_errno (EPERM);
|
set_errno (ENOENT);
|
||||||
CloseHandle (proc);
|
CloseHandle (proc);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
@ -103,7 +109,7 @@ fhandler_process_fd::fd_reopen (int flags)
|
|||||||
fhandler_base *fh;
|
fhandler_base *fh;
|
||||||
HANDLE hdl;
|
HANDLE hdl;
|
||||||
|
|
||||||
fh = fetch_fh (hdl);
|
fh = fetch_fh (hdl, 0);
|
||||||
if (!fh)
|
if (!fh)
|
||||||
return NULL;
|
return NULL;
|
||||||
fh->set_io_handle (hdl);
|
fh->set_io_handle (hdl);
|
||||||
@ -126,7 +132,7 @@ fhandler_process_fd::fstat (struct stat *statbuf)
|
|||||||
fhandler_base *fh;
|
fhandler_base *fh;
|
||||||
HANDLE hdl;
|
HANDLE hdl;
|
||||||
|
|
||||||
fh = fetch_fh (hdl);
|
fh = fetch_fh (hdl, 0);
|
||||||
if (!fh)
|
if (!fh)
|
||||||
return -1;
|
return -1;
|
||||||
fh->set_io_handle (hdl);
|
fh->set_io_handle (hdl);
|
||||||
@ -142,7 +148,7 @@ fhandler_process_fd::link (const char *newpath)
|
|||||||
fhandler_base *fh;
|
fhandler_base *fh;
|
||||||
HANDLE hdl;
|
HANDLE hdl;
|
||||||
|
|
||||||
fh = fetch_fh (hdl);
|
fh = fetch_fh (hdl, FFH_LINKAT);
|
||||||
if (!fh)
|
if (!fh)
|
||||||
return -1;
|
return -1;
|
||||||
fh->set_io_handle (hdl);
|
fh->set_io_handle (hdl);
|
||||||
|
@ -187,7 +187,10 @@ struct _sigcommune
|
|||||||
void *_si_process_handle;
|
void *_si_process_handle;
|
||||||
__extension__ union
|
__extension__ union
|
||||||
{
|
{
|
||||||
|
struct {
|
||||||
int _si_fd;
|
int _si_fd;
|
||||||
|
uint32_t _si_flags;
|
||||||
|
};
|
||||||
int64_t _si_pipe_unique_id;
|
int64_t _si_pipe_unique_id;
|
||||||
char *_si_str;
|
char *_si_str;
|
||||||
};
|
};
|
||||||
|
@ -73,6 +73,11 @@ enum path_types
|
|||||||
PATH_DONT_USE = _BIT (31) /* conversion to signed happens. */
|
PATH_DONT_USE = _BIT (31) /* conversion to signed happens. */
|
||||||
};
|
};
|
||||||
|
|
||||||
|
enum fetch_fh_flags
|
||||||
|
{
|
||||||
|
FFH_LINKAT = (1 << 0),
|
||||||
|
};
|
||||||
|
|
||||||
NTSTATUS file_get_fai (HANDLE, PFILE_ALL_INFORMATION);
|
NTSTATUS file_get_fai (HANDLE, PFILE_ALL_INFORMATION);
|
||||||
int check_reparse_point_target (HANDLE, bool, PREPARSE_DATA_BUFFER,
|
int check_reparse_point_target (HANDLE, bool, PREPARSE_DATA_BUFFER,
|
||||||
PUNICODE_STRING);
|
PUNICODE_STRING);
|
||||||
|
@ -660,9 +660,13 @@ commune_process (void *arg)
|
|||||||
{
|
{
|
||||||
sigproc_printf ("processing PICOM_FILE_PATHCONV");
|
sigproc_printf ("processing PICOM_FILE_PATHCONV");
|
||||||
int fd = si._si_commune._si_fd;
|
int fd = si._si_commune._si_fd;
|
||||||
|
uint32_t flags = si._si_commune._si_flags;
|
||||||
unsigned int n = 0;
|
unsigned int n = 0;
|
||||||
cygheap_fdget cfd (fd);
|
cygheap_fdget cfd (fd);
|
||||||
if (cfd >= 0)
|
if (cfd >= 0
|
||||||
|
&& (!(flags & FFH_LINKAT)
|
||||||
|
|| (cfd->get_flags () & (O_TMPFILE | O_EXCL))
|
||||||
|
!= (O_TMPFILE | O_EXCL)))
|
||||||
{
|
{
|
||||||
fhandler_base *fh = cfd;
|
fhandler_base *fh = cfd;
|
||||||
void *ser_buf = fh->pc.serialize (fh->get_handle (), n);
|
void *ser_buf = fh->pc.serialize (fh->get_handle (), n);
|
||||||
@ -763,6 +767,7 @@ _pinfo::commune_request (__uint32_t code, ...)
|
|||||||
case PICOM_FD:
|
case PICOM_FD:
|
||||||
case PICOM_FILE_PATHCONV:
|
case PICOM_FILE_PATHCONV:
|
||||||
si._si_commune._si_fd = va_arg (args, int);
|
si._si_commune._si_fd = va_arg (args, int);
|
||||||
|
si._si_commune._si_flags = va_arg (args, uint32_t);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
break;
|
break;
|
||||||
@ -852,13 +857,13 @@ _pinfo::pipe_fhandler (int64_t unique_id, size_t &n)
|
|||||||
}
|
}
|
||||||
|
|
||||||
void *
|
void *
|
||||||
_pinfo::file_pathconv (int fd, size_t &n)
|
_pinfo::file_pathconv (int fd, uint32_t flags, size_t &n)
|
||||||
{
|
{
|
||||||
if (!pid)
|
if (!pid)
|
||||||
return NULL;
|
return NULL;
|
||||||
if (pid == myself->pid)
|
if (pid == myself->pid)
|
||||||
return NULL;
|
return NULL;
|
||||||
commune_result cr = commune_request (PICOM_FILE_PATHCONV, fd);
|
commune_result cr = commune_request (PICOM_FILE_PATHCONV, fd, flags);
|
||||||
n = cr.n;
|
n = cr.n;
|
||||||
return (void *) cr.s;
|
return (void *) cr.s;
|
||||||
}
|
}
|
||||||
|
@ -103,7 +103,7 @@ public:
|
|||||||
commune_result commune_request (__uint32_t, ...);
|
commune_result commune_request (__uint32_t, ...);
|
||||||
bool alive ();
|
bool alive ();
|
||||||
fhandler_pipe *pipe_fhandler (int64_t, size_t &);
|
fhandler_pipe *pipe_fhandler (int64_t, size_t &);
|
||||||
void *file_pathconv (int, size_t &);
|
void *file_pathconv (int, uint32_t, size_t &);
|
||||||
char *fd (int fd, size_t &);
|
char *fd (int fd, size_t &);
|
||||||
char *fds (size_t &);
|
char *fds (size_t &);
|
||||||
char *root (size_t &);
|
char *root (size_t &);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user