From: Darrick J. Wong <djwong@xxxxxxxxxx> In the next patch, we'll tighten up the security on the xfs_scrub service so that it can't escape. However, sanboxing the service involves making the host filesystem as inaccessible as possible, with the filesystem to scrub bind mounted onto a known location within the sandbox. Hence we need one path for reporting and a new -A argument to tell scrub what it should actually be trying to open. Signed-off-by: Darrick J. Wong <djwong@xxxxxxxxxx> --- doc/README-env-vars.txt | 2 ++ scrub/phase1.c | 4 ++-- scrub/vfs.c | 2 +- scrub/xfs_scrub.c | 9 +++++++-- scrub/xfs_scrub.h | 5 ++++- 5 files changed, 16 insertions(+), 6 deletions(-) diff --git a/doc/README-env-vars.txt b/doc/README-env-vars.txt index eec59a82513..d7984df8202 100644 --- a/doc/README-env-vars.txt +++ b/doc/README-env-vars.txt @@ -24,3 +24,5 @@ XFS_SCRUB_THREADS -- start exactly this number of threads Available even in non-debug mode: SERVICE_MODE -- compress all error codes to 1 for LSB service action compliance +SERVICE_MOUNTPOINT -- actual path to open for issuing kernel + scrub calls diff --git a/scrub/phase1.c b/scrub/phase1.c index faa554f1e1e..80fd0c6e27c 100644 --- a/scrub/phase1.c +++ b/scrub/phase1.c @@ -146,7 +146,7 @@ phase1_func( * CAP_SYS_ADMIN, which we probably need to do anything fancy * with the (XFS driver) kernel. */ - error = -xfd_open(&ctx->mnt, ctx->mntpoint, + error = -xfd_open(&ctx->mnt, ctx->actual_mntpoint, O_RDONLY | O_NOATIME | O_DIRECTORY); if (error) { if (error == EPERM) @@ -199,7 +199,7 @@ _("Not an XFS filesystem.")); return error; } - error = path_to_fshandle(ctx->mntpoint, &ctx->fshandle, + error = path_to_fshandle(ctx->actual_mntpoint, &ctx->fshandle, &ctx->fshandle_len); if (error) { str_errno(ctx, _("getting fshandle")); diff --git a/scrub/vfs.c b/scrub/vfs.c index 85ee2694b00..c64c6c41105 100644 --- a/scrub/vfs.c +++ b/scrub/vfs.c @@ -249,7 +249,7 @@ scan_fs_tree( goto out_cond; } - ret = queue_subdir(ctx, &sft, &wq, ctx->mntpoint, true); + ret = queue_subdir(ctx, &sft, &wq, ctx->actual_mntpoint, true); if (ret) { str_liberror(ctx, ret, _("queueing directory scan")); goto out_wq; diff --git a/scrub/xfs_scrub.c b/scrub/xfs_scrub.c index bdee8e4fdae..23d8fec5d9b 100644 --- a/scrub/xfs_scrub.c +++ b/scrub/xfs_scrub.c @@ -118,6 +118,8 @@ * Available even in non-debug mode: * SERVICE_MODE -- compress all error codes to 1 for LSB * service action compliance + * SERVICE_MOUNTPOINT -- actual path to open for issuing kernel + * scrub calls */ /* Program name; needed for libfrog error reports. */ @@ -739,6 +741,9 @@ main( usage(); ctx.mntpoint = argv[optind]; + ctx.actual_mntpoint = getenv("SERVICE_MOUNTPOINT"); + if (!ctx.actual_mntpoint) + ctx.actual_mntpoint = ctx.mntpoint; stdout_isatty = isatty(STDOUT_FILENO); stderr_isatty = isatty(STDERR_FILENO); @@ -756,7 +761,7 @@ main( return SCRUB_RET_OPERROR; /* Find the mount record for the passed-in argument. */ - if (stat(argv[optind], &ctx.mnt_sb) < 0) { + if (stat(ctx.actual_mntpoint, &ctx.mnt_sb) < 0) { fprintf(stderr, _("%s: could not stat: %s: %s\n"), progname, argv[optind], strerror(errno)); @@ -779,7 +784,7 @@ main( } fs_table_initialise(0, NULL, 0, NULL); - fsp = fs_table_lookup_mount(ctx.mntpoint); + fsp = fs_table_lookup_mount(ctx.actual_mntpoint); if (!fsp) { fprintf(stderr, _("%s: Not a XFS mount point.\n"), ctx.mntpoint); diff --git a/scrub/xfs_scrub.h b/scrub/xfs_scrub.h index 004d2d02587..2ef8b2e5066 100644 --- a/scrub/xfs_scrub.h +++ b/scrub/xfs_scrub.h @@ -36,9 +36,12 @@ enum error_action { struct scrub_ctx { /* Immutable scrub state. */ - /* Strings we need for presentation */ + /* Mountpoint we use for presentation */ char *mntpoint; + /* Actual VFS path to the filesystem */ + char *actual_mntpoint; + /* Mountpoint info */ struct stat mnt_sb; struct statvfs mnt_sv;