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:
		| @@ -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 | ||||||
|   { |   { | ||||||
|     int _si_fd; |     struct { | ||||||
|  |       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 &); | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user