Skip to content

Commit abe0b29

Browse files
committed
1 parent 5a43f24 commit abe0b29

21 files changed

+185
-44
lines changed

hphp/runtime/base/preg.cpp

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,7 @@
4949
#include "hphp/util/logger.h"
5050
#include "hphp/util/concurrent-scalable-cache.h"
5151

52+
#include <folly/FileUtil.h>
5253
#include <folly/json.h>
5354

5455
/* Only defined in pcre >= 8.32 */
@@ -217,7 +218,7 @@ struct PCRECache {
217218
TempKeyCache& keyCache);
218219
void insert(Accessor& accessor, const StringData* regex,
219220
TempKeyCache& keyCache, const pcre_cache_entry* ent);
220-
void dump(const std::string& filename);
221+
void dump(folly::File& file);
221222
size_t size() const;
222223

223224
private:
@@ -512,12 +513,12 @@ void PCRECache::insert(
512513
}
513514
}
514515

515-
void PCRECache::dump(const std::string& filename) {
516-
std::ofstream out(filename.c_str());
516+
void PCRECache::dump(folly::File& file) {
517517
switch (m_kind) {
518518
case CacheKind::Static:
519519
for (auto& it : *m_staticCache) {
520-
out << it.first->data() << "\n";
520+
folly::writeFull(file.fd(), it.first->data(), it.first->size());
521+
folly::writeFull(file.fd(), "\n", 1);
521522
}
522523
break;
523524
case CacheKind::Lru:
@@ -530,12 +531,12 @@ void PCRECache::dump(const std::string& filename) {
530531
m_scalableCache->snapshotKeys(keys);
531532
}
532533
for (auto& key: keys) {
533-
out << key.c_str() << "\n";
534+
folly::writeFull(file.fd(), key.data(), key.size());
535+
folly::writeFull(file.fd(), "\n", 1);
534536
}
535537
}
536538
break;
537539
}
538-
out.close();
539540
}
540541

