1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1.2 +++ b/conf/dstest_file_access.cfg Wed Feb 09 22:30:29 2022 +0100
1.3 @@ -0,0 +1,51 @@
1.4 +-- vim:set ft=lua:
1.5 +
1.6 +local L4 = require("L4");
1.7 +
1.8 +local l = L4.default_loader;
1.9 +
1.10 +local pipe_server = l:new_channel();
1.11 +
1.12 +l:startv({
1.13 + caps = {
1.14 + server = pipe_server:svr(),
1.15 + },
1.16 + log = { "pipes", "r" },
1.17 + },
1.18 + "rom/dstest_pipe_server", "10");
1.19 +
1.20 +local blocksvr = l:new_channel();
1.21 +
1.22 +l:startv({
1.23 + caps = {
1.24 + server = blocksvr:svr(),
1.25 + },
1.26 + log = { "blocksvr", "r" },
1.27 + },
1.28 + "rom/dstest_block_server", "10");
1.29 +
1.30 +local ext2svr = l:new_channel();
1.31 +
1.32 +l:startv({
1.33 + caps = {
1.34 + blocksvr = blocksvr,
1.35 + pipes = pipe_server,
1.36 + ext2svr = ext2svr:svr(),
1.37 + },
1.38 + log = { "ext2svr", "y" },
1.39 + },
1.40 + "rom/dstest_ext2_server", "blocksvr", "rom/e2test.fs", "10", "ext2svr");
1.41 +
1.42 +-- Obtain user filesystems with umask 0022 (18).
1.43 +
1.44 +local open_for_user = 6;
1.45 +local ext2svr_davidb = L4.cast(L4.Proto.Factory, ext2svr):create(open_for_user, 1001, 1001, 18);
1.46 +
1.47 +l:startv({
1.48 + caps = {
1.49 + server = ext2svr_davidb,
1.50 + },
1.51 + log = { "client", "g" },
1.52 + },
1.53 + -- program, directory
1.54 + "rom/dstest_file_access", "home/paulb/private", "home/paulb/public", "home/paulb/shared");
2.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
2.2 +++ b/conf/dstest_file_access.list Wed Feb 09 22:30:29 2022 +0100
2.3 @@ -0,0 +1,28 @@
2.4 +entry dstest_file_access
2.5 +roottask moe rom/dstest_file_access.cfg
2.6 +module dstest_file_access.cfg
2.7 +module e2test.fs
2.8 +module l4re
2.9 +module ned
2.10 +module dstest_file_access
2.11 +module dstest_ext2_server
2.12 +module dstest_block_server
2.13 +module dstest_pipe_server
2.14 +module lib4re-c.so
2.15 +module lib4re-c-util.so
2.16 +module lib4re.so
2.17 +module lib4re-util.so
2.18 +module libc_be_l4refile.so
2.19 +module libc_be_l4re.so
2.20 +module libc_be_socket_noop.so
2.21 +module libc_support_misc.so
2.22 +module libdl.so
2.23 +module libipc.so
2.24 +module libl4sys-direct.so
2.25 +module libl4sys.so
2.26 +module libl4util.so
2.27 +module libld-l4.so
2.28 +module libpthread.so
2.29 +module libstdc++.so
2.30 +module libsupc++.so
2.31 +module libuc_c.so
3.1 --- a/libfsserver/include/fsserver/ext2_file_operations.h Tue Feb 08 00:03:32 2022 +0100
3.2 +++ b/libfsserver/include/fsserver/ext2_file_operations.h Wed Feb 09 22:30:29 2022 +0100
3.3 @@ -57,10 +57,16 @@
3.4 {
3.5 }
3.6
3.7 + /* Access and object type tests. */
3.8 +
3.9 + bool can_access(user_t user, flags_t flags, ext2_ino_t ino);
3.10 +
3.11 bool is_directory(ext2_ino_t ino_file);
3.12
3.13 bool is_file(ext2_ino_t ino_file);
3.14
3.15 + /* File manipulation. */
3.16 +
3.17 void close_file(ext2_file_t file);
3.18
3.19 long create_file(ext2_ino_t ino_parent, const char *filename, user_t user,
4.1 --- a/libfsserver/lib/files/ext2_file_opener.cc Tue Feb 08 00:03:32 2022 +0100
4.2 +++ b/libfsserver/lib/files/ext2_file_opener.cc Wed Feb 09 22:30:29 2022 +0100
4.3 @@ -1,7 +1,7 @@
4.4 /*
4.5 * An opener for a file provided by an Ext2-compatible filesystem.
4.6 *
4.7 - * Copyright (C) 2021 Paul Boddie <paul@boddie.org.uk>
4.8 + * Copyright (C) 2021, 2022 Paul Boddie <paul@boddie.org.uk>
4.9 *
4.10 * This program is free software; you can redistribute it and/or
4.11 * modify it under the terms of the GNU General Public License as
4.12 @@ -64,6 +64,9 @@
4.13
4.14 if (!err)
4.15 {
4.16 + if (!_ops->can_access(_user, flags, ino))
4.17 + return -L4_EPERM;
4.18 +
4.19 *fileid = (fileid_t) ino;
4.20 return L4_EOK;
4.21 }
5.1 --- a/libfsserver/lib/files/ext2_file_operations.cc Tue Feb 08 00:03:32 2022 +0100
5.2 +++ b/libfsserver/lib/files/ext2_file_operations.cc Wed Feb 09 22:30:29 2022 +0100
5.3 @@ -22,10 +22,27 @@
5.4 #include <e2access/access.h>
5.5 #include <e2access/image.h>
5.6 #include <e2access/path.h>
5.7 +#include <systypes/fcntl.h>
5.8
5.9 #include "ext2_file_operations.h"
5.10
5.11 -/* Object type tests. */
5.12 +
5.13 +
5.14 +/* Access and object type tests. */
5.15 +
5.16 +bool Ext2FileOperations::can_access(user_t user, flags_t flags, ext2_ino_t ino)
5.17 +{
5.18 + struct ext2_inode inode;
5.19 + errcode_t retval = ext2fs_read_inode(_fs, ino, &inode);
5.20 +
5.21 + if (retval)
5.22 + return false;
5.23 +
5.24 + if ((flags & O_RDWR) || (flags & O_WRONLY))
5.25 + return access_can_write(user, &inode);
5.26 + else
5.27 + return access_can_read(user, &inode);
5.28 +}
5.29
5.30 bool Ext2FileOperations::is_directory(ext2_ino_t ino_file)
5.31 {
5.32 @@ -41,6 +58,8 @@
5.33 return _image_isfile(_fs, ino_file);
5.34 }
5.35
5.36 +
5.37 +
5.38 /* Perform closing operations on a file. */
5.39
5.40 void Ext2FileOperations::close_file(ext2_file_t file)
6.1 --- a/libfsserver/lib/generic/resource_registry.cc Tue Feb 08 00:03:32 2022 +0100
6.2 +++ b/libfsserver/lib/generic/resource_registry.cc Wed Feb 09 22:30:29 2022 +0100
6.3 @@ -1,7 +1,7 @@
6.4 /*
6.5 * Filesystem resource registry incorporating opening functionality.
6.6 *
6.7 - * Copyright (C) 2021 Paul Boddie <paul@boddie.org.uk>
6.8 + * Copyright (C) 2021, 2022 Paul Boddie <paul@boddie.org.uk>
6.9 *
6.10 * This program is free software; you can redistribute it and/or
6.11 * modify it under the terms of the GNU General Public License as
6.12 @@ -143,7 +143,8 @@
6.13 std::lock_guard<std::mutex> guard(_lock);
6.14
6.15 /* Obtain an identifier for the object, even for new files (subject to use
6.16 - of the appropriate flag). */
6.17 + of the appropriate flag). This also checks the access rights for any
6.18 + configured user. */
6.19
6.20 fileid_t fileid;
6.21 long err = opening->get_fileid(path, flags, &fileid);
6.22 @@ -176,7 +177,8 @@
6.23 {
6.24 std::lock_guard<std::mutex> guard(_lock);
6.25
6.26 - /* Obtain an identifier for any recognised object. */
6.27 + /* Obtain an identifier for any recognised object. This also checks the
6.28 + access rights for any configured user. */
6.29
6.30 fileid_t fileid;
6.31 long err = opening->get_fileid(path, 0, &fileid);
6.32 @@ -226,7 +228,8 @@
6.33 long err;
6.34 fileid_t source_fileid, target_fileid;
6.35
6.36 - /* Obtain an identifier for any recognised object. */
6.37 + /* Obtain an identifier for any recognised object. This also checks the
6.38 + access rights for any configured user. */
6.39
6.40 err = opening->get_fileid(source, 0, &source_fileid);
6.41
7.1 --- a/test_files/mk_e2test.sh Tue Feb 08 00:03:32 2022 +0100
7.2 +++ b/test_files/mk_e2test.sh Wed Feb 09 22:30:29 2022 +0100
7.3 @@ -1,6 +1,9 @@
7.4 #!/bin/sh
7.5
7.6 -THIS_DIR=$(realpath $(dirname "$0"))
7.7 +# NOTE: There should be a stable user identifier defined, not that of the user
7.8 +# NOTE: running this script.
7.9 +
7.10 +PROGNAME=$(basename "$0")
7.11
7.12 if [ "$1" = '-q' ] ; then
7.13 QUIET=$1
7.14 @@ -9,19 +12,21 @@
7.15 QUIET=
7.16 fi
7.17
7.18 -PKGDIR=$1
7.19 -E2ACCESS_DIR=$2
7.20 -TARGET=$3
7.21 +PKGDIR=$(realpath "$1")
7.22 +E2ACCESS_DIR=$(realpath "$2")
7.23 +TARGET=$(realpath "$3")
7.24
7.25 if [ ! -e "$PKGDIR" ] || [ ! -e "$E2ACCESS_DIR" ] || [ ! "$TARGET" ] ; then
7.26 - echo "Usage: $0 [ -q ] <package directory> <e2access directory> <target>" 1>&2
7.27 + cat 1>&2 <<EOF
7.28 +Usage: $PROGNAME [ -q ] <package directory> <e2access directory> <target>
7.29 +
7.30 +Package directory: $PKGDIR
7.31 +e2access directory: $E2ACCESS_DIR
7.32 +Target filesystem: $TARGET
7.33 +EOF
7.34 exit 1
7.35 fi
7.36
7.37 -PKGDIR=`realpath "$PKGDIR"`
7.38 -E2ACCESS_DIR=`realpath "$E2ACCESS_DIR"`
7.39 -TARGET=`realpath "$TARGET"`
7.40 -
7.41 # Initialise the program details and environment.
7.42
7.43 E2ACCESS="$E2ACCESS_DIR"/e2access
7.44 @@ -31,6 +36,34 @@
7.45
7.46 mkdir tmp_e2test
7.47 cd tmp_e2test
7.48 +
7.49 +# Set a sensible umask.
7.50 +
7.51 +umask 0022
7.52 +
7.53 +mkdir -p home/paulb/public
7.54 +echo "Public!" > home/paulb/public/message
7.55 +
7.56 +# Set a restrictive umask.
7.57 +
7.58 +umask 0077
7.59 +
7.60 +echo "Not public!" > home/paulb/public/message2
7.61 +
7.62 +mkdir -p home/paulb/private
7.63 +echo "Private!" > home/paulb/private/message
7.64 +
7.65 +# Set a permissive umask.
7.66 +
7.67 +umask 0000
7.68 +
7.69 +mkdir -p home/paulb/shared
7.70 +echo "Editable!" > home/paulb/shared/message
7.71 +
7.72 +# Restore the umask for the remaining files.
7.73 +
7.74 +umask 0022
7.75 +
7.76 mkdir -p home/paulb/many
7.77 cd home/paulb/many
7.78
7.79 @@ -62,12 +95,12 @@
7.80 exit 1
7.81 fi
7.82
7.83 -# Add the directory and files to the image.
7.84 +# Add the directories and files to the image.
7.85
7.86 -"$E2ACCESS" "$TARGET" --make-dirs home/paulb/many
7.87 -
7.88 -"$E2ACCESS" "$TARGET" --copy-in $(find home/paulb/many -maxdepth 1 -type f | sort) home/paulb/many
7.89 -"$E2ACCESS" "$TARGET" --copy-in $(find home/paulb -maxdepth 1 -type f | sort) home/paulb
7.90 +for DIR in home/paulb/private home/paulb/public home/paulb/shared home/paulb/many home/paulb ; do
7.91 + "$E2ACCESS" "$TARGET" --make-dirs "$DIR"
7.92 + "$E2ACCESS" "$TARGET" --copy-in $(find "$DIR" -maxdepth 1 -type f | sort) "$DIR"
7.93 +done
7.94
7.95 # Leave the root of the filesystem.
7.96
7.97 @@ -78,6 +111,11 @@
7.98 "$E2ACCESS" "$TARGET" --list-dirs 'home'
7.99 "$E2ACCESS" "$TARGET" --list-dirs 'home/paulb'
7.100 "$E2ACCESS" "$TARGET" --list-dirs 'home/paulb/many'
7.101 + "$E2ACCESS" "$TARGET" --list-dirs 'home/paulb/private'
7.102 + "$E2ACCESS" "$TARGET" --list-dirs 'home/paulb/public'
7.103 + "$E2ACCESS" "$TARGET" --list-dirs 'home/paulb/shared'
7.104 fi
7.105
7.106 rm -r tmp_e2test
7.107 +
7.108 +# vim: tabstop=4 expandtab shiftwidth=4
8.1 --- a/tests/Makefile Tue Feb 08 00:03:32 2022 +0100
8.2 +++ b/tests/Makefile Wed Feb 09 22:30:29 2022 +0100
8.3 @@ -4,6 +4,7 @@
8.4 TARGET = \
8.5 dstest_block_client dstest_block_client_simple \
8.6 dstest_ext2fs_client \
8.7 + dstest_file_access \
8.8 dstest_file_client \
8.9 dstest_file_monitor \
8.10 dstest_file_readdir \
8.11 @@ -21,6 +22,8 @@
8.12
8.13 SRC_CC_dstest_ext2fs_client = dstest_ext2fs_client.cc
8.14
8.15 +SRC_CC_dstest_file_access = dstest_file_access.cc
8.16 +
8.17 SRC_CC_dstest_file_client = dstest_file_client.cc
8.18
8.19 SRC_CC_dstest_file_monitor = dstest_file_monitor.cc
9.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
9.2 +++ b/tests/dstest_file_access.cc Wed Feb 09 22:30:29 2022 +0100
9.3 @@ -0,0 +1,98 @@
9.4 +/*
9.5 + * Test file access.
9.6 + *
9.7 + * Copyright (C) 2020, 2021, 2022 Paul Boddie <paul@boddie.org.uk>
9.8 + *
9.9 + * This program is free software; you can redistribute it and/or
9.10 + * modify it under the terms of the GNU General Public License as
9.11 + * published by the Free Software Foundation; either version 2 of
9.12 + * the License, or (at your option) any later version.
9.13 + *
9.14 + * This program is distributed in the hope that it will be useful,
9.15 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
9.16 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
9.17 + * GNU General Public License for more details.
9.18 + *
9.19 + * You should have received a copy of the GNU General Public License
9.20 + * along with this program; if not, write to the Free Software
9.21 + * Foundation, Inc., 51 Franklin Street, Fifth Floor,
9.22 + * Boston, MA 02110-1301, USA
9.23 + */
9.24 +
9.25 +#include <l4/re/env.h>
9.26 +#include <l4/sys/err.h>
9.27 +
9.28 +#include <stdio.h>
9.29 +#include <string.h>
9.30 +#include <stdlib.h>
9.31 +
9.32 +#include <fsclient/client.h>
9.33 +#include <systypes/fcntl.h>
9.34 +
9.35 +
9.36 +
9.37 +int main(int argc, char *argv[])
9.38 +{
9.39 + if (argc < 2)
9.40 + {
9.41 + printf("Need directory names.\n");
9.42 + return 1;
9.43 + }
9.44 +
9.45 + for (int i = 1; i < argc; i++)
9.46 + {
9.47 + char *dirname = argv[i];
9.48 +
9.49 + printf("Opening %s...\n", dirname);
9.50 +
9.51 + file_t *reader = client_opendir(dirname);
9.52 +
9.53 + if (reader == NULL)
9.54 + {
9.55 + printf("Could not read from directory: %s\n", dirname);
9.56 + continue;
9.57 + }
9.58 +
9.59 + printf("Reading...\n");
9.60 +
9.61 + struct dirent *dirent;
9.62 +
9.63 + while ((dirent = client_readdir(reader)) != NULL)
9.64 + {
9.65 + char *filename = dirent->d_name;
9.66 + if (!strlen(filename) || (filename[0] == '.'))
9.67 + continue;
9.68 +
9.69 + char path[strlen(filename) + strlen(dirname) + 2];
9.70 +
9.71 + sprintf(path, "%s/%s", dirname, filename);
9.72 +
9.73 + printf("Attempt to read %s...\n", filename);
9.74 +
9.75 + file_t *file = client_open(path, O_RDONLY);
9.76 +
9.77 + if (file == NULL)
9.78 + printf("Could not open file: %s\n", filename);
9.79 + else
9.80 + {
9.81 + char buffer[32];
9.82 + offset_t nread = client_read(file, buffer, 32);
9.83 +
9.84 + fputs("Start of file: ", stdout);
9.85 + fwrite(buffer, sizeof(char), nread, stdout);
9.86 + fputs("\n", stdout);
9.87 +
9.88 + client_close(file);
9.89 + }
9.90 +
9.91 + free(dirent);
9.92 + }
9.93 +
9.94 + printf("Directory shown.\n");
9.95 +
9.96 + }
9.97 +
9.98 + return 0;
9.99 +}
9.100 +
9.101 +// vim: tabstop=2 expandtab shiftwidth=2