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
|
||||
{
|
||||
fhandler_base *fetch_fh (HANDLE &);
|
||||
fhandler_base *fetch_fh (HANDLE &, uint32_t);
|
||||
|
||||
public:
|
||||
fhandler_process_fd () : fhandler_process () {}
|
||||
|
@ -29,7 +29,7 @@ details. */
|
||||
|
||||
|
||||
fhandler_base *
|
||||
fhandler_process_fd::fetch_fh (HANDLE &out_hdl)
|
||||
fhandler_process_fd::fetch_fh (HANDLE &out_hdl, uint32_t flags)
|
||||
{
|
||||
const char *path;
|
||||
char *e;
|
||||
@ -49,6 +49,12 @@ fhandler_process_fd::fetch_fh (HANDLE &out_hdl)
|
||||
cygheap_fdget cfd (fd, true);
|
||||
if (cfd < 0)
|
||||
return NULL;
|
||||
if ((flags & FFH_LINKAT)
|
||||
&& (cfd->get_flags () & (O_TMPFILE | O_EXCL)) == (O_TMPFILE | O_EXCL))
|
||||
{
|
||||
set_errno (ENOENT);
|
||||
return NULL;
|
||||
}
|
||||
proc = GetCurrentProcess ();
|
||||
pc << cfd->pc;
|
||||
hdl = cfd->get_handle ();
|
||||
@ -68,10 +74,10 @@ fhandler_process_fd::fetch_fh (HANDLE &out_hdl)
|
||||
return NULL;
|
||||
}
|
||||
size_t size;
|
||||
void *buf = p->file_pathconv (fd, size);
|
||||
void *buf = p->file_pathconv (fd, FFH_LINKAT, size);
|
||||
if (size == 0)
|
||||
{
|
||||
set_errno (EPERM);
|
||||
set_errno (ENOENT);
|
||||
CloseHandle (proc);
|
||||
return NULL;
|
||||
}
|
||||
@ -103,7 +109,7 @@ fhandler_process_fd::fd_reopen (int flags)
|
||||
fhandler_base *fh;
|
||||
HANDLE hdl;
|
||||
|
||||
fh = fetch_fh (hdl);
|
||||
fh = fetch_fh (hdl, 0);
|
||||
if (!fh)
|
||||
return NULL;
|
||||
fh->set_io_handle (hdl);
|
||||
@ -126,7 +132,7 @@ fhandler_process_fd::fstat (struct stat *statbuf)
|
||||
fhandler_base *fh;
|
||||
HANDLE hdl;
|
||||
|
||||
fh = fetch_fh (hdl);
|
||||
fh = fetch_fh (hdl, 0);
|
||||
if (!fh)
|
||||
return -1;
|
||||
fh->set_io_handle (hdl);
|
||||
@ -142,7 +148,7 @@ fhandler_process_fd::link (const char *newpath)
|
||||
fhandler_base *fh;
|
||||
HANDLE hdl;
|
||||
|
||||
fh = fetch_fh (hdl);
|
||||
fh = fetch_fh (hdl, FFH_LINKAT);
|
||||
if (!fh)
|
||||
return -1;
|
||||
fh->set_io_handle (hdl);
|
||||
|
@ -187,7 +187,10 @@ struct _sigcommune
|
||||
void *_si_process_handle;
|
||||
__extension__ union
|
||||
{
|
||||
int _si_fd;
|
||||
struct {
|
||||
int _si_fd;
|
||||
uint32_t _si_flags;
|
||||
};
|
||||
int64_t _si_pipe_unique_id;
|
||||
char *_si_str;
|
||||
};
|
||||
|
@ -73,6 +73,11 @@ enum path_types
|
||||
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);
|
||||
int check_reparse_point_target (HANDLE, bool, PREPARSE_DATA_BUFFER,
|
||||
PUNICODE_STRING);
|
||||
|
@ -660,9 +660,13 @@ commune_process (void *arg)
|
||||
{
|
||||
sigproc_printf ("processing PICOM_FILE_PATHCONV");
|
||||
int fd = si._si_commune._si_fd;
|
||||
uint32_t flags = si._si_commune._si_flags;
|
||||
unsigned int n = 0;
|
||||
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;
|
||||
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_FILE_PATHCONV:
|
||||
si._si_commune._si_fd = va_arg (args, int);
|
||||
si._si_commune._si_flags = va_arg (args, uint32_t);
|
||||
break;
|
||||
|
||||
break;
|
||||
@ -852,13 +857,13 @@ _pinfo::pipe_fhandler (int64_t unique_id, size_t &n)
|
||||
}
|
||||
|
||||
void *
|
||||
_pinfo::file_pathconv (int fd, size_t &n)
|
||||
_pinfo::file_pathconv (int fd, uint32_t flags, size_t &n)
|
||||
{
|
||||
if (!pid)
|
||||
return NULL;
|
||||
if (pid == myself->pid)
|
||||
return NULL;
|
||||
commune_result cr = commune_request (PICOM_FILE_PATHCONV, fd);
|
||||
commune_result cr = commune_request (PICOM_FILE_PATHCONV, fd, flags);
|
||||
n = cr.n;
|
||||
return (void *) cr.s;
|
||||
}
|
||||
|
@ -103,7 +103,7 @@ public:
|
||||
commune_result commune_request (__uint32_t, ...);
|
||||
bool alive ();
|
||||
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 *fds (size_t &);
|
||||
char *root (size_t &);
|
||||
|
Loading…
x
Reference in New Issue
Block a user