示例#1
0
        public unsafe void RavenDB_15975()
        {
            using (var options = StorageEnvironmentOptions.ForPath(DataDir))
            {
                options.Encryption.MasterKey = Sodium.GenerateRandomBuffer((int)Sodium.crypto_aead_xchacha20poly1305_ietf_keybytes());

                using (var innerPager = LinuxTestUtils.GetNewPager(options, DataDir, "Raven.Voron"))
                {
                    AbstractPager cryptoPager;
                    using (cryptoPager = new CryptoPager(innerPager))
                    {
                        using (var tx = new TempPagerTransaction(isWriteTransaction: true))
                        {
                            var overflowSize = 4 * Constants.Storage.PageSize + 100;

                            cryptoPager.EnsureContinuous(26, 5);
                            var pagePointer = cryptoPager.AcquirePagePointerForNewPage(tx, 26, 5);

                            var header = (PageHeader *)pagePointer;
                            header->PageNumber   = 26;
                            header->Flags        = PageFlags.Overflow;
                            header->OverflowSize = overflowSize;

                            Memory.Set(pagePointer + PageHeader.SizeOf, (byte)'X', overflowSize);
                        }


                        using (var tx = new TempPagerTransaction())
                        {
                            var pagePointer = cryptoPager.AcquirePagePointer(tx, 26);

                            // Making sure that the data was decrypted and still holds those 'X' chars
                            Assert.True(pagePointer[PageHeader.SizeOf] == 'X');
                            Assert.True(pagePointer[666] == 'X');
                            Assert.True(pagePointer[1039] == 'X');
                        }
                    }
                }
            }
        }
示例#2
0
        public unsafe void WriteAndReadPageUsingCryptoPager()
        {
            using (var options = StorageEnvironmentOptions.ForPath(DataDir))
            {
                options.Encryption.MasterKey = Sodium.GenerateRandomBuffer((int)Sodium.crypto_aead_xchacha20poly1305_ietf_keybytes());

                using (var innerPager = LinuxTestUtils.GetNewPager(options, DataDir, "Raven.Voron"))
                {
                    AbstractPager cryptoPager;
                    using (cryptoPager = new CryptoPager(innerPager))
                    {
                        using (var tx = new TempPagerTransaction(isWriteTransaction: true))
                        {
                            cryptoPager.EnsureContinuous(17, 1); // We're gonna try to read and write to page 17
                            var pagePointer = cryptoPager.AcquirePagePointerForNewPage(tx, 17, 1);

                            var header = (PageHeader *)pagePointer;
                            header->PageNumber = 17;
                            header->Flags      = PageFlags.Single | PageFlags.FixedSizeTreePage;

                            Memory.Set(pagePointer + PageHeader.SizeOf, (byte)'X', Constants.Storage.PageSize - PageHeader.SizeOf);
                        }

                        using (var tx = new TempPagerTransaction())
                        {
                            var pagePointer = cryptoPager.AcquirePagePointer(tx, 17);

                            // Making sure that the data was decrypted and still holds those 'X' chars
                            Assert.True(pagePointer[PageHeader.SizeOf] == 'X');
                            Assert.True(pagePointer[666] == 'X');
                            Assert.True(pagePointer[1039] == 'X');
                        }
                    }
                }
            }
        }
示例#3
0
        public unsafe void ValidatePageChecksumShouldDetectDataCorruption()
        {
            // Create some random data
            var treeNames = new List <string>();

            var random = new Random();

            var value1 = new byte[random.Next(1024 * 1024 * 2)];
            var value2 = new byte[random.Next(1024 * 1024 * 2)];

            random.NextBytes(value1);
            random.NextBytes(value2);

            const int treeCount   = 5;
            const int recordCount = 6;

            using (var env = new StorageEnvironment(StorageEnvironmentOptions.ForPath(DataDir)))
            {
                env.Options.ManualFlushing = true;

                for (int i = 0; i < treeCount; i++)
                {
                    using (var tx = env.WriteTransaction())
                    {
                        string name = "tree/" + i;
                        treeNames.Add(name);

                        var tree = tx.CreateTree(name);

                        for (int j = 0; j < recordCount; j++)
                        {
                            tree.Add(string.Format("{0}/items/{1}", name, j), j % 2 == 0 ? value1 : value2);
                        }

                        tx.Commit();
                    }
                }
                env.FlushLogToDataFile();
            }

            // Lets corrupt something
            using (var options = StorageEnvironmentOptions.ForPath(DataDir))
                using (var pager = LinuxTestUtils.GetNewPager(options, DataDir, "Raven.Voron"))
                    using (var tempTX = new TempPagerTransaction())
                    {
                        var writePtr = pager.AcquirePagePointer(tempTX, 2) + PageHeader.SizeOf + 43; // just some random place on page #2
                        for (byte i = 0; i < 8; i++)
                        {
                            writePtr[i] = i;
                        }
                    }

            // Now lets try to read it all back and hope we get an exception
            try
            {
                using (var env = new StorageEnvironment(StorageEnvironmentOptions.ForPath(DataDir)))
                {
                    using (var tx = env.ReadTransaction())
                    {
                        foreach (var treeName in treeNames)
                        {
                            var tree = tx.CreateTree(treeName);

                            for (int i = 0; i < recordCount; i++)
                            {
                                var readResult = tree.Read(string.Format("{0}/items/{1}", treeName, i));

                                Assert.NotNull(readResult);

                                if (i % 2 == 0)
                                {
                                    var readBytes = new byte[value1.Length];
                                    readResult.Reader.Read(readBytes, 0, readBytes.Length);
                                }
                                else
                                {
                                    var readBytes = new byte[value2.Length];
                                    readResult.Reader.Read(readBytes, 0, readBytes.Length);
                                }
                            }
                        }
                    }
                }
            }
            catch (Exception e)
            {
                Assert.True(e is InvalidOperationException || e is InvalidDataException);
            }
        }