diff --git a/interfaces/kits/js/src/mod_fs/class_watcher/fs_file_watcher.cpp b/interfaces/kits/js/src/mod_fs/class_watcher/fs_file_watcher.cpp index 9f77d49df39c7e271a3d9ca53d0e9a9b9418a648..e411c3e6aed596b896da0e000812516b78d19c25 100644 --- a/interfaces/kits/js/src/mod_fs/class_watcher/fs_file_watcher.cpp +++ b/interfaces/kits/js/src/mod_fs/class_watcher/fs_file_watcher.cpp @@ -202,6 +202,18 @@ void FsFileWatcher::ReadNotifyEvent() while (index < len) { event = reinterpret_cast(buf + index); + if ((len - index) < sizeof(struct inotify_event)) { + HILOGE("out of bounds access, len:%{public}d, index: %{public}d, inotify: %{public}zu", + len, index, sizeof(struct inotify_event)); + break; + } + if (event->len > (static_cast(len - index - sizeof(struct inotify_event)))) { + HILOGE("out of bounds access, index: %{public}d, inotify: %{public}zu, " + "event :%{public}u, len: %{public}d", + index, sizeof(struct inotify_event), + event->len, len); + break; + } NotifyEvent(event); index += sizeof(struct inotify_event) + static_cast(event->len); } diff --git a/interfaces/kits/js/src/mod_fs/properties/ani/access_ani.cpp b/interfaces/kits/js/src/mod_fs/properties/ani/access_ani.cpp index 329e116231db924a7a676180d4d20c25f63f8eca..41052ff71a9b15e57bd6f24f390653572ee451fc 100644 --- a/interfaces/kits/js/src/mod_fs/properties/ani/access_ani.cpp +++ b/interfaces/kits/js/src/mod_fs/properties/ani/access_ani.cpp @@ -102,10 +102,10 @@ ani_boolean AccessAni::AccessSync3( auto flagType = OptToAccessFlagType(flagOpt); FsResult fsRet = FsResult::Error(UNKNOWN_ERR); - if (flagOpt == std::nullopt) { - fsRet = AccessCore::DoAccess(pathStr, modeType); - } else { + if (modeType != std::nullopt && flagType != std::nullopt) { fsRet = AccessCore::DoAccess(pathStr, modeType.value(), flagType.value()); + } else { + fsRet = AccessCore::DoAccess(pathStr, modeType); } if (!fsRet.IsSuccess()) { diff --git a/interfaces/kits/js/src/mod_fs/properties/copy_core.cpp b/interfaces/kits/js/src/mod_fs/properties/copy_core.cpp index 45403ca6d82752fcac6b36e2cf72b2f063305337..ed94402f280ee8997a72f1e4f62a18d8fdfec729 100644 --- a/interfaces/kits/js/src/mod_fs/properties/copy_core.cpp +++ b/interfaces/kits/js/src/mod_fs/properties/copy_core.cpp @@ -666,6 +666,19 @@ void CopyCore::ReadNotifyEvent(std::shared_ptr infos) } while (infos->run && index < len) { event = reinterpret_cast(buf + index); + if ((len - index) < sizeof(struct inotify_event)) { + HILOGE("out of bounds access, len:%{public}d, index: %{public}lld, inotify: %{public}zu", + len, index, sizeof(struct inotify_event)); + break; + } + if (event->len > (static_cast(len - index - sizeof(struct inotify_event)))) { + HILOGE("out of bounds access, index: %{public}lld, inotify: %{public}zu, " + "event :%{public}u, len: %{public}d", + index, sizeof(struct inotify_event), + event->len, len); + break; + } + auto [needContinue, errCode, needSend] = HandleProgress(event, infos, callback); if (!needContinue) { infos->exceptionCode = errCode; diff --git a/interfaces/test/unittest/js/mod_fs/class_watcher/fs_file_watcher_mock_test.cpp b/interfaces/test/unittest/js/mod_fs/class_watcher/fs_file_watcher_mock_test.cpp index fe585ef7104b6cea9541622392a5c523b052b3e3..33fd4b466201f212afff8f1817d0ef231099c34f 100644 --- a/interfaces/test/unittest/js/mod_fs/class_watcher/fs_file_watcher_mock_test.cpp +++ b/interfaces/test/unittest/js/mod_fs/class_watcher/fs_file_watcher_mock_test.cpp @@ -1058,6 +1058,55 @@ HWTEST_F(FsFileWatcherMockTest, FsFileWatcherMockTest_ReadNotifyEvent_003, testi GTEST_LOG_(INFO) << "FsFileWatcherMockTest-end FsFileWatcherMockTest_ReadNotifyEvent_003"; } +/** + * @tc.name: FsFileWatcherMockTest_ReadNotifyEvent_004 + * @tc.desc: Test function of ReadNotifyEvent interface for SUCCESS when len < sizeof(struct inotify_event). + * @tc.size: MEDIUM + * @tc.type: FUNC + * @tc.level Level 1 + */ +HWTEST_F(FsFileWatcherMockTest, FsFileWatcherMockTest_ReadNotifyEvent_004, testing::ext::TestSize.Level1) +{ + GTEST_LOG_(INFO) << "FsFileWatcherMockTest-begin FsFileWatcherMockTest_ReadNotifyEvent_004"; + // Prepare test condition + FsFileWatcher &watcher = FsFileWatcher::GetInstance(); + int32_t len = static_cast(sizeof(struct inotify_event)) - 1; + // Set mock behaviors + auto unistdMock = UnistdMock::GetMock(); + EXPECT_CALL(*unistdMock, read(testing::_, testing::_, testing::_)).Times(1).WillOnce(testing::Return(len)); + // Do testing + watcher.ReadNotifyEvent(); + // Verify results + testing::Mock::VerifyAndClearExpectations(unistdMock.get()); + GTEST_LOG_(INFO) << "FsFileWatcherMockTest-end FsFileWatcherMockTest_ReadNotifyEvent_004"; +} + +/** + * @tc.name: FsFileWatcherMockTest_ReadNotifyEvent_005 + * @tc.desc: Test function of ReadNotifyEvent interface for SUCCESS when event->len exceeds the remaining buffer size. + * @tc.size: MEDIUM + * @tc.type: FUNC + * @tc.level Level 1 + */ +HWTEST_F(FsFileWatcherMockTest, FsFileWatcherMockTest_ReadNotifyEvent_005, testing::ext::TestSize.Level1) +{ + GTEST_LOG_(INFO) << "FsFileWatcherMockTest-begin FsFileWatcherMockTest_ReadNotifyEvent_005"; + // Prepare test condition + FsFileWatcher &watcher = FsFileWatcher::GetInstance(); + char buffer[BUF_SIZE]; + struct inotify_event* event = reinterpret_cast(buffer); + event->len = 10; + int32_t len = sizeof(struct inotify_event) + 5; + // Set mock behaviors + auto unistdMock = UnistdMock::GetMock(); + EXPECT_CALL(*unistdMock, read(testing::_, testing::_, testing::_)).Times(1).WillOnce(testing::Return(len)); + // Do testing + watcher.ReadNotifyEvent(); + // Verify results + testing::Mock::VerifyAndClearExpectations(unistdMock.get()); + GTEST_LOG_(INFO) << "FsFileWatcherMockTest-end FsFileWatcherMockTest_ReadNotifyEvent_005"; +} + /** * @tc.name: FsFileWatcherMockTest_NotifyEvent_001 * @tc.desc: Test function of FsFileWatcher::NotifyEvent interface for SUCCESS when valid event without filename. diff --git a/interfaces/test/unittest/js/mod_fs/properties/copy_core_mock_test.cpp b/interfaces/test/unittest/js/mod_fs/properties/copy_core_mock_test.cpp index 6e832264aaceae17bf33a0678fd5dbe2c7647f43..d7fe0bc18956aed83b2e4a07b7c190e3fca4fa27 100644 --- a/interfaces/test/unittest/js/mod_fs/properties/copy_core_mock_test.cpp +++ b/interfaces/test/unittest/js/mod_fs/properties/copy_core_mock_test.cpp @@ -48,6 +48,7 @@ public: private: static constexpr mode_t permission0755 = 0755; static constexpr mode_t permission0644 = 0644; + static constexpr int32_t bufSize = 1024; }; const string CopyCoreMockTest::testDir = "/data/test"; @@ -403,6 +404,61 @@ HWTEST_F(CopyCoreMockTest, CopyCoreMockTest_ReadNotifyEvent_003, testing::ext::T GTEST_LOG_(INFO) << "CopyCoreMockTest-end CopyCoreMockTest_ReadNotifyEvent_003"; } +/** + * @tc.name: CopyCoreMockTest_ReadNotifyEvent_004 + * @tc.desc: Test function of ReadNotifyEvent interface for SUCCESS when len < sizeof(struct inotify_event). + * @tc.size: SMALL + * @tc.type: FUNC + * @tc.level Level 1 + */ +HWTEST_F(CopyCoreMockTest, CopyCoreMockTest_ReadNotifyEvent_004, testing::ext::TestSize.Level1) +{ + GTEST_LOG_(INFO) << "CopyCoreMockTest-begin CopyCoreMockTest_ReadNotifyEvent_004"; + // Prepare test condition + auto infos = make_shared(); + infos->run = true; + auto callback = CopyCore::RegisterListener(infos); + int len = static_cast(sizeof(struct inotify_event)) - 1; + // Set mock behaviors + auto unistdMock = UnistdMock::GetMock(); + EXPECT_CALL(*unistdMock, read(testing::_, testing::_, testing::_)).Times(1).WillOnce(testing::Return(len)); + // Do testing + CopyCore::ReadNotifyEvent(infos); + // Verify results + EXPECT_NE(callback, nullptr); + testing::Mock::VerifyAndClearExpectations(unistdMock.get()); + GTEST_LOG_(INFO) << "CopyCoreMockTest-end CopyCoreMockTest_ReadNotifyEvent_004"; +} + +/** + * @tc.name: CopyCoreMockTest_ReadNotifyEvent_005 + * @tc.desc: Test function of ReadNotifyEvent interface for SUCCESS when event->len exceeds the remaining buffer size. + * @tc.size: SMALL + * @tc.type: FUNC + * @tc.level Level 1 + */ +HWTEST_F(CopyCoreMockTest, CopyCoreMockTest_ReadNotifyEvent_005, testing::ext::TestSize.Level1) +{ + GTEST_LOG_(INFO) << "CopyCoreMockTest-begin CopyCoreMockTest_ReadNotifyEvent_005"; + // Prepare test condition + auto infos = make_shared(); + infos->run = true; + auto callback = CopyCore::RegisterListener(infos); + char buffer[bufSize]; + struct inotify_event* event = reinterpret_cast(buffer); + event->len = 10; + int len = sizeof(struct inotify_event) + 5; + // Set mock behaviors + auto unistdMock = UnistdMock::GetMock(); + EXPECT_CALL(*unistdMock, read(testing::_, testing::_, testing::_)).Times(1).WillOnce(testing::Return(len)); + // Do testing + CopyCore::ReadNotifyEvent(infos); + // Verify results + EXPECT_NE(callback, nullptr); + testing::Mock::VerifyAndClearExpectations(unistdMock.get()); + GTEST_LOG_(INFO) << "CopyCoreMockTest-end CopyCoreMockTest_ReadNotifyEvent_005"; +} + /** * @tc.name: CopyCoreMockTest_ReadNotifyEventLocked_001 * @tc.desc: Test ReadNotifyEventLocked when closed is false.