mirror of
https://github.com/reactos/reactos.git
synced 2025-06-10 04:14:53 +00:00
Fixed a potential cause of registry corruption in NtSetValueKey():
- Mark all modified cells dirty. - Allocate value cell after value list cell has been created or resized. svn path=/trunk/; revision=7643
This commit is contained in:
parent
c6f4c292e9
commit
9dfb5ee1cc
3 changed files with 40 additions and 33 deletions
|
@ -502,15 +502,16 @@ CmiGetValueFromKeyByIndex(IN PREGISTRY_HIVE RegistryHive,
|
||||||
OUT PVALUE_CELL *ValueCell);
|
OUT PVALUE_CELL *ValueCell);
|
||||||
|
|
||||||
NTSTATUS
|
NTSTATUS
|
||||||
CmiAddValueToKey(IN PREGISTRY_HIVE RegistryHive,
|
CmiAddValueToKey(IN PREGISTRY_HIVE RegistryHive,
|
||||||
IN PKEY_CELL KeyCell,
|
IN PKEY_CELL KeyCell,
|
||||||
IN PUNICODE_STRING ValueName,
|
IN BLOCK_OFFSET KeyCellOffset,
|
||||||
OUT PVALUE_CELL *pValueCell,
|
IN PUNICODE_STRING ValueName,
|
||||||
OUT BLOCK_OFFSET *pVBOffset);
|
OUT PVALUE_CELL *pValueCell,
|
||||||
|
OUT BLOCK_OFFSET *pValueCellOffset);
|
||||||
|
|
||||||
NTSTATUS
|
NTSTATUS
|
||||||
CmiDeleteValueFromKey(IN PREGISTRY_HIVE RegistryHive,
|
CmiDeleteValueFromKey(IN PREGISTRY_HIVE RegistryHive,
|
||||||
IN PKEY_CELL KeyCell,
|
IN PKEY_CELL KeyCell,
|
||||||
IN BLOCK_OFFSET KeyCellOffset,
|
IN BLOCK_OFFSET KeyCellOffset,
|
||||||
IN PUNICODE_STRING ValueName);
|
IN PUNICODE_STRING ValueName);
|
||||||
|
|
||||||
|
|
|
@ -1276,13 +1276,10 @@ NtSetValueKey(IN HANDLE KeyHandle,
|
||||||
DPRINT("Allocate new value cell\n");
|
DPRINT("Allocate new value cell\n");
|
||||||
Status = CmiAddValueToKey(RegistryHive,
|
Status = CmiAddValueToKey(RegistryHive,
|
||||||
KeyCell,
|
KeyCell,
|
||||||
|
KeyObject->KeyCellOffset,
|
||||||
ValueName,
|
ValueName,
|
||||||
&ValueCell,
|
&ValueCell,
|
||||||
&ValueCellOffset);
|
&ValueCellOffset);
|
||||||
if (NT_SUCCESS(Status))
|
|
||||||
{
|
|
||||||
CmiMarkBlockDirty(RegistryHive, ValueCellOffset);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!NT_SUCCESS(Status))
|
if (!NT_SUCCESS(Status))
|
||||||
|
|
|
@ -2818,31 +2818,23 @@ CmiGetValueFromKeyByIndex(IN PREGISTRY_HIVE RegistryHive,
|
||||||
NTSTATUS
|
NTSTATUS
|
||||||
CmiAddValueToKey(IN PREGISTRY_HIVE RegistryHive,
|
CmiAddValueToKey(IN PREGISTRY_HIVE RegistryHive,
|
||||||
IN PKEY_CELL KeyCell,
|
IN PKEY_CELL KeyCell,
|
||||||
|
IN BLOCK_OFFSET KeyCellOffset,
|
||||||
IN PUNICODE_STRING ValueName,
|
IN PUNICODE_STRING ValueName,
|
||||||
OUT PVALUE_CELL *pValueCell,
|
OUT PVALUE_CELL *pValueCell,
|
||||||
OUT BLOCK_OFFSET *pVBOffset)
|
OUT BLOCK_OFFSET *pValueCellOffset)
|
||||||
{
|
{
|
||||||
PVALUE_LIST_CELL NewValueListCell;
|
PVALUE_LIST_CELL NewValueListCell;
|
||||||
PVALUE_LIST_CELL ValueListCell;
|
PVALUE_LIST_CELL ValueListCell;
|
||||||
PVALUE_CELL NewValueCell;
|
PVALUE_CELL NewValueCell;
|
||||||
BLOCK_OFFSET VLBOffset;
|
BLOCK_OFFSET NewValueListCellOffset;
|
||||||
BLOCK_OFFSET VBOffset;
|
BLOCK_OFFSET ValueListCellOffset;
|
||||||
|
BLOCK_OFFSET NewValueCellOffset;
|
||||||
ULONG CellSize;
|
ULONG CellSize;
|
||||||
NTSTATUS Status;
|
NTSTATUS Status;
|
||||||
|
|
||||||
Status = CmiAllocateValueCell(RegistryHive,
|
|
||||||
&NewValueCell,
|
|
||||||
&VBOffset,
|
|
||||||
ValueName);
|
|
||||||
if (!NT_SUCCESS(Status))
|
|
||||||
{
|
|
||||||
return Status;
|
|
||||||
}
|
|
||||||
|
|
||||||
DPRINT("KeyCell->ValuesOffset %lu\n", (ULONG)KeyCell->ValueListOffset);
|
DPRINT("KeyCell->ValuesOffset %lu\n", (ULONG)KeyCell->ValueListOffset);
|
||||||
|
|
||||||
ValueListCell = CmiGetCell (RegistryHive, KeyCell->ValueListOffset, NULL);
|
ValueListCell = CmiGetCell (RegistryHive, KeyCell->ValueListOffset, NULL);
|
||||||
|
|
||||||
if (ValueListCell == NULL)
|
if (ValueListCell == NULL)
|
||||||
{
|
{
|
||||||
CellSize = sizeof(VALUE_LIST_CELL) +
|
CellSize = sizeof(VALUE_LIST_CELL) +
|
||||||
|
@ -2850,14 +2842,15 @@ CmiAddValueToKey(IN PREGISTRY_HIVE RegistryHive,
|
||||||
Status = CmiAllocateCell (RegistryHive,
|
Status = CmiAllocateCell (RegistryHive,
|
||||||
CellSize,
|
CellSize,
|
||||||
(PVOID) &ValueListCell,
|
(PVOID) &ValueListCell,
|
||||||
&VLBOffset);
|
&ValueListCellOffset);
|
||||||
|
|
||||||
if (!NT_SUCCESS(Status))
|
if (!NT_SUCCESS(Status))
|
||||||
{
|
{
|
||||||
CmiDestroyValueCell(RegistryHive, NewValueCell, VBOffset);
|
|
||||||
return Status;
|
return Status;
|
||||||
}
|
}
|
||||||
KeyCell->ValueListOffset = VLBOffset;
|
|
||||||
|
KeyCell->ValueListOffset = ValueListCellOffset;
|
||||||
|
CmiMarkBlockDirty(RegistryHive, KeyCellOffset);
|
||||||
|
CmiMarkBlockDirty(RegistryHive, ValueListCellOffset);
|
||||||
}
|
}
|
||||||
else if (KeyCell->NumberOfValues >=
|
else if (KeyCell->NumberOfValues >=
|
||||||
(((ULONG)ABS_VALUE(ValueListCell->CellSize) - sizeof(VALUE_LIST_CELL)) / sizeof(BLOCK_OFFSET)))
|
(((ULONG)ABS_VALUE(ValueListCell->CellSize) - sizeof(VALUE_LIST_CELL)) / sizeof(BLOCK_OFFSET)))
|
||||||
|
@ -2867,10 +2860,9 @@ CmiAddValueToKey(IN PREGISTRY_HIVE RegistryHive,
|
||||||
Status = CmiAllocateCell (RegistryHive,
|
Status = CmiAllocateCell (RegistryHive,
|
||||||
CellSize,
|
CellSize,
|
||||||
(PVOID) &NewValueListCell,
|
(PVOID) &NewValueListCell,
|
||||||
&VLBOffset);
|
&NewValueListCellOffset);
|
||||||
if (!NT_SUCCESS(Status))
|
if (!NT_SUCCESS(Status))
|
||||||
{
|
{
|
||||||
CmiDestroyValueCell(RegistryHive, NewValueCell, VBOffset);
|
|
||||||
return Status;
|
return Status;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2878,8 +2870,12 @@ CmiAddValueToKey(IN PREGISTRY_HIVE RegistryHive,
|
||||||
&ValueListCell->ValueOffset[0],
|
&ValueListCell->ValueOffset[0],
|
||||||
sizeof(BLOCK_OFFSET) * KeyCell->NumberOfValues);
|
sizeof(BLOCK_OFFSET) * KeyCell->NumberOfValues);
|
||||||
CmiDestroyCell (RegistryHive, ValueListCell, KeyCell->ValueListOffset);
|
CmiDestroyCell (RegistryHive, ValueListCell, KeyCell->ValueListOffset);
|
||||||
KeyCell->ValueListOffset = VLBOffset;
|
CmiMarkBlockDirty (RegistryHive, KeyCell->ValueListOffset);
|
||||||
|
|
||||||
|
KeyCell->ValueListOffset = NewValueListCellOffset;
|
||||||
ValueListCell = NewValueListCell;
|
ValueListCell = NewValueListCell;
|
||||||
|
CmiMarkBlockDirty (RegistryHive, KeyCellOffset);
|
||||||
|
CmiMarkBlockDirty (RegistryHive, NewValueListCellOffset);
|
||||||
}
|
}
|
||||||
|
|
||||||
DPRINT("KeyCell->NumberOfValues %lu, ValueListCell->CellSize %lu (%lu %lx)\n",
|
DPRINT("KeyCell->NumberOfValues %lu, ValueListCell->CellSize %lu (%lu %lx)\n",
|
||||||
|
@ -2888,11 +2884,24 @@ CmiAddValueToKey(IN PREGISTRY_HIVE RegistryHive,
|
||||||
((ULONG)ABS_VALUE(ValueListCell->CellSize) - sizeof(VALUE_LIST_CELL)) / sizeof(BLOCK_OFFSET),
|
((ULONG)ABS_VALUE(ValueListCell->CellSize) - sizeof(VALUE_LIST_CELL)) / sizeof(BLOCK_OFFSET),
|
||||||
((ULONG)ABS_VALUE(ValueListCell->CellSize) - sizeof(VALUE_LIST_CELL)) / sizeof(BLOCK_OFFSET));
|
((ULONG)ABS_VALUE(ValueListCell->CellSize) - sizeof(VALUE_LIST_CELL)) / sizeof(BLOCK_OFFSET));
|
||||||
|
|
||||||
ValueListCell->ValueOffset[KeyCell->NumberOfValues] = VBOffset;
|
Status = CmiAllocateValueCell(RegistryHive,
|
||||||
|
&NewValueCell,
|
||||||
|
&NewValueCellOffset,
|
||||||
|
ValueName);
|
||||||
|
if (!NT_SUCCESS(Status))
|
||||||
|
{
|
||||||
|
return Status;
|
||||||
|
}
|
||||||
|
|
||||||
|
ValueListCell->ValueOffset[KeyCell->NumberOfValues] = NewValueCellOffset;
|
||||||
KeyCell->NumberOfValues++;
|
KeyCell->NumberOfValues++;
|
||||||
|
|
||||||
|
CmiMarkBlockDirty(RegistryHive, KeyCellOffset);
|
||||||
|
CmiMarkBlockDirty(RegistryHive, KeyCell->ValueListOffset);
|
||||||
|
CmiMarkBlockDirty(RegistryHive, NewValueCellOffset);
|
||||||
|
|
||||||
*pValueCell = NewValueCell;
|
*pValueCell = NewValueCell;
|
||||||
*pVBOffset = VBOffset;
|
*pValueCellOffset = NewValueCellOffset;
|
||||||
|
|
||||||
return STATUS_SUCCESS;
|
return STATUS_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue