@@ -1968,9 +1968,36 @@ MAPmmapAndRecord(
1968
1968
// Set the requested mapping with forced PROT_WRITE to ensure data from the file can be read there,
1969
1969
// read the data in and finally remove the forced PROT_WRITE. On Intel we can still switch the
1970
1970
// protection later with mprotect.
1971
- if ((mprotect (pvBaseAddress, len + adjust, PROT_WRITE) == -1 ) ||
1972
- (pread (fd, pvBaseAddress, len + adjust, offset - adjust) == -1 ) ||
1973
- (mprotect (pvBaseAddress, len + adjust, prot) == -1 ))
1971
+ bool failCondition = mprotect (pvBaseAddress, len + adjust, PROT_WRITE) == -1 ;
1972
+ if (!failCondition)
1973
+ {
1974
+ unsigned char * buf = pvBaseAddress;
1975
+ size_t nbyte = len + adjust;
1976
+ size_t offset2 = offset - adjust;
1977
+ while (nbyte > 0 )
1978
+ {
1979
+ ssize_t result;
1980
+ while (-1 == result = pread (fd, buf, nbyte, offset2) && errno == EINTR);
1981
+ if (result == -1 )
1982
+ {
1983
+ failCondition = true ;
1984
+ break ;
1985
+ }
1986
+ buf += result;
1987
+ nbyte -= result;
1988
+ offset2 += result;
1989
+ if (result == 0 )
1990
+ {
1991
+ if (nbyte > 0 )
1992
+ {
1993
+ failCondition = true ;
1994
+ errno = EIO; // set to a generic IO error, to indicate that we couldn't read the whole requested region
1995
+ }
1996
+ break ;
1997
+ }
1998
+ }
1999
+ }
2000
+ if (failCondition || (mprotect (pvBaseAddress, len + adjust, prot) == -1 ))
1974
2001
{
1975
2002
palError = FILEGetLastErrorFromErrno ();
1976
2003
}
@@ -2080,16 +2107,54 @@ void * MAPMapPEFile(HANDLE hFile, off_t offset)
2080
2107
// Step 1: Read the PE headers and reserve enough space for the whole image somewhere.
2081
2108
IMAGE_DOS_HEADER dosHeader;
2082
2109
IMAGE_NT_HEADERS ntHeader;
2083
- if (sizeof (dosHeader) != pread (fd, &dosHeader, sizeof (dosHeader), offset))
2084
- {
2085
- palError = FILEGetLastErrorFromErrno ();
2086
- ERROR_ (LOADER)( " reading dos header failed\n " );
2087
- goto done;
2088
- }
2089
- if (sizeof (ntHeader) != pread (fd, &ntHeader, sizeof (ntHeader), offset + dosHeader.e_lfanew ))
2090
- {
2091
- palError = FILEGetLastErrorFromErrno ();
2092
- goto done;
2110
+ unsigned char * preadBuf = &dosHeader;
2111
+ size_t nbyte = sizeof (dosHeader);
2112
+ size_t preadOffset = offset;
2113
+ while (nbyte > 0 )
2114
+ {
2115
+ ssize_t result;
2116
+ while (-1 == result = pread (fd, preadBuf, nbyte, preadOffset) && errno == EINTR);
2117
+ if (result == 0 )
2118
+ {
2119
+ if (nbyte > 0 )
2120
+ {
2121
+ errno = EIO; // set to a generic IO error, to indicate that we couldn't read the whole requested region
2122
+ result = -1 ;
2123
+ }
2124
+ }
2125
+ if (result == -1 )
2126
+ {
2127
+ palError = FILEGetLastErrorFromErrno ();
2128
+ ERROR_ (LOADER)( " reading dos header failed\n " );
2129
+ goto done;
2130
+ }
2131
+ preadBuf += result;
2132
+ nbyte -= result;
2133
+ preadOffset += result;
2134
+ }
2135
+ unsigned char * preadBuf = &ntHeader;
2136
+ size_t nbyte = sizeof (ntHeader);
2137
+ size_t preadOffset = offset + dosHeader.e_lfanew ;
2138
+ while (nbyte > 0 )
2139
+ {
2140
+ ssize_t result;
2141
+ while (-1 == result = pread (fd, preadBuf, nbyte, preadOffset) && errno == EINTR);
2142
+ if (result == 0 )
2143
+ {
2144
+ if (nbyte > 0 )
2145
+ {
2146
+ errno = EIO; // set to a generic IO error, to indicate that we couldn't read the whole requested region
2147
+ result = -1 ;
2148
+ }
2149
+ }
2150
+ if (result == -1 )
2151
+ {
2152
+ palError = FILEGetLastErrorFromErrno ();
2153
+ goto done;
2154
+ }
2155
+ preadBuf += result;
2156
+ nbyte -= result;
2157
+ preadOffset += result;
2093
2158
}
2094
2159
2095
2160
if ((VAL16 (IMAGE_DOS_SIGNATURE) != VAL16 (dosHeader.e_magic ))
0 commit comments