* ntdll.h (STATUS_END_OF_FILE): Define.

* path.cc (symlink_info::check_shortcut): Use NT function to get file
	size.  Reintroduce checking file size before reading it.  Eliminiate
	close_it label.
	(symlink_info::check_sysfile): Check for EOF condition.
This commit is contained in:
Corinna Vinschen 2007-10-13 11:06:43 +00:00
parent 8cca1e6c93
commit fc7290fd39
3 changed files with 42 additions and 19 deletions

View File

@ -1,3 +1,11 @@
2007-10-12 Corinna Vinschen <corinna@vinschen.de>
* ntdll.h (STATUS_END_OF_FILE): Define.
* path.cc (symlink_info::check_shortcut): Use NT function to get file
size. Reintroduce checking file size before reading it. Eliminiate
close_it label.
(symlink_info::check_sysfile): Check for EOF condition.
2007-10-11 Corinna Vinschen <corinna@vinschen.de> 2007-10-11 Corinna Vinschen <corinna@vinschen.de>
* path.cc (basename): Return pointer into the path argument itself. * path.cc (basename): Return pointer into the path argument itself.

View File

@ -17,6 +17,7 @@
#define STATUS_INVALID_PARAMETER ((NTSTATUS) 0xc000000d) #define STATUS_INVALID_PARAMETER ((NTSTATUS) 0xc000000d)
#define STATUS_NO_SUCH_FILE ((NTSTATUS) 0xc000000f) #define STATUS_NO_SUCH_FILE ((NTSTATUS) 0xc000000f)
#define STATUS_INVALID_DEVICE_REQUEST ((NTSTATUS) 0xc0000010) #define STATUS_INVALID_DEVICE_REQUEST ((NTSTATUS) 0xc0000010)
#define STATUS_END_OF_FILE ((NTSTATUS) 0xc0000011)
#define STATUS_NO_MEDIA_IN_DEVICE ((NTSTATUS) 0xc0000013) #define STATUS_NO_MEDIA_IN_DEVICE ((NTSTATUS) 0xc0000013)
#define STATUS_ACCESS_DENIED ((NTSTATUS) 0xc0000022) #define STATUS_ACCESS_DENIED ((NTSTATUS) 0xc0000022)
#define STATUS_BUFFER_TOO_SMALL ((NTSTATUS) 0xc0000023) #define STATUS_BUFFER_TOO_SMALL ((NTSTATUS) 0xc0000023)

View File

