use a smaller subset of flags for remounting readonly
a) In the linux namespace mount case an additional MS_NOATIME, etc. will result in EPERM on remounting something hosted in a toplevel [rel]atime mount. man 2 mount has 'An attempt was made to modify (MS_REMOUNT) the MS_RDONLY, MS_NOSUID, or MS_NOEXEC flag, or one of the "atime" flags (MS_NOATIME, MS_NODIRATIME, MS_RELATIME) of an existing mount, but the mount is locked'. b) lxc has default apparmor rules of https://github.com/lxc/lxc/blob/main/config/apparmor/abstractions/container-base where the closest match is: "mount options=(ro,remount,bind,nodev,nosuid)" so additional 'MS_SILENT' or 'MS_REC' flags similarly also cause the remount to be denied So if we use a more recognized set of options we work out of the box in the default lxc configuration. Signed-off-by: Caolán McNamara <caolan.mcnamara@collabora.com> Change-Id: I5f8de2de998ae1a85fefc1c9537b79b2b3bdefec
This commit is contained in:
parent
9719250e73
commit
5fbc4bbbdd
3 changed files with 18 additions and 20 deletions
|
@ -29,13 +29,11 @@
|
||||||
|
|
||||||
#define MOUNT mount_wrapper
|
#define MOUNT mount_wrapper
|
||||||
#define MS_MGC_VAL 0
|
#define MS_MGC_VAL 0
|
||||||
#define MS_SILENT 0
|
|
||||||
#define MS_NODEV 0
|
#define MS_NODEV 0
|
||||||
#define MS_UNBINDABLE 0
|
#define MS_UNBINDABLE 0
|
||||||
#define MS_BIND 1
|
#define MS_BIND 1
|
||||||
#define MS_REC 2
|
#define MS_REC 2
|
||||||
#define MS_REMOUNT 4
|
#define MS_REMOUNT 4
|
||||||
#define MS_NOATIME 8
|
|
||||||
#define MS_NOSUID 16
|
#define MS_NOSUID 16
|
||||||
#define MS_RDONLY 32
|
#define MS_RDONLY 32
|
||||||
|
|
||||||
|
@ -82,9 +80,6 @@ int mount_wrapper(const char *source, const char *target,
|
||||||
if(mountflags & MS_REMOUNT)
|
if(mountflags & MS_REMOUNT)
|
||||||
freebsd_flags |= MNT_UPDATE;
|
freebsd_flags |= MNT_UPDATE;
|
||||||
|
|
||||||
if(mountflags & MS_NOATIME)
|
|
||||||
freebsd_flags |= MNT_NOATIME;
|
|
||||||
|
|
||||||
if(mountflags & MS_NOSUID)
|
if(mountflags & MS_NOSUID)
|
||||||
freebsd_flags |= MNT_NOSUID;
|
freebsd_flags |= MNT_NOSUID;
|
||||||
|
|
||||||
|
@ -147,7 +142,7 @@ void usage(const char* program)
|
||||||
fprintf(stderr, " -u to unmount the target.\n");
|
fprintf(stderr, " -u to unmount the target.\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
int domount(bool namespace_mount, int argc, const char* const* argv)
|
int domount(int argc, const char* const* argv)
|
||||||
{
|
{
|
||||||
const char* program = argv[0];
|
const char* program = argv[0];
|
||||||
if (argc < 3)
|
if (argc < 3)
|
||||||
|
@ -300,16 +295,19 @@ int domount(bool namespace_mount, int argc, const char* const* argv)
|
||||||
else if (strcmp(option, "-r") == 0) // Readonly Mount.
|
else if (strcmp(option, "-r") == 0) // Readonly Mount.
|
||||||
{
|
{
|
||||||
// Now we need to set read-only and other flags with a remount.
|
// Now we need to set read-only and other flags with a remount.
|
||||||
unsigned long mountflags = (MS_BIND | MS_REC | MS_REMOUNT | MS_NODEV | MS_NOSUID
|
unsigned long mountflags = (MS_BIND | MS_REMOUNT | MS_NODEV | MS_NOSUID | MS_RDONLY);
|
||||||
| MS_RDONLY | MS_SILENT);
|
|
||||||
// In the linux namespace mount case, setting MS_NOATIME results in EPERM on remounting
|
/* a) In the linux namespace mount case an additional MS_NOATIME, etc. will result in
|
||||||
// something hosted in a toplevel [rel]atime mount. man 2 mount states 'An attempt was
|
EPERM on remounting something hosted in a toplevel [rel]atime mount. man 2 mount
|
||||||
// made to modify (MS_REMOUNT) the MS_RDONLY, MS_NOSUID, or MS_NOEXEC flag, or one of
|
has 'An attempt was made to modify (MS_REMOUNT) the MS_RDONLY, MS_NOSUID, or
|
||||||
// the "atime" flags (MS_NOATIME, MS_NODIRATIME, MS_RELATIME) of an existing mount, but
|
MS_NOEXEC flag, or one of the "atime" flags (MS_NOATIME, MS_NODIRATIME, MS_RELATIME)
|
||||||
// the mount is locked'. Presumably we can add flags that drop privs, but not those
|
of an existing mount, but the mount is locked'.
|
||||||
// that could circumvent original mount policy.
|
|
||||||
if (!namespace_mount)
|
b) lxc has default apparmor rules of
|
||||||
mountflags |= MS_NOATIME;
|
https://github.com/lxc/lxc/blob/main/config/apparmor/abstractions/container-base
|
||||||
|
where the closest match is: "mount options=(ro,remount,bind,nodev,nosuid)"
|
||||||
|
so additional 'MS_SILENT' or 'MS_REC' flags cause the remount to be denied
|
||||||
|
*/
|
||||||
int retval = MOUNT(source, target, nullptr, mountflags, nullptr);
|
int retval = MOUNT(source, target, nullptr, mountflags, nullptr);
|
||||||
if (retval)
|
if (retval)
|
||||||
{
|
{
|
||||||
|
|
|
@ -33,7 +33,7 @@
|
||||||
#include "Log.hpp"
|
#include "Log.hpp"
|
||||||
#include <SigUtil.hpp>
|
#include <SigUtil.hpp>
|
||||||
|
|
||||||
extern int domount(bool namespace_mount, int argc, const char* const* argv);
|
extern int domount(int argc, const char* const* argv);
|
||||||
|
|
||||||
namespace JailUtil
|
namespace JailUtil
|
||||||
{
|
{
|
||||||
|
@ -130,7 +130,7 @@ bool coolmount(const std::string& arg, std::string source, std::string target)
|
||||||
argv[argc++] = source.c_str();
|
argv[argc++] = source.c_str();
|
||||||
if (!target.empty())
|
if (!target.empty())
|
||||||
argv[argc++] = target.c_str();
|
argv[argc++] = target.c_str();
|
||||||
return domount(true, argc, argv) == EX_OK;
|
return domount(argc, argv) == EX_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
const std::string cmd = Poco::Path(Util::getApplicationPath(), "coolmount").toString() + ' '
|
const std::string cmd = Poco::Path(Util::getApplicationPath(), "coolmount").toString() + ' '
|
||||||
|
|
|
@ -19,7 +19,7 @@
|
||||||
|
|
||||||
#include <security.h>
|
#include <security.h>
|
||||||
|
|
||||||
extern int domount(bool namespace_mount, int argc, const char* const* argv);
|
extern int domount(int argc, const char* const* argv);
|
||||||
|
|
||||||
int main(int argc, char** argv)
|
int main(int argc, char** argv)
|
||||||
{
|
{
|
||||||
|
@ -31,7 +31,7 @@ int main(int argc, char** argv)
|
||||||
/*WARNING*/ }
|
/*WARNING*/ }
|
||||||
/*WARNING: PRIVILEGED CODE CHECKING END */
|
/*WARNING: PRIVILEGED CODE CHECKING END */
|
||||||
|
|
||||||
return domount(false, argc, argv);
|
return domount(argc, argv);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|
||||||
|
|
Loading…
Reference in a new issue