Open
Bug 339994
Opened 19 years ago
Updated 3 years ago
Coverity 498, PR_EmulateSendFile may pass NULL to func that dereferences it
Categories
(NSPR :: NSPR, defect)
Tracking
(Not tracked)
NEW
4.7
People
(Reporter: nelson, Unassigned)
Details
(Keywords: coverity)
PR_EmulateSendFile may pass a NULL mapHandle to PR_MemMap, which dereferences it.
To do so, this sequence of statements:
376 if (sfd->file_nbytes)
377 file_bytes = sfd->file_nbytes;
378 else
379 file_bytes = info.size - sfd->file_offset;
380
381 alignment = PR_GetMemMapAlignment();
382
383 /* number of initial bytes to skip in mmap'd segment */
384 addr_offset = sfd->file_offset % alignment;
385
386 /* find previous mmap alignment boundary */
387 file_mmap_offset = sfd->file_offset - addr_offset;
388
389 /*
390 * If the file is large, mmap and send the file in chunks so as
391 * to not consume too much virtual address space
392 */
393 mmap_len = PR_MIN(file_bytes + addr_offset, SENDFILE_MMAP_CHUNK);
394 len = mmap_len - addr_offset;
395
396 /*
397 * Map in (part of) file. Take care of zero-length files.
398 */
399 if (len) {
must result in len being zero, so that the following lines are not executed:
400 LL_I2L(zero64, 0);
401 mapHandle = PR_CreateFileMap(sfd->fd, zero64, PR_PROT_READONLY);
There may be several ways this can occur. Here's one:
if "alignment" is greater than SENDFILE_MMAP_CHUNK (currently 256K)
and the caller sets these members of sfd as shown:
sfd->file_offset = SENDFILE_MMAP_CHUNK;
sfd->file_nbytes = any value greater than zero, and not greater than
the file size minus SENDFILE_MMAP_CHUNK
sfd->hlen = any value greater than zero.
I do not know if PR_GetMemMapAlignment() ever returns a value > 256k.
IIRC, on some boxes, the page size in IRIX is 256k on some boxes,
but that is not greater than 256K.
Comment 1•19 years ago
|
||
If "alignment" is greater than SENDFILE_MMAP_CHUNK, "len"
can be not only 0 but also negative.
The code in that function requires not only SENDFILE_MMAP_CHUNK
be greater than "alignment" but also SENDFILE_MMAP_CHUNK
be a multiple of "alignment". This requirement is enfored
by an assertion later in the function:
/*
* Map in (part of) file
*/
file_mmap_offset = sfd->file_offset + count - sfd->hlen;
PR_ASSERT((file_mmap_offset % alignment) == 0);
LL_I2L(file_mmap_offset64, file_mmap_offset);
addr = PR_MemMap(mapHandle, file_mmap_offset64, len);
To ensure that SENDFILE_MMAP_CHUNK is a multiple of
"alignment", we can define a variable "sendfile_mmap_chunk"
as n*alignment, where n = 256K/alignment,
and use sendfile_mmap_chunk instead of SENDFILE_MMAP_CHUNK
throughout the code. I'm not sure if this change will
silence Coverity though.
At line 395 we should also assert that if files_bytes > 0,
then len > 0:
PR_ASSERT((file_bytes == 0) || len > 0);
The reason is that if files_bytes > 0, then we must call
PR_CreateFileMap to create mapHandle. Right now that is
done inside the if (len) block.
Sample values of "alignment":
HP-UX ia64 32-bit: 4K
HP-UX ia64 64-bit: 4K
Linux x86: 4K
Linux x86-64: 4K
Mac OS X PowerPC: 4K
Solaris 9 SPARC 32-bit: 8K
Solaris 9 SPARC 64-bit: 8K
Windows XP SP2: 64K
None of these is greater than SENDFILE_MMAP_CHUNK (256K).
So right now this bug is only a theoretical possibility.
Severity: normal → minor
Updated•19 years ago
|
Target Milestone: --- → 4.7
Updated•19 years ago
|
QA Contact: wtchang → nspr
Updated•3 years ago
|
Severity: minor → S4
Comment 2•3 years ago
|
||
The bug assignee is inactive on Bugzilla, so the assignee is being reset.
Assignee: wtc → nobody
You need to log in
before you can comment on or make changes to this bug.
Description
•