@ -3158,19 +3158,30 @@ symlink_info::check_shortcut (HANDLE h)
char *buf, *cp; char *buf, *cp;
unsigned short len; unsigned short len;
int res = 0; int res = 0;
DWORD size; NTSTATUS status;
IO_STATUS_BLOCK io; IO_STATUS_BLOCK io;
FILE_STANDARD_INFORMATION fsi;
size = GetFileSize (h, NULL); status = NtQueryInformationFile (h, &io, &fsi, sizeof fsi,
buf = (char *) alloca (size + 1); FileStandardInformation);
if (!NT_SUCCESS (NtReadFile (h, NULL, NULL, NULL, if (!NT_SUCCESS (status))
&io, buf, size, NULL, NULL)))
{ {
set_error (EIO); set_error (EIO);
goto close_it; return 0;
}
if (fsi.EndOfFile.QuadPart <= sizeof (win_shortcut_hdr)
|| fsi.EndOfFile.QuadPart > 4 * 65536)
return 0;
buf = (char *) alloca (fsi.EndOfFile.LowPart + 1);
if (!NT_SUCCESS (NtReadFile (h, NULL, NULL, NULL,
&io, buf, fsi.EndOfFile.LowPart, NULL, NULL)))
{
set_error (EIO);
return 0;
} }
file_header = (win_shortcut_hdr *) buf; file_header = (win_shortcut_hdr *) buf;
if (io.Information != size || !cmp_shortcut_header (file_header)) if (io.Information != fsi.EndOfFile.LowPart
|| !cmp_shortcut_header (file_header))
goto file_not_symlink; goto file_not_symlink;
cp = buf + sizeof (win_shortcut_hdr); cp = buf + sizeof (win_shortcut_hdr);
if (file_header->flags & WSH_FLAG_IDLIST) /* Skip ITEMIDLIST */ if (file_header->flags & WSH_FLAG_IDLIST) /* Skip ITEMIDLIST */
@ -3185,7 +3196,7 @@ symlink_info::check_shortcut (HANDLE h)
{ {
/* Has appended full path? If so, use it instead of description. */ /* Has appended full path? If so, use it instead of description. */
unsigned short relpath_len = *(unsigned short *) (cp + len); unsigned short relpath_len = *(unsigned short *) (cp + len);
if (cp + len + 2 + relpath_len < buf + size) if (cp + len + 2 + relpath_len < buf + fsi.EndOfFile.LowPart)
{ {
cp += len + 2 + relpath_len; cp += len + 2 + relpath_len;
len = *(unsigned short *) cp; len = *(unsigned short *) cp;
@ -3198,15 +3209,13 @@ symlink_info::check_shortcut (HANDLE h)
} }
if (res) /* It's a symlink. */ if (res) /* It's a symlink. */
pflags = PATH_SYMLINK | PATH_LNK; pflags = PATH_SYMLINK | PATH_LNK;
goto close_it; return res;
file_not_symlink: file_not_symlink:
/* Not a symlink, see if executable. */ /* Not a symlink, see if executable. */
if (!(pflags & PATH_ALL_EXEC) && has_exec_chars ((const char *) &file_header, io.Information)) if (!(pflags & PATH_ALL_EXEC) && has_exec_chars ((const char *) &file_header, io.Information))
pflags |= PATH_EXEC; pflags |= PATH_EXEC;
return 0;
close_it:
return res;
} }
int int
@ -3214,14 +3223,17 @@ symlink_info::check_sysfile (HANDLE h)
{ {
char cookie_buf[sizeof (SYMLINK_COOKIE) - 1]; char cookie_buf[sizeof (SYMLINK_COOKIE) - 1];
char srcbuf[SYMLINK_MAX + 2]; char srcbuf[SYMLINK_MAX + 2];
NTSTATUS status;
IO_STATUS_BLOCK io; IO_STATUS_BLOCK io;
int res = 0; int res = 0;
if (!NT_SUCCESS (NtReadFile (h, NULL, NULL, NULL, &io, status = NtReadFile (h, NULL, NULL, NULL, &io, cookie_buf,
cookie_buf, sizeof (cookie_buf), NULL, NULL))) sizeof (cookie_buf), NULL, NULL);
if (!NT_SUCCESS (status))
{ {
debug_printf ("ReadFile1 failed"); debug_printf ("ReadFile1 failed");
set_error (EIO); if (status != STATUS_END_OF_FILE)
set_error (EIO);
} }
else if (io.Information == sizeof (cookie_buf) else if (io.Information == sizeof (cookie_buf)
&& memcmp (cookie_buf, SYMLINK_COOKIE, sizeof (cookie_buf)) == 0) && memcmp (cookie_buf, SYMLINK_COOKIE, sizeof (cookie_buf)) == 0)
@ -3229,16 +3241,18 @@ symlink_info::check_sysfile (HANDLE h)
/* It's a symlink. */ /* It's a symlink. */
pflags = PATH_SYMLINK; pflags = PATH_SYMLINK;
if (!NT_SUCCESS (NtReadFile (h, NULL, NULL, NULL, &io, status = NtReadFile (h, NULL, NULL, NULL, &io, srcbuf,
srcbuf, SYMLINK_MAX + 2, NULL, NULL))) SYMLINK_MAX + 2, NULL, NULL);
if (!NT_SUCCESS (status))
{ {
debug_printf ("ReadFile2 failed"); debug_printf ("ReadFile2 failed");
set_error (EIO); if (status != STATUS_END_OF_FILE)
set_error (EIO);
} }
else if (io.Information > SYMLINK_MAX + 1) else if (io.Information > SYMLINK_MAX + 1)
{ {
debug_printf ("symlink string too long"); debug_printf ("symlink string too long");
set_error (EIO);
} }
else else
res = posixify (srcbuf); res = posixify (srcbuf);