diff options
author | Samuel Thibault <samuel.thibault@ens-lyon.org> | 2014-05-30 20:21:54 +0200 |
---|---|---|
committer | Samuel Thibault <samuel.thibault@ens-lyon.org> | 2014-05-30 20:21:54 +0200 |
commit | 2e94e61f1c6263adfcbca641b74f9a07ea8298a0 (patch) | |
tree | 818ba89762e09d3653010458e4b542259c46875a | |
parent | ac38884dc9ad32a11d09f55ba9fe399cd0a48e2f (diff) |
Fix buffer allocation on io_read
* random.c (trivfs_S_io_read): Catch buffer allocation error, and
truncate allocation when we return less data than requested.
-rw-r--r-- | random.c | 21 |
1 files changed, 17 insertions, 4 deletions
@@ -152,6 +152,7 @@ trivfs_S_io_read (struct trivfs_protid *cred, if (amount > 0) { + mach_msg_type_number_t new_amount; while (readable_pool (amount, level) == 0) { if (cred->po->openmodes & O_NONBLOCK) @@ -170,10 +171,22 @@ trivfs_S_io_read (struct trivfs_protid *cred, /* Possibly allocate a new buffer. */ if (*data_len < amount) - *data = mmap (0, amount, PROT_READ|PROT_WRITE, - MAP_ANON, 0, 0); - - amount = read_pool ((byte *) *data, amount, level); + { + *data = mmap (0, amount, PROT_READ|PROT_WRITE, + MAP_ANON, 0, 0); + if (*data == MAP_FAILED) + { + pthread_mutex_unlock (&global_lock); + return errno; + } + } + + new_amount = read_pool ((byte *) *data, amount, level); + + if (new_amount < amount) + munmap (*data + round_page (new_amount), + round_page(amount) - round_page (new_amount)); + amount = new_amount; } *data_len = amount; |