Skip to content

Commit fbb832f

Browse files
RafaelGSSaduh95
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 978ad84 commit fbb832f

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
@@ -235,15 +235,25 @@ void FSPermission::RebuildTree(PermissionScope scope) {
235235

236236
void FSPermission::GrantAccess(PermissionScope perm, const std::string& res) {
237237
const std::string path = WildcardIfDir(res);
238-
if (perm == PermissionScope::kFileSystemRead &&
239-
!granted_in_fs_.Lookup(path)) {
240-
granted_in_fs_.Insert(path);
241-
granted_paths_in_.push_back(path);
238+
// Track every explicit grant, even when already covered by another one,
239+
// so that it still applies if the covering grant is dropped later.
240+
if (perm == PermissionScope::kFileSystemRead) {
241+
if (std::find(granted_paths_in_.begin(), granted_paths_in_.end(), path) ==
242+
granted_paths_in_.end()) {
243+
granted_paths_in_.push_back(path);
244+
}
245+
if (!granted_in_fs_.Lookup(path)) {
246+
granted_in_fs_.Insert(path);
247+
}
242248
deny_all_in_ = false;
243-
} else if (perm == PermissionScope::kFileSystemWrite &&
244-
!granted_out_fs_.Lookup(path)) {
245-
granted_out_fs_.Insert(path);
246-
granted_paths_out_.push_back(path);
249+
} else if (perm == PermissionScope::kFileSystemWrite) {
250+
if (std::find(granted_paths_out_.begin(), granted_paths_out_.end(), path) ==
251+
granted_paths_out_.end()) {
252+
granted_paths_out_.push_back(path);
253+
}
254+
if (!granted_out_fs_.Lookup(path)) {
255+
granted_out_fs_.Insert(path);
256+
}
247257
deny_all_out_ = false;
248258
}
249259
}

‎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)