541542
size_t PCRECache::size() const {
@@ -572,8 +573,8 @@ void pcre_reinit() {
572573
void pcre_init() {
573574
}
574575

575-
void pcre_dump_cache(const std::string& filename) {
576-
s_pcreCache.dump(filename);
576+
void pcre_dump_cache(folly::File& file) {
577+
s_pcreCache.dump(file);
577578
}
578579

579580
static pcre_jit_stack* alloc_jit_stack(void* /*data*/) {

hphp/runtime/base/preg.h

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818

1919
#include "hphp/runtime/base/type-string.h"
2020

21+
#include <folly/File.h>
2122
#include <folly/Optional.h>
2223

2324
#include <cstdint>
@@ -111,9 +112,9 @@ void pcre_reinit();
111112
void pcre_session_exit();
112113

113114
/*
114-
* Dump the contents of the PCRE cache to filename.
115+
* Dump the contents of the PCRE cache to the given file.
115116
*/
116-
void pcre_dump_cache(const std::string& filename);
117+
void pcre_dump_cache(folly::File& file);
117118

118119
///////////////////////////////////////////////////////////////////////////////
119120
// PHP API

hphp/runtime/base/runtime-option.cpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,7 @@
5454
#include "hphp/util/gzip.h"
5555
#include "hphp/util/hardware-counter.h"
5656
#include "hphp/util/hdf.h"
57+
#include "hphp/util/light-process.h"
5758
#include "hphp/util/log-file-flusher.h"
5859
#include "hphp/util/logger.h"
5960
#include "hphp/util/network.h"
@@ -754,6 +755,7 @@ bool RuntimeOption::AdminServerStatsNeedPassword = true;
754755
std::string RuntimeOption::AdminPassword;
755756
std::set<std::string> RuntimeOption::AdminPasswords;
756757
std::set<std::string> RuntimeOption::HashedAdminPasswords;
758+
std::string RuntimeOption::AdminDumpPath;
757759

758760
std::string RuntimeOption::ProxyOriginRaw;
759761
int RuntimeOption::ProxyPercentageRaw = 0;
@@ -2398,6 +2400,8 @@ void RuntimeOption::Load(
23982400
"Server.LightProcessFilePrefix", "./lightprocess");
23992401
Config::Bind(LightProcessCount, ini, config,
24002402
"Server.LightProcessCount", 0);
2403+
Config::Bind(LightProcess::g_strictUser, ini, config,
2404+
"Server.LightProcessStrictUser", false);
24012405
Config::Bind(ForceServerNameToHeader, ini, config,
24022406
"Server.ForceServerNameToHeader");
24032407
Config::Bind(AllowDuplicateCookies, ini, config,
@@ -2513,6 +2517,8 @@ void RuntimeOption::Load(
25132517
AdminPasswords = Config::GetSet(ini, config, "AdminServer.Passwords");
25142518
HashedAdminPasswords =
25152519
Config::GetSet(ini, config, "AdminServer.HashedPasswords");
2520+
Config::Bind(AdminDumpPath, ini, config,
2521+
"AdminServer.DumpPath", "/tmp/hhvm_admin_dump");
25162522
}
25172523
{
25182524
// Proxy

hphp/runtime/base/runtime-option.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -496,6 +496,8 @@ struct RuntimeOption {
496496
static std::set<std::string> AdminPasswords;
497497
static std::set<std::string> HashedAdminPasswords;
498498

499+
static std::string AdminDumpPath;
500+
499501
/*
500502
* Options related to reverse proxying. ProxyOriginRaw and ProxyPercentageRaw
501503
* may be mutated by background threads and should only be read or written

hphp/runtime/base/string-util.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -435,7 +435,8 @@ String StringUtil::ROT13(const String& input) {
435435
}
436436

437437
String StringUtil::Crypt(const String& input, const char *salt /* = "" */) {
438-
if (salt && salt[0] == '\0') {
438+
assertx(salt);
439+
if (salt[0] == '\0') {
439440
raise_notice("crypt(): No salt parameter was specified."
440441
" You must use a randomly generated salt and a strong"
441442
" hash function to produce a secure hash.");

hphp/runtime/ext/domdocument/ext_domdocument.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,9 @@ struct DOMNode {
5151
// for __clone
5252
DOMNode& operator=(const DOMNode& copy);
5353

54-
req::ptr<XMLDocumentData> doc() const { return m_node->doc(); }
54+
req::ptr<XMLDocumentData> doc() const {
55+
return m_node ? m_node->doc() : nullptr;
56+
}
5557
XMLNode node() const { return m_node; }
5658
xmlNodePtr nodep() const {
5759
return m_node ? m_node->nodep() : nullptr;

hphp/runtime/ext/gd/libgd/gd.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -185,8 +185,8 @@ gdImagePtr gdImageCreateTrueColor (int sx, int sy)
185185

186186
// Check for OOM before doing a potentially large allocation.
187187
auto allocsz = sizeof(gdImage)
188-
+ sy * (sizeof(int *) + sizeof(unsigned char *))
189-
+ sx * sy * (sizeof(int) + sizeof(unsigned char));
188+
+ (sizeof(int *) + sizeof(unsigned char *)) * sy
189+
+ (sizeof(int) + sizeof(unsigned char)) * sx * sy;
190190
if (UNLIKELY(precheckOOM(allocsz))) {
191191
// Don't throw here because GD might need to do its own cleanup.
192192
return NULL;

hphp/runtime/ext/ldap/ext_ldap.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2139,7 +2139,7 @@ String HHVM_FUNCTION(ldap_escape,
21392139

21402140
char hex[] = "0123456789abcdef";
21412141

2142-
String result(3 * value.size(), ReserveString);
2142+
String result(3UL * value.size(), ReserveString);
21432143
char *rdata = result.get()->mutableData(), *r = rdata;
21442144

21452145
for (int i = 0; i < value.size(); i++) {

hphp/runtime/ext/xmlreader/ext_xmlreader.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -598,11 +598,11 @@ Variant HHVM_METHOD(XMLReader, expand,
598598
if (!basenode.isNull()) {
599599
auto dombasenode = Native::data<DOMNode>(basenode.toObject());
600600
doc = dombasenode->doc();
601-
docp = doc->docp();
602-
if (docp == nullptr) {
601+
if (doc == nullptr || doc->docp() == nullptr) {
603602
raise_warning("Invalid State Error");
604603
return false;
605604
}
605+
docp = doc->docp();
606606
}
607607

608608
if (data->m_ptr) {

hphp/runtime/server/admin-request-handler.cpp

Lines changed: 46 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,9 @@
7676
#endif
7777

7878
#include <folly/Conv.h>
79+
#include <folly/File.h>
80+
#include <folly/FileUtil.h>
81+
#include <folly/Optional.h>
7982
#include <folly/Random.h>
8083
#include <folly/portability/Unistd.h>
8184

@@ -254,6 +257,34 @@ void AdminRequestHandler::teardownRequest(Transport* transport) noexcept {
254257
WarnIfNotOK(transport);
255258
}
256259

260+
namespace {
261+
262+
// When this struct is destroyed, it will close the file.
263+
struct DumpFile {
264+
std::string path;
265+
folly::File file;
266+
};
267+
268+
folly::Optional<DumpFile> dump_file(const char* name) {
269+
auto const path = folly::sformat("{}/{}", RO::AdminDumpPath, name);
270+
271+
// mkdir -p the directory prefix of `path`
272+
if (FileUtil::mkdir(path) != 0) return folly::none;
273+
274+
// If remove fails because of a permissions issue, then we won't be
275+
// able to open the file for exclusive write below.
276+
remove(path.c_str());
277+
278+
// Create the file, failing if it already exists. Doing so ensures
279+
// that we have write access to the file and that no other user does.
280+
auto const fd = open(path.c_str(), O_CREAT|O_EXCL|O_RDWR, 0666);
281+
if (fd < 0) return folly::none;
282+
283+
return DumpFile{path, folly::File(fd, /*owns=*/true)};
284+
}
285+
286+
}
287+
257288
void AdminRequestHandler::handleRequest(Transport *transport) {
258289
transport->addHeader("Content-Type", "text/plain");
259290
std::string cmd = transport->getCommand();
@@ -714,10 +745,12 @@ void AdminRequestHandler::handleRequest(Transport *transport) {
714745
break;
715746
}
716747
if (strncmp(cmd.c_str(), "dump-static-strings", 19) == 0) {
717-
auto filename = transport->getParam("file");
718-
if (filename == "") filename = "/tmp/static_strings";
719-
handleDumpStaticStringsRequest(cmd, filename);
720-
transport->sendString("OK\n");
748+
if (auto file = dump_file("static_strings")) {
749+
handleDumpStaticStringsRequest(file->file);
750+
transport->sendString(folly::sformat("dumped to {}\n", file->path));
751+
} else {
752+
transport->sendString("Unable to mkdir or file already exists.\n");
753+
}
721754
break;
722755
}
723756
if (strncmp(cmd.c_str(), "random-static-strings", 21) == 0) {
@@ -746,10 +779,12 @@ void AdminRequestHandler::handleRequest(Transport *transport) {
746779
}
747780

748781
if (cmd == "dump-pcre-cache") {
749-
auto filename = transport->getParam("file");
750-
if (filename == "") filename = "/tmp/pcre_cache";
751-
pcre_dump_cache(filename);
752-
transport->sendString("OK\n");
782+
if (auto file = dump_file("pcre_cache")) {
783+
pcre_dump_cache(file->file);
784+
transport->sendString(folly::sformat("dumped to {}\n", file->path));
785+
} else {
786+
transport->sendString("Unable to mkdir or file already exists.\n");
787+
}
753788
break;
754789
}
755790

@@ -1368,13 +1403,11 @@ std::string formatStaticString(StringData* str) {
13681403
"----\n{} bytes\n{}\n", str->size(), str->toCppString());
13691404
}
13701405

1371-
bool AdminRequestHandler::handleDumpStaticStringsRequest(
1372-
const std::string& /*cmd*/, const std::string& filename) {
1406+
bool AdminRequestHandler::handleDumpStaticStringsRequest(folly::File& file) {
13731407
auto const& list = lookupDefinedStaticStrings();
1374-
std::ofstream out(filename.c_str());
1375-
SCOPE_EXIT { out.close(); };
13761408
for (auto item : list) {
1377-
out << formatStaticString(item);
1409+
auto const line = formatStaticString(item);
1410+
folly::writeFull(file.fd(), line.data(), line.size());
13781411
if (RuntimeOption::EvalPerfDataMap) {
13791412
auto const len = std::min<size_t>(item->size(), 255);
13801413
std::string str(item->data(), len);

hphp/runtime/server/admin-request-handler.h

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,8 @@
1919
#include "hphp/runtime/server/access-log.h"
2020
#include "hphp/runtime/server/server.h"
2121

22+
#include <folly/File.h>
23+
2224
namespace HPHP {
2325
///////////////////////////////////////////////////////////////////////////////
2426

@@ -72,8 +74,7 @@ struct AdminRequestHandler : RequestHandler {
7274
Transport *transport);
7375
bool handleStaticStringsRequest(const std::string &cmd,
7476
Transport *transport);
75-
bool handleDumpStaticStringsRequest(const std::string &cmd,
76-
const std::string &filename);
77+
bool handleDumpStaticStringsRequest(folly::File& file);
7778
bool handleRandomStaticStringsRequest(const std::string &cmd,
7879
Transport *transport);
7980
bool handleVMRequest (const std::string &cmd, Transport *transport);

hphp/test/slow/ext_ldap/t78806688.php

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
<?hh
2+
3+
<<__EntryPoint>>
4+
function main(): void {
5+
$multiplier = 1431655769;
6+
$s = str_repeat("a", $multiplier);
7+
ldap_escape($s);
8+
echo "FAIL!\n";
9+
}
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Fatal error: String length exceeded: 4294967307 > %d in %s/t78806688.php on line 7
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
<?hh
2+
3+
<<__EntryPoint>>
4+
function main(): void {
5+
$key = "\x26\xbd\xbd\xbd\xff\x60\xbf\xff\xff\x60";
6+
$salt1 = "\x24\x32\x78\x24\x31\x30\x24\x24\x35\x24\xad\x20\x20\x26\xff\x60\xbf\xff\xff\x60\x24\x31\x78\xa8\xa8\xa0\x01\x01\x01\x01\x01\x01";
7+
$salt2 = "\x24\x32\x78\x24\x31\x30\x24\x24\x35";
8+
9+
var_dump(base64_encode(crypt($key, $salt1)));
10+
var_dump(base64_encode(crypt($key, $salt2)));
11+
}
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
string(4) "KjA="
2+
string(12) "JDJ4JDEwJCQ1"
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
<?hh
2+
3+
<<__EntryPoint>>
4+
function main(): void {
5+
$a = new XMLReader();
6+
$b = new DOMNode();
7+
$a->expand($b);
8+
$a->expand($a);
9+
}
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
Warning: Invalid State Error in %s on line %d
2+
3+
Warning: Invalid State Error in %s on line %d

0 commit comments

Comments
 (0)