SERVER-91862 Validate DB name before writing to config.databases (#24637)

GitOrigin-RevId: d309a265a7bcf366481f7240443cd508679ef841
This commit is contained in:
Daniel Gómez Ferro 2024-07-16 13:06:33 +02:00 committed by MongoDB Bot
parent 4e3b7a935d
commit 10fa3926f1
4 changed files with 60 additions and 12 deletions

View File

@ -4,15 +4,59 @@
// @tags: [
// assumes_no_implicit_collection_creation_on_get_collection
// ]
var invalidDB = db.getSiblingDB("NonExistentDB");
// This is a hack to bypass invalid database name checking by the DB constructor
invalidDB._name = "Invalid DB Name";
import {FixtureHelpers} from "jstests/libs/fixture_helpers.js";
assert.writeError(invalidDB.coll.insert({x: 1}));
function testInvalidDBName(invalidName) {
const isMongos = FixtureHelpers.isMongos(db);
const errMsg = `'${invalidName}' database with invalid name was created`;
let invalidDB = db.getSiblingDB("NonExistentDB");
// Ensure that no database was created
var dbList = db.getSiblingDB('admin').runCommand({listDatabases: 1}).databases;
dbList.forEach(function(dbInfo) {
assert.neq('Invalid DB Name', dbInfo.name, 'database with invalid name was created');
});
// This is a hack to bypass invalid database name checking by the DB constructor
invalidDB._name = invalidName;
function validateState() {
// Ensure that no database was created
var dbList = db.getSiblingDB('admin').runCommand({listDatabases: 1}).databases;
dbList.forEach(function(dbInfo) {
assert.neq(invalidName, dbInfo.name, errMsg);
});
// On sharding ensure no entry was added to config.databases
if (isMongos) {
assert.eq(
db.getSiblingDB('config').databases.countDocuments({_id: invalidName}), 0, errMsg);
}
}
function testCommandFailsAndValidate(command) {
assert.commandFailedWithCode(command(), ErrorCodes.InvalidNamespace, errMsg);
validateState();
}
function testWriteErrorAndValidate(command) {
assert.writeError(command(), errMsg);
validateState();
}
testWriteErrorAndValidate(() => {
return invalidDB.test.insert({x: 1});
});
testCommandFailsAndValidate(() => {
return invalidDB.createCollection("test");
});
testCommandFailsAndValidate(() => {
return invalidDB.createView("a", "b", [{$match: {year: 1}}]);
});
if (isMongos) {
testCommandFailsAndValidate(() => {
return sh.shardCollection(invalidName + ".test", {a: 1});
});
testCommandFailsAndValidate(() => {
return sh.enableSharding(invalidName);
});
}
}
testInvalidDBName("Invalid DB Name");
testInvalidDBName("$invalidDBName");

View File

@ -2,8 +2,6 @@
* Test shardCollection command behavior
*/
import {findChunksUtil} from "jstests/sharding/libs/find_chunks_util.js";
var kDbName = db.getName();
db.dropDatabase();

View File

@ -201,6 +201,12 @@ Status createProfileCollection(OperationContext* opCtx, Database* db) {
const auto dbProfilingNS = NamespaceString::makeSystemDotProfileNamespace(db->name());
if (!dbProfilingNS.isValid(DatabaseName::DollarInDbNameBehavior::Disallow)) {
return Status(ErrorCodes::InvalidNamespace,
str::stream()
<< "Invalid database name: " << db->name().toStringForErrorMsg());
}
// Checking the collection exists must also be done in the WCE retry loop. Only retrying
// collection creation would endlessly throw errors because the collection exists: must check
// and see the collection exists in order to break free.

View File

@ -131,7 +131,7 @@ DatabaseType ShardingCatalogManager::createDatabase(
uassert(ErrorCodes::InvalidNamespace,
str::stream() << "Invalid db name specified: " << dbName.toStringForErrorMsg(),
DatabaseName::isValid(dbName, DatabaseName::DollarInDbNameBehavior::Allow));
DatabaseName::isValid(dbName, DatabaseName::DollarInDbNameBehavior::Disallow));
// Make sure to force update of any stale metadata
ON_BLOCK_EXIT([&] { RoutingInformationCache::get(opCtx)->purgeDatabase(dbName); });