wwpackage: validate cleanup directory after open
This commit is contained in:
@@ -440,10 +440,24 @@ fn pkgmakedir(path: str) bool = {
|
|||||||
return os.mkdir(path, 448i32) == 0;
|
return os.mkdir(path, 448i32) == 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// The coordinator removes only its minted temp root; validating the opened
|
||||||
|
// inode keeps a replaced path from carrying cleanup outside that ownership.
|
||||||
fn pkgremoveall(path: str) bool = {
|
fn pkgremoveall(path: str) bool = {
|
||||||
if (!pkgisdir(path)) { return os.remove(path) == 0; };
|
let st: os.filestat;
|
||||||
|
match (os.lstat(&st, path)) {
|
||||||
|
case void => void;
|
||||||
|
case let e: os.oserror => return false;
|
||||||
|
};
|
||||||
|
if (!pkgmodeis(st.mode, os.mode.DIR)) { return os.remove(path) == 0; };
|
||||||
let fd: i32 = os.open(path, os.flag.RDONLY, 0i32);
|
let fd: i32 = os.open(path, os.flag.RDONLY, 0i32);
|
||||||
if (fd < 0) { return false; };
|
if (fd < 0) { return false; };
|
||||||
|
let opened: os.filestat;
|
||||||
|
match (os.fstat(&opened, fd)) {
|
||||||
|
case void => void;
|
||||||
|
case let e: os.oserror => { os.close(fd); return false; };
|
||||||
|
};
|
||||||
|
if (!pkgmodeis(opened.mode, os.mode.DIR)
|
||||||
|
|| opened.inode != st.inode) { os.close(fd); return false; };
|
||||||
let ok: bool = true;
|
let ok: bool = true;
|
||||||
let buf: []u8 = alloc([], 8192u64)!;
|
let buf: []u8 = alloc([], 8192u64)!;
|
||||||
buf.len = 8192;
|
buf.len = 8192;
|
||||||
@@ -476,7 +490,7 @@ fn pkgremoveall(path: str) bool = {
|
|||||||
n = os.getdents64(fd, buf.ptr, 8192u64);
|
n = os.getdents64(fd, buf.ptr, 8192u64);
|
||||||
};
|
};
|
||||||
if (n < 0i64) { ok = false; };
|
if (n < 0i64) { ok = false; };
|
||||||
os.close(fd);
|
if (os.close(fd) != 0) { ok = false; };
|
||||||
if (os.rmdir(path) != 0) { ok = false; };
|
if (os.rmdir(path) != 0) { ok = false; };
|
||||||
return ok;
|
return ok;
|
||||||
};
|
};
|
||||||
|
|||||||
Reference in New Issue
Block a user