* Test to trace kernel bug in fsconfig(2) with btrfs
@ 2020-02-06 9:50 Richard Haines
0 siblings, 0 replies; only message in thread
From: Richard Haines @ 2020-02-06 9:50 UTC (permalink / raw)
To: linux-fsdevel; +Cc: selinux, dhowells, viro, sds, paul, omosnace
[-- Attachment #1: Type: text/plain, Size: 1285 bytes --]
I've attached a test program 'fsmount.c'. This can be used along with
the test script below to show a kernel bug when calling fsconfig(2)
with security options on a btrfs filesystem.
This problem only occurs using fsconfig(2) when attempting to add
security options. Setting a native btrfs option (e.g. flushoncommit)
works.
Copy the statements below into test.sh and run with the fs name. Other
fs will work such as ext4, xfs. Only btrfs will fail.
#!/bin/sh
fs_name=$1
mkdir -p /mnt/selinux-testsuite
dd if=/dev/zero of=./fstest bs=4096 count=27904
dev=`losetup -f`
losetup $dev ./fstest
mkfs.$fs_name $dev
/usr/bin/systemctl stop udisks2 # Stops crap appearing in journal log
# mount(2) works:
#mount -t $fs_name -o "rootcontext=system_u:object_r:unconfined_t:s0"
$dev /mnt/selinux-testsuite
# This native btrfs "flushoncommit" option will work with fsconfig(2):
#./fsmount $fs_name $dev /mnt/selinux-testsuite "flushoncommit"
# This will not:
./fsmount $fs_name $dev /mnt/selinux-testsuite
"rootcontext=system_u:object_r:unconfined_t:s0"
# rootcontext fails with journal entry: SELinux: mount invalid.
# Same superblock, different security settings for (dev loop0, type
btrfs)
umount /mnt/selinux-testsuite
losetup -d $dev
/usr/bin/systemctl start udisks2
rm -f ./fstest
[-- Attachment #2: fsmount.c --]
[-- Type: text/x-csrc, Size: 2727 bytes --]
/* cc fsmount.c -o fsmount -Wall */
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <errno.h>
#include <fcntl.h>
#include <sys/prctl.h>
#include <linux/mount.h>
#include <linux/unistd.h>
int fsopen(const char *fs_name, unsigned int flags)
{
return syscall(__NR_fsopen, fs_name, flags);
}
int fsconfig(int fsfd, unsigned int cmd, const char *key,
const void *val, int aux)
{
return syscall(__NR_fsconfig, fsfd, cmd, key, val, aux);
}
int fsmount(int fsfd, unsigned int flags, unsigned int ms_flags)
{
return syscall(__NR_fsmount, fsfd, flags, ms_flags);
}
int move_mount(int from_dfd, const char *from_pathname, int to_dfd,
const char *to_pathname, unsigned int flags)
{
return syscall(__NR_move_mount, from_dfd, from_pathname,
to_dfd, to_pathname, flags);
}
#define MAX_OPS 10
int fsconfig_opts(int fd, char *src, char *opts)
{
int ret, i, max_entries = 0;
int cmd[MAX_OPS];
char *key[MAX_OPS], *value[MAX_OPS];
char *src_str = "source";
cmd[0] = FSCONFIG_SET_STRING;
key[0] = src_str;
value[0] = src;
for (i = 1; i < MAX_OPS; i++) {
value[i] = strsep(&opts, ",");
if (!value[i]) {
max_entries = i + 1;
break;
}
cmd[i] = FSCONFIG_SET_STRING;
}
for (i = 1; value[i] != NULL; i++) {
key[i] = strsep(&value[i], "=");
if (!value[i])
cmd[i] = FSCONFIG_SET_FLAG;
}
cmd[i] = FSCONFIG_CMD_CREATE;
key[i] = NULL;
value[i] = NULL;
for (i = 0; i != max_entries; i++) {
printf("fsconfig(0x%x, %s, %s, 0)\n", cmd[i], key[i], value[i]);
ret = fsconfig(fd, cmd[i], key[i], value[i], 0);
if (ret < 0) {
fprintf(stderr, "Failed fsconfig(2): %s\n",
strerror(errno));
return -1;
}
}
return 0;
}
int main(int argc, char *argv[])
{
int ret, fsfd, mfd;
unsigned int mount_attrs = 0;
char *opts;
if (argc != 5) {
fprintf(stderr, "usage: %s <type> <src> <tgt> <opts>\n", argv[0]);
return 1;
}
fsfd = fsopen(argv[1], 0);
if (fsfd < 0) {
fprintf(stderr, "Failed fsopen(2): %s\n", strerror(errno));
return -1;
}
if (!strncmp (argv[1], "nfs", 3))
mount_attrs = MS_NODEV;
opts = strdup(argv[4]);
ret = fsconfig_opts(fsfd, argv[2], opts);
if (ret < 0) {
fprintf(stderr, "Failed to add options: %s\n", argv[4]);
close(fsfd);
return -1;
}
printf("Successfully added options: %s\n", argv[4]);
mfd = fsmount(fsfd, 0, mount_attrs);
if (mfd < 0) {
fprintf(stderr, "Failed fsmount(2): %s\n", strerror(errno));
return -1;
}
close(fsfd);
ret = move_mount(mfd, "", AT_FDCWD, argv[3], MOVE_MOUNT_F_EMPTY_PATH);
if (ret < 0) {
fprintf(stderr, "Failed move_mount(2): %s\n", strerror(errno));
return -1;
}
close(mfd);
printf("Successfully mounted on: %s\n", argv[3]);
return 0;
}
^ permalink raw reply [flat|nested] only message in thread
only message in thread, other threads:[~2020-02-06 9:50 UTC | newest]
Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-02-06 9:50 Test to trace kernel bug in fsconfig(2) with btrfs Richard Haines
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).