summaryrefslogtreecommitdiff
path: root/src/mongo/db/ops
diff options
context:
space:
mode:
authorShreyas Kalyan <shreyas.kalyan@mongodb.com>2022-05-26 14:44:55 -0500
committerEvergreen Agent <no-reply@evergreen.mongodb.com>2022-06-17 22:40:09 +0000
commitcc2a4dffbaed59cf50a0dec5b23ec124622f1240 (patch)
tree40c80791810744bcde9173ad3eb36f4c863faa39 /src/mongo/db/ops
parent4817d3fda9bc9a4594beec01ba2244523d695e87 (diff)
downloadmongo-cc2a4dffbaed59cf50a0dec5b23ec124622f1240.tar.gz
SERVER-66662 Block insertion into __safeContent__
Diffstat (limited to 'src/mongo/db/ops')
-rw-r--r--src/mongo/db/ops/write_ops_exec.cpp58
-rw-r--r--src/mongo/db/ops/write_ops_exec.h3
2 files changed, 55 insertions, 6 deletions
diff --git a/src/mongo/db/ops/write_ops_exec.cpp b/src/mongo/db/ops/write_ops_exec.cpp
index ee703965b72..33d1cd596b8 100644
--- a/src/mongo/db/ops/write_ops_exec.cpp
+++ b/src/mongo/db/ops/write_ops_exec.cpp
@@ -604,11 +604,36 @@ SingleWriteResult makeWriteResultForInsertOrDeleteRetry() {
return res;
}
+
+// Returns the flags that determine the type of document validation we want to
+// perform. First item in the tuple determines whether to bypass document validation altogether,
+// second item determines if _safeContent_ array can be modified in an encrypted collection.
+std::tuple<bool, bool> getDocumentValidationFlags(OperationContext* opCtx,
+ const write_ops::WriteCommandRequestBase& req) {
+ auto& encryptionInfo = req.getEncryptionInformation();
+ const bool fleCrudProcessed = getFleCrudProcessed(opCtx, encryptionInfo);
+ return std::make_tuple(req.getBypassDocumentValidation(), fleCrudProcessed);
+}
} // namespace
+bool getFleCrudProcessed(OperationContext* opCtx,
+ const boost::optional<EncryptionInformation>& encryptionInfo) {
+ if (encryptionInfo && encryptionInfo->getCrudProcessed().value_or(false)) {
+ uassert(6666201,
+ "External users cannot have crudProcessed enabled",
+ AuthorizationSession::get(opCtx->getClient())
+ ->isAuthorizedForActionsOnResource(ResourcePattern::forClusterResource(),
+ ActionType::internal));
+
+ return true;
+ }
+ return false;
+}
+
WriteResult performInserts(OperationContext* opCtx,
const write_ops::InsertCommandRequest& wholeOp,
OperationSource source) {
+
// Insert performs its own retries, so we should only be within a WriteUnitOfWork when run in a
// transaction.
auto txnParticipant = TransactionParticipant::get(opCtx);
@@ -643,8 +668,15 @@ WriteResult performInserts(OperationContext* opCtx,
uassertStatusOK(userAllowedWriteNS(opCtx, wholeOp.getNamespace()));
}
- DisableDocumentSchemaValidationIfTrue docSchemaValidationDisabler(
- opCtx, wholeOp.getWriteCommandRequestBase().getBypassDocumentValidation());
+ const auto [disableDocumentValidation, fleCrudProcessed] =
+ getDocumentValidationFlags(opCtx, wholeOp.getWriteCommandRequestBase());
+
+ DisableDocumentSchemaValidationIfTrue docSchemaValidationDisabler(opCtx,
+ disableDocumentValidation);
+
+ DisableSafeContentValidationIfTrue safeContentValidationDisabler(
+ opCtx, disableDocumentValidation, fleCrudProcessed);
+
LastOpFixer lastOpFixer(opCtx, wholeOp.getNamespace());
WriteResult out;
@@ -1003,8 +1035,15 @@ WriteResult performUpdates(OperationContext* opCtx,
(txnParticipant && opCtx->inMultiDocumentTransaction()));
uassertStatusOK(userAllowedWriteNS(opCtx, ns));
- DisableDocumentSchemaValidationIfTrue docSchemaValidationDisabler(
- opCtx, wholeOp.getWriteCommandRequestBase().getBypassDocumentValidation());
+ const auto [disableDocumentValidation, fleCrudProcessed] =
+ getDocumentValidationFlags(opCtx, wholeOp.getWriteCommandRequestBase());
+
+ DisableDocumentSchemaValidationIfTrue docSchemaValidationDisabler(opCtx,
+ disableDocumentValidation);
+
+ DisableSafeContentValidationIfTrue safeContentValidationDisabler(
+ opCtx, disableDocumentValidation, fleCrudProcessed);
+
LastOpFixer lastOpFixer(opCtx, ns);
bool containsRetry = false;
@@ -1231,8 +1270,15 @@ WriteResult performDeletes(OperationContext* opCtx,
(txnParticipant && opCtx->inMultiDocumentTransaction()));
uassertStatusOK(userAllowedWriteNS(opCtx, ns));
- DisableDocumentSchemaValidationIfTrue docSchemaValidationDisabler(
- opCtx, wholeOp.getWriteCommandRequestBase().getBypassDocumentValidation());
+ const auto [disableDocumentValidation, fleCrudProcessed] =
+ getDocumentValidationFlags(opCtx, wholeOp.getWriteCommandRequestBase());
+
+ DisableDocumentSchemaValidationIfTrue docSchemaValidationDisabler(opCtx,
+ disableDocumentValidation);
+
+ DisableSafeContentValidationIfTrue safeContentValidationDisabler(
+ opCtx, disableDocumentValidation, fleCrudProcessed);
+
LastOpFixer lastOpFixer(opCtx, ns);
bool containsRetry = false;
diff --git a/src/mongo/db/ops/write_ops_exec.h b/src/mongo/db/ops/write_ops_exec.h
index 548a3034713..3550a51c1ce 100644
--- a/src/mongo/db/ops/write_ops_exec.h
+++ b/src/mongo/db/ops/write_ops_exec.h
@@ -64,6 +64,9 @@ struct WriteResult {
bool canContinue = true;
};
+bool getFleCrudProcessed(OperationContext* opCtx,
+ const boost::optional<EncryptionInformation>& encryptionInfo);
+
/**
* Performs a batch of inserts, updates, or deletes.
*