All the mail mirrored from lore.kernel.org
 help / color / mirror / Atom feed
* 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 10:22 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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.