commit a0935155f8491fc179f94e8b9e2f571f3dae8c6d
parent aa5b18e25764291a1b23976fad0bb49182daba75
Author: Jan Pobrislo <ccx@te2000.cz>
Date: Fri, 12 Dec 2025 01:38:10 +0000
normalize pivot_root paths, use put_old suffix only for umount
Diffstat:
1 file changed, 31 insertions(+), 8 deletions(-)
diff --git a/src/lns-lockdown_main.c b/src/lns-lockdown_main.c
@@ -61,15 +61,28 @@ int stralloc_catenv0(stralloc *sa, char const * env_name) {
/*** individual steps of dropping into sandbox ***/
void pivot_and_umount(
- char const *const old_place_for_new_root,
- char const *const new_place_for_old_root,
+ char const *const new_root,
+ char const *const put_old,
struct unexport_s *const unex
) {
+ size_t newroot_len = 0;
+ for(size_t char_n=0; new_root[char_n]; char_n++) {
+ if(new_root[char_n] == 0) {
+ newroot_len = char_n;
+ break;
+ }
+ if(new_root[char_n] != put_old[char_n]) {
+ strerr_dief1x(100, "first path is not prefix of second path");
+ }
+ if(char_n > PATH_MAX) {
+ strerr_dief1x(111, "realpath() returned invalid string");
+ }
+ }
size_t mtp_count, mtp_n;
- int oldroot_len = strlen(new_place_for_old_root);
+ size_t oldroot_len = strlen(put_old) - newroot_len;
stralloc sa_env = STRALLOC_ZERO;
stralloc sa_mtp = STRALLOC_ZERO;
- if (!stralloc_catb(&sa_mtp, new_place_for_old_root, oldroot_len)) {
+ if (!stralloc_catb(&sa_mtp, &put_old[newroot_len], oldroot_len)) {
strerr_diefu1sys(111, "store mount path");
}
if (!size_scan(getenv_dienotset("NS_MTP_COUNT"), &mtp_count)) {
@@ -81,10 +94,10 @@ void pivot_and_umount(
unex->count++;
/* pivot_root */
- if (chdir(old_place_for_new_root) < 0) {
- strerr_diefu2sys(111, "chdir to ", old_place_for_new_root) ;
+ if (chdir(new_root) < 0) {
+ strerr_diefu2sys(111, "chdir to ", new_root) ;
}
- if (syscall_pivot_root(".", new_place_for_old_root) < 0) {
+ if (syscall_pivot_root(".", put_old) < 0) {
strerr_diefu1sys(111, "pivot_root") ;
}
if (chroot(".") < 0) {
@@ -264,7 +277,17 @@ int main (int argc, char const *const *argv) {
if (argc < 3) {
dieusage();
}
- pivot_and_umount(argv[0], argv[1], &unex);
+ char *new_root = realpath(argv[0], NULL);
+ if (new_root == NULL) {
+ strerr_diefu1sys(111, "to resolve first path");
+ }
+ char *put_old = realpath(argv[1], NULL);
+ if (new_root == NULL) {
+ strerr_diefu1sys(111, "to resolve first path");
+ }
+ pivot_and_umount(new_root, put_old, &unex);
+ free(new_root);
+ free(put_old);
if (drop_privs) {
drop(&privs);
} else if (seccomp_fd >= 0) {