diff options
Diffstat (limited to 'base/file_descriptor_shuffle.cc')
-rw-r--r-- | base/file_descriptor_shuffle.cc | 36 |
1 files changed, 24 insertions, 12 deletions
diff --git a/base/file_descriptor_shuffle.cc b/base/file_descriptor_shuffle.cc index e722a29..2bb156b 100644 --- a/base/file_descriptor_shuffle.cc +++ b/base/file_descriptor_shuffle.cc @@ -12,28 +12,36 @@ namespace base { -bool PerformInjectiveMultimap(const InjectiveMultimap& m_in, - InjectionDelegate* delegate) { - InjectiveMultimap m(m_in); - std::vector<int> extra_fds; +bool PerformInjectiveMultimapDestructive( + InjectiveMultimap* m, InjectionDelegate* delegate) { + static const size_t kMaxExtraFDs = 16; + int extra_fds[kMaxExtraFDs]; + unsigned next_extra_fd = 0; - for (InjectiveMultimap::iterator i = m.begin(); i != m.end(); ++i) { + // DANGER: this function may not allocate. + + for (InjectiveMultimap::iterator i = m->begin(); i != m->end(); ++i) { int temp_fd = -1; // We DCHECK the injectiveness of the mapping. - for (InjectiveMultimap::iterator j = i + 1; j != m.end(); ++j) { + for (InjectiveMultimap::iterator j = i + 1; j != m->end(); ++j) { DCHECK(i->dest != j->dest) << "Both fd " << i->source << " and " << j->source << " map to " << i->dest; } const bool is_identity = i->source == i->dest; - for (InjectiveMultimap::iterator j = i + 1; j != m.end(); ++j) { + for (InjectiveMultimap::iterator j = i + 1; j != m->end(); ++j) { if (!is_identity && i->dest == j->source) { if (temp_fd == -1) { if (!delegate->Duplicate(&temp_fd, i->dest)) return false; - extra_fds.push_back(temp_fd); + if (next_extra_fd < kMaxExtraFDs) { + extra_fds[next_extra_fd++] = temp_fd; + } else { + RAW_LOG(ERROR, "PerformInjectiveMultimapDestructive overflowed " + "extra_fds. Leaking file descriptors!"); + } } j->source = temp_fd; @@ -58,14 +66,18 @@ bool PerformInjectiveMultimap(const InjectiveMultimap& m_in, delegate->Close(i->source); } - for (std::vector<int>::const_iterator - i = extra_fds.begin(); i != extra_fds.end(); ++i) { - delegate->Close(*i); - } + for (unsigned i = 0; i < next_extra_fd; i++) + delegate->Close(extra_fds[i]); return true; } +bool PerformInjectiveMultimap(const InjectiveMultimap& m_in, + InjectionDelegate* delegate) { + InjectiveMultimap m(m_in); + return PerformInjectiveMultimapDestructive(&m, delegate); +} + bool FileDescriptorTableInjection::Duplicate(int* result, int fd) { *result = HANDLE_EINTR(dup(fd)); return *result >= 0; |