Skip to content

Commit f775dfe

Browse files
trondnDavid Haikney
authored andcommitted
MB-32840, MB-32685: Merge vulcan->alice
* couchbase/vulcan: MB-32840: Prevent crash when rotating empty audit log MB-32685: Delay updating RBAC db revision number MB-32661: [BP] Fix expiration decoding with docflags included Change-Id: I9c33b179adccd81bdcc6168cab536adc1582fccd
2 parents 94a16e4 + f3a5ac2 commit f775dfe

File tree

3 files changed

+32
-4
lines changed

3 files changed

+32
-4
lines changed

auditd/src/auditfile.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,7 @@ class AuditFile {
5353
// closing and then re-opening we can just keep open and
5454
// update the open_time.
5555
open_time = auditd_time();
56-
return true;
56+
return false;
5757
}
5858
close_and_rotate_log();
5959
return true;

auditd/tests/auditfile_test.cc

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,28 @@ TEST_F(AuditFileTest, TestFileCreation) {
8282
EXPECT_EQ(1, files.size());
8383
}
8484

85+
/**
86+
* Test that an empty file is properly rotated using ensure_open()
87+
* Seen issues in the past such as MB-32232
88+
*/
89+
TEST_F(AuditFileTest, TestRotateEmptyFile) {
90+
AuditConfig defaultvalue;
91+
config.set_rotate_interval(defaultvalue.get_min_file_rotation_time());
92+
config.set_rotate_size(1024*1024);
93+
94+
AuditFile auditfile;
95+
auditfile.reconfigure(config);
96+
97+
auditfile.ensure_open();
98+
cb_timeofday_timetravel(defaultvalue.get_min_file_rotation_time() + 1);
99+
auditfile.ensure_open();
100+
101+
auditfile.close();
102+
103+
auto files = findFilesWithPrefix(testdir + "/testing");
104+
EXPECT_EQ(0, files.size());
105+
}
106+
85107
/**
86108
* Test that we can create a file, and as time flies by we rotate
87109
* to use the next file

rbac/privilege_database.cc

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,12 @@ namespace rbac {
3434
// Every time we create a new PrivilegeDatabase we bump the generation.
3535
// The PrivilegeContext contains the generation number it was generated
3636
// from so that we can easily detect if the PrivilegeContext is stale.
37-
static std::atomic<uint32_t> generation{0};
37+
// The current_generation contains the version number of the PrivilegeDatabase
38+
// currently in use, and create_generation is the counter being used
39+
// to work around race conditions where multiple threads is trying to
40+
// create and update the RBAC database (last one wins)
41+
static std::atomic<uint32_t> current_generation{0};
42+
static std::atomic<uint32_t> create_generation{0};
3843

3944
// The read write lock needed when you want to build a context
4045
cb::RWLock rwlock;
@@ -128,7 +133,7 @@ PrivilegeMask UserEntry::parsePrivileges(const cJSON* priv, bool buckets) {
128133
}
129134

130135
PrivilegeDatabase::PrivilegeDatabase(const cJSON* json)
131-
: generation(cb::rbac::generation.operator++()) {
136+
: generation(cb::rbac::create_generation.operator++()) {
132137

133138
if (json != nullptr) {
134139
for (auto it = json->child; it != nullptr; it = it->next) {
@@ -172,7 +177,7 @@ std::pair<PrivilegeContext, bool> PrivilegeDatabase::createInitialContext(
172177
}
173178

174179
PrivilegeAccess PrivilegeContext::check(Privilege privilege) const {
175-
if (generation != cb::rbac::generation) {
180+
if (generation != cb::rbac::current_generation) {
176181
return PrivilegeAccess::Stale;
177182
}
178183

@@ -275,6 +280,7 @@ void loadPrivilegeDatabase(const std::string& filename) {
275280
// Handle race conditions
276281
if (db->generation < database->generation) {
277282
db.swap(database);
283+
current_generation = db->generation;
278284
}
279285
}
280286

0 commit comments

Comments
 (0)