Skip to content

Commit 51f66f0

Browse files
RafaelGSSrichardlau
authored andcommitted
permission: keep explicit fs grants when dropping a covering directory
Signed-off-by: RafaelGSS <rafael.nunu@hotmail.com> PR-URL: #66556 Reviewed-By: Ulises Gascón <ulisesgascongonzalez@gmail.com>
1 parent 3d691ab commit 51f66f0

2 files changed

Lines changed: 52 additions & 8 deletions

File tree

‎src/permission/fs_permission.cc‎

Lines changed: 18 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -216,15 +216,25 @@ void FSPermission::RebuildTree(PermissionScope scope) {
216216

217217
void FSPermission::GrantAccess(PermissionScope perm, const std::string& res) {
218218
const std::string path = WildcardIfDir(res);
219-
if (perm == PermissionScope::kFileSystemRead &&
220-
!granted_in_fs_.Lookup(path)) {
221-
granted_in_fs_.Insert(path);
222-
granted_paths_in_.push_back(path);
219+
// Track every explicit grant, even when already covered by another one,
220+
// so that it still applies if the covering grant is dropped later.
221+
if (perm == PermissionScope::kFileSystemRead) {
222+
if (std::find(granted_paths_in_.begin(), granted_paths_in_.end(), path) ==
223+
granted_paths_in_.end()) {
224+
granted_paths_in_.push_back(path);
225+
}
226+
if (!granted_in_fs_.Lookup(path)) {
227+
granted_in_fs_.Insert(path);
228+
}
223229
deny_all_in_ = false;
224-
} else if (perm == PermissionScope::kFileSystemWrite &&
225-
!granted_out_fs_.Lookup(path)) {
226-
granted_out_fs_.Insert(path);
227-
granted_paths_out_.push_back(path);
230+
} else if (perm == PermissionScope::kFileSystemWrite) {
231+
if (std::find(granted_paths_out_.begin(), granted_paths_out_.end(), path) ==
232+
granted_paths_out_.end()) {
233+
granted_paths_out_.push_back(path);
234+
}
235+
if (!granted_out_fs_.Lookup(path)) {
236+
granted_out_fs_.Insert(path);
237+
}
228238
deny_all_out_ = false;
229239
}
230240
}

‎test/parallel/test-permission-drop-fs-granted-path.js‎

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -133,6 +133,40 @@ fs.writeFileSync(path.join(dir, 'item2.txt'), 'bbb');
133133
assert.strictEqual(child.status, 0);
134134
}
135135

136+
// Grant a directory and a file inside it separately, drop the directory
137+
// the explicit file grant still applies regardless of the flag order
138+
for (const files of [
139+
[dir, path.join(dir, 'item1.txt')],
140+
[path.join(dir, 'item1.txt'), dir],
141+
]) {
142+
const child = spawnSync(process.execPath, [
143+
'--permission',
144+
...files.map((file) => `--allow-fs-read=${file}`),
145+
...files.map((file) => `--allow-fs-write=${file}`),
146+
'-e',
147+
`
148+
const assert = require('assert');
149+
const fs = require('fs');
150+
const dir = ${JSON.stringify(dir)};
151+
152+
for (const scope of ['fs.read', 'fs.write']) {
153+
assert.ok(process.permission.has(scope, dir + '/item1.txt'));
154+
assert.ok(process.permission.has(scope, dir + '/item2.txt'));
155+
156+
process.permission.drop(scope, dir);
157+
158+
assert.ok(process.permission.has(scope, dir + '/item1.txt'));
159+
assert.ok(!process.permission.has(scope, dir + '/item2.txt'));
160+
}
161+
assert.strictEqual(fs.readFileSync(dir + '/item1.txt', 'utf8'), 'aaa');
162+
`,
163+
]);
164+
if (child.status !== 0) {
165+
console.error('Case 5 stderr:', child.stderr?.toString());
166+
}
167+
assert.strictEqual(child.status, 0);
168+
}
169+
136170
// Drop entire scope without reference - revokes everything
137171
{
138172
const child = spawnSync(process.execPath, [

0 commit comments

Comments
 (0)