From: Richard Haines <richard_c_haines@btinternet.com>
To: linux-fsdevel@vger.kernel.org
Cc: selinux@vger.kernel.org, dhowells@redhat.com,
viro@zeniv.linux.org.uk, sds@tycho.nsa.gov, paul@paul-moore.com,
omosnace@redhat.com
Subject: Test to trace kernel bug in fsconfig(2) with btrfs
Date: Thu, 06 Feb 2020 09:50:46 +0000 [thread overview]
Message-ID: <c02674c970fa292610402aa866c4068772d9ad4e.camel@btinternet.com> (raw)
[-- 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;
}
reply other threads:[~2020-02-06 9:50 UTC|newest]
Thread overview: [no followups] expand[flat|nested] mbox.gz Atom feed
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=c02674c970fa292610402aa866c4068772d9ad4e.camel@btinternet.com \
--to=richard_c_haines@btinternet.com \
--cc=dhowells@redhat.com \
--cc=linux-fsdevel@vger.kernel.org \
--cc=omosnace@redhat.com \
--cc=paul@paul-moore.com \
--cc=sds@tycho.nsa.gov \
--cc=selinux@vger.kernel.org \
--cc=viro@zeniv.linux.org.uk \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
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).