Uploaded image for project: 'Core Server'
  1. Core Server
  2. SERVER-48513

User collections can be renamed to a valid system collection, leading to server crash.

    • Type: Icon: Bug Bug
    • Resolution: Duplicate
    • Priority: Icon: Major - P3 Major - P3
    • None
    • Affects Version/s: None
    • Component/s: Catalog
    • None
    • Storage Execution
    • ALL
    • Hide
      load('jstests/libs/parallelTester.js');
      load("jstests/replsets/rslib.js");
      
      (function() {
      
      "use strict";
      
      const dbName = jsTest.name();
      const collName = "coll";
      
      var rst = new ReplSetTest({nodes: [{}, {rsConfig: {priority: 1}}]});
      rst.startSet();
      rst.initiate();
      
      const primary = rst.getPrimary();
      const primaryDB = primary.getDB(dbName);
      const primaryAdmin = primary.getDB("admin");
      const primaryColl = primaryDB[collName];
      const collNss = primaryColl.getFullName();
      const secondary = rst.getSecondary();
      
      TestData.dbName = dbName;
      TestData.collName = collName;
      
      jsTestLog("Do a document write");
      assert.commandWorked(
              primaryColl.insert({_id: 0}, {"writeConcern": {"w": "majority"}}));
      
      jsTestLog("Insert duplicate records to admin.users");
      assert.commandWorked(
              primaryAdmin.users.insert({user: 'backdoor', db: 'admin', pwd: 'hashed', roles: '--port'}, {"writeConcern": {"w": "majority"}}));
      
      assert.commandWorked(
              primaryAdmin.users.insert({user: 'backdoor', db: 'admin', pwd: 'hashed', roles: '--port'}, {"writeConcern": {"w": "majority"}}));
      
      print("Listing admin.users doc  " + tojson(primaryAdmin.users.find().toArray()));
      
      // This step makes admin.system.users collection to have a records that would violate if the indexes 'user_1_db_1' gets built.
      jsTestLog("Rename collection from admin.users to admin.systemusers");
      assert.commandWorked(primaryAdmin.adminCommand({renameCollection: "admin.users" , to: "admin.system.users", dropTarget: true}));
      
      print("Listing admin.system.users doc  " + tojson(primaryAdmin.system.users.find().toArray()));
      rst.awaitReplication();
      
      jsTestLog("Make primary step down");
      assert.commandWorked(primary.adminCommand({"replSetStepDown": 1000, "force": true}));
      
      jsTestLog("Make secondary step up");
      assert.commandWorked(secondary.adminCommand({"replSetStepUp": 1}));
      
      // Now, the new primary would try to build index 'user_1_db_1' for  admin.system.users collection as part of onTransitionToPrimary hook, leading to fassert failure due to duplicate key error.
      // Wait for the secondary to become master.
      rst.getPrimary();
      
      rst.stopSet();
      })();
      
      Show
      load('jstests/libs/parallelTester.js'); load("jstests/replsets/rslib.js"); (function() { "use strict"; const dbName = jsTest.name(); const collName = "coll"; var rst = new ReplSetTest({nodes: [{}, {rsConfig: {priority: 1}}]}); rst.startSet(); rst.initiate(); const primary = rst.getPrimary(); const primaryDB = primary.getDB(dbName); const primaryAdmin = primary.getDB("admin"); const primaryColl = primaryDB[collName]; const collNss = primaryColl.getFullName(); const secondary = rst.getSecondary(); TestData.dbName = dbName; TestData.collName = collName; jsTestLog("Do a document write"); assert.commandWorked(         primaryColl.insert({_id: 0}, {"writeConcern": {"w": "majority"}})); jsTestLog("Insert duplicate records to admin.users"); assert.commandWorked(         primaryAdmin.users.insert({user: 'backdoor', db: 'admin', pwd: 'hashed', roles: '--port'}, {"writeConcern": {"w": "majority"}})); assert.commandWorked(         primaryAdmin.users.insert({user: 'backdoor', db: 'admin', pwd: 'hashed', roles: '--port'}, {"writeConcern": {"w": "majority"}})); print("Listing admin.users doc " + tojson(primaryAdmin.users.find().toArray())); // This step makes admin.system.users collection to have a records that would violate if the indexes 'user_1_db_1' gets built. jsTestLog("Rename collection from admin.users to admin.systemusers"); assert.commandWorked(primaryAdmin.adminCommand({renameCollection: "admin.users" , to: "admin.system.users", dropTarget: true})); print("Listing admin.system.users doc " + tojson(primaryAdmin.system.users.find().toArray())); rst.awaitReplication(); jsTestLog("Make primary step down"); assert.commandWorked(primary.adminCommand({"replSetStepDown": 1000, "force": true})); jsTestLog("Make secondary step up"); assert.commandWorked(secondary.adminCommand({"replSetStepUp": 1})); // Now, the new primary would try to build index 'user_1_db_1' for admin.system.users collection as part of onTransitionToPrimary hook, leading to fassert failure due to duplicate key error. // Wait for the secondary to become master. rst.getPrimary(); rst.stopSet(); })();
    • 0

      Noticed a build failure whose root cause is that we allow user collections to get renamed to a valid system collections if the target system collection is not present. As a result, that system collection can have docs that would violate the index key constraints when it's indexes gets built in future, leading to fassert failure. But, on the other hand, if the target system collection is present, then we would fail the rename either due to
      1) 'NamespaceExists' error if 'droptarget' param of rename cmd is set as false.
      2)'can't drop system collection <system collection name>' error if droptarget param of rename cmd is set true.

            Assignee:
            backlog-server-execution [DO NOT USE] Backlog - Storage Execution Team
            Reporter:
            suganthi.mani@mongodb.com Suganthi Mani
            Votes:
            0 Vote for this issue
            Watchers:
            6 Start watching this issue

              Created:
              Updated:
              Resolved: