axeld + bonefish:

Added parameters --start-offset and --end-offset to restrict the
access of the file system to only that part of the given file.


git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@23970 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Ingo Weinhold
2008-02-17 13:42:27 +00:00
parent 9ae93dcd7f
commit 3e61704042
9 changed files with 404 additions and 27 deletions
+1
View File
@@ -47,6 +47,7 @@ BuildPlatformStaticLibrary <build>fs_shell.a :
lock.cpp
module.cpp
node_monitor.cpp
partition_support.cpp
path_util.cpp
rootfs.cpp
sem.cpp
+10 -5
View File
@@ -1,5 +1,5 @@
/*
* Copyright 2007, Ingo Weinhold, [email protected].de.
* Copyright 2007-2008, Ingo Weinhold, ingo_weinhold@gmx.de.
* Distributed under the terms of the MIT License.
*/
@@ -9,6 +9,7 @@
#include <stdarg.h>
#include "fssh_errno.h"
#include "partition_support.h"
#include "stat_util.h"
@@ -37,19 +38,23 @@ fssh_open(const char *pathname, int oflags, ...)
// Use the _kern_open() defined in libroot on BeOS incompatible systems.
// Required for proper attribute emulation support.
int fd;
#if __BEOS__
return open(pathname, to_platform_open_mode(oflags),
fd = open(pathname, to_platform_open_mode(oflags),
to_platform_mode(mode));
#else
int fd = _kern_open(-1, pathname, to_platform_open_mode(oflags),
fd = _kern_open(-1, pathname, to_platform_open_mode(oflags),
to_platform_mode(mode));
if (fd < 0) {
fssh_set_errno(fd);
return -1;
fd = -1;
}
return fd;
#endif
restricted_file_opened(fd);
return fd;
}
+21 -2
View File
@@ -27,6 +27,7 @@
#include "fssh_string.h"
#include "fssh_type_constants.h"
#include "module.h"
#include "partition_support.h"
#include "path_util.h"
#include "syscalls.h"
#include "vfs.h"
@@ -1159,8 +1160,11 @@ static void
print_usage(bool error)
{
fprintf((error ? stderr : stdout),
"Usage: %s [-n] <device>\n"
" %s --initialize [-n] <device> <volume name> "
"Usage: %s [ --start-offset <startOffset>]\n"
" [ --end-offset <endOffset>] [-n] <device>\n"
" %s [ --start-offset <startOffset>]\n"
" [ --end-offset <endOffset>]\n"
" --initialize [-n] <device> <volume name> "
"[ <init parameters> ]\n",
sArgv[0], sArgv[0]
);
@@ -1193,6 +1197,8 @@ main(int argc, const char* const* argv)
const char* device = NULL;
const char* volumeName = NULL;
const char* initParameters = NULL;
fssh_off_t startOffset = 0;
fssh_off_t endOffset = -1;
// eat options
int argi = 1;
@@ -1204,6 +1210,14 @@ main(int argc, const char* const* argv)
initialize = true;
} else if (strcmp(arg, "-n") == 0) {
interactive = false;
} else if (strcmp(arg, "--start-offset") == 0) {
if (argi >= argc)
print_usage_and_exit(true);
startOffset = atoll(argv[argi++]);
} else if (strcmp(arg, "--end-offset") == 0) {
if (argi >= argc)
print_usage_and_exit(true);
endOffset = atoll(argv[argi++]);
} else {
print_usage_and_exit(true);
}
@@ -1247,6 +1261,11 @@ main(int argc, const char* const* argv)
return error;
}
// restrict access if requested
if (startOffset != 0 || endOffset != -1)
add_file_restriction(device, startOffset, endOffset);
// start the action
int result;
if (initialize) {
+215
View File
@@ -0,0 +1,215 @@
/*
* Copyright 2008, Ingo Weinhold, ingo_weinhold@gmx.de.
* Distributed under the terms of the MIT License.
*/
#include "compatibility.h"
#include "partition_support.h"
#include <errno.h>
#include <unistd.h>
#include <list>
#include "fssh_errno.h"
#include "fssh_stat.h"
#include "fssh_unistd.h"
#include "stat_priv.h"
namespace FSShell {
struct FileRestriction {
FileRestriction(fssh_dev_t device, fssh_ino_t node, fssh_off_t startOffset,
fssh_off_t endOffset)
: device(device),
node(node),
startOffset(startOffset),
endOffset(endOffset)
{
}
fssh_dev_t device;
fssh_ino_t node;
fssh_off_t startOffset;
fssh_off_t endOffset;
};
typedef std::list<FileRestriction*> FileRestrictionList;
static FileRestrictionList sFileRestrictions;
static FileRestriction*
find_file_restriction(fssh_dev_t device, fssh_ino_t node)
{
for (FileRestrictionList::iterator it = sFileRestrictions.begin();
it != sFileRestrictions.end();
++it) {
FileRestriction* restriction = *it;
if (restriction->device == device && restriction->node == node)
return restriction;
}
return NULL;
}
static FileRestriction*
find_file_restriction(int fd)
{
struct fssh_stat st;
if (unrestricted_fstat(fd, &st) < 0)
return NULL;
return find_file_restriction(st.fssh_st_dev, st.fssh_st_ino);
}
void
add_file_restriction(const char* fileName, fssh_off_t startOffset,
fssh_off_t endOffset)
{
struct fssh_stat st;
if (unrestricted_stat(fileName, &st) < 0)
return;
fssh_dev_t device = st.fssh_st_dev;
fssh_ino_t node = st.fssh_st_ino;
FileRestriction* restriction = find_file_restriction(device, node);
if (restriction)
return;
if (endOffset < 0)
endOffset = st.fssh_st_size;
restriction = new FileRestriction(device, node, startOffset, endOffset);
sFileRestrictions.push_back(restriction);
}
void
restricted_file_opened(int fd)
{
FileRestriction* restriction = find_file_restriction(fd);
if (!restriction)
return;
lseek(fd, restriction->startOffset, SEEK_SET);
}
void
restricted_file_duped(int oldFD, int newFD)
{
}
void
restricted_file_closed(int fd)
{
}
int
restricted_file_restrict_io(int fd, fssh_off_t& pos, fssh_off_t size)
{
FileRestriction* restriction = find_file_restriction(fd);
if (!restriction)
return 0;
if (pos < 0) {
pos = lseek(fd, 0, SEEK_CUR);
if (pos < 0)
return -1;
} else
pos += restriction->startOffset;
if (pos < restriction->startOffset || pos > restriction->endOffset) {
fssh_set_errno(B_BAD_VALUE);
return -1;
}
fssh_off_t maxSize = restriction->endOffset - pos;
if (size > maxSize)
size = maxSize;
return 0;
}
#include <stdio.h>
void
restricted_file_restrict_stat(struct fssh_stat* st)
{
FileRestriction* restriction = find_file_restriction(st->fssh_st_dev,
st->fssh_st_ino);
if (!restriction)
return;
printf("restricted_file_restrict_stat(): startOffset: %lld, endOffset: %lld\n",
restriction->startOffset, restriction->endOffset);
st->fssh_st_size = restriction->endOffset - restriction->startOffset;
}
static int
to_platform_seek_mode(int fsshWhence)
{
switch (fsshWhence) {
case FSSH_SEEK_CUR:
return SEEK_CUR;
case FSSH_SEEK_END:
return SEEK_END;
case FSSH_SEEK_SET:
default:
return SEEK_SET;
}
}
fssh_off_t
fssh_lseek(int fd, fssh_off_t offset, int whence)
{
FileRestriction* restriction = find_file_restriction(fd);
if (!restriction)
return lseek(fd, offset, to_platform_seek_mode(whence));
fssh_off_t pos;
switch (whence) {
case FSSH_SEEK_CUR:
{
pos = lseek(fd, 0, SEEK_CUR);
if (pos < 0)
return pos;
pos += offset;
break;
}
case FSSH_SEEK_END:
pos = restriction->endOffset + offset;
break;
case FSSH_SEEK_SET:
default:
pos = restriction->startOffset + offset;
break;
}
if (pos < restriction->startOffset) {
fssh_set_errno(B_BAD_VALUE);
return -1;
}
pos = lseek(fd, pos, SEEK_SET);
if (pos >= 0)
pos -= restriction->startOffset;
return pos;
}
} // namespace FSShell
+29
View File
@@ -0,0 +1,29 @@
/*
* Copyright 2008, Ingo Weinhold, ingo_weinhold@gmx.de.
* Distributed under the terms of the MIT License.
*/
#ifndef _FSSH_PARTITION_SUPPORT_H
#define _FSSH_PARTITION_SUPPORT_H
#include "fssh_defs.h"
#include "fssh_stat.h"
namespace FSShell {
void add_file_restriction(const char* fileName, fssh_off_t startOffset,
fssh_off_t endOffset);
void restricted_file_opened(int fd);
void restricted_file_duped(int oldFD, int newFD);
void restricted_file_closed(int fd);
int restricted_file_restrict_io(int fd, fssh_off_t& pos, fssh_off_t size);
void restricted_file_restrict_stat(struct fssh_stat* st);
} // namespace FSShell
#endif // _FSSH_PARTITION_SUPPORT_H
+49 -10
View File
@@ -12,6 +12,8 @@
#include <sys/stat.h>
#include "fssh_errno.h"
#include "partition_support.h"
#include "stat_priv.h"
#include "stat_util.h"
@@ -27,14 +29,7 @@ using FSShell::to_platform_mode;
int
fssh_mkdir(const char *path, fssh_mode_t mode)
{
return mkdir(path, to_platform_mode(mode));
}
int
fssh_stat(const char *path, struct fssh_stat *fsshStat)
FSShell::unrestricted_stat(const char *path, struct fssh_stat *fsshStat)
{
struct stat st;
@@ -58,7 +53,7 @@ fssh_stat(const char *path, struct fssh_stat *fsshStat)
int
fssh_fstat(int fd, struct fssh_stat *fsshStat)
FSShell::unrestricted_fstat(int fd, struct fssh_stat *fsshStat)
{
struct stat st;
@@ -82,7 +77,7 @@ fssh_fstat(int fd, struct fssh_stat *fsshStat)
int
fssh_lstat(const char *path, struct fssh_stat *fsshStat)
FSShell::unrestricted_lstat(const char *path, struct fssh_stat *fsshStat)
{
struct stat st;
@@ -103,3 +98,47 @@ fssh_lstat(const char *path, struct fssh_stat *fsshStat)
return 0;
}
// #pragma mark -
int
fssh_mkdir(const char *path, fssh_mode_t mode)
{
return mkdir(path, to_platform_mode(mode));
}
int
fssh_stat(const char *path, struct fssh_stat *fsshStat)
{
if (FSShell::unrestricted_stat(path, fsshStat) < 0)
return -1;
FSShell::restricted_file_restrict_stat(fsshStat);
return 0;
}
int
fssh_fstat(int fd, struct fssh_stat *fsshStat)
{
if (FSShell::unrestricted_fstat(fd, fsshStat) < 0)
return -1;
FSShell::restricted_file_restrict_stat(fsshStat);
return 0;
}
int
fssh_lstat(const char *path, struct fssh_stat *fsshStat)
{
if (FSShell::unrestricted_lstat(path, fsshStat) < 0)
return -1;
FSShell::restricted_file_restrict_stat(fsshStat);
return 0;
}
+20
View File
@@ -0,0 +1,20 @@
/*
* Copyright 2008, Ingo Weinhold, ingo_weinhold@gmx.de.
* Distributed under the terms of the MIT License.
*/
#ifndef _FSSH_STAT_PRIV_H
#define _FSSH_STAT_PRIV_H
#include "fssh_defs.h"
namespace FSShell {
int unrestricted_stat(const char *path, struct fssh_stat *fsshStat);
int unrestricted_fstat(int fd, struct fssh_stat *fsshStat);
int unrestricted_lstat(const char *path, struct fssh_stat *fsshStat);
} // namespace FSShell
#endif // _FSSH_STAT_PRIV_H
+21 -1
View File
@@ -1,5 +1,5 @@
/*
* Copyright 2007, Ingo Weinhold, bonefish@cs.tu-berlin.de.
* Copyright 2007-2008, Ingo Weinhold, bonefish@cs.tu-berlin.de.
* Distributed under the terms of the MIT License.
*/
@@ -12,6 +12,8 @@
#include <errno.h>
#include <sys/uio.h>
#include "partition_support.h"
static const fssh_size_t kMaxIOVecs = 1024;
@@ -41,6 +43,11 @@ fssh_readv(int fd, const struct fssh_iovec *vector, fssh_size_t count)
if (!prepare_iovecs(vector, count, systemVecs))
return -1;
fssh_off_t pos = -1;
fssh_size_t length = 0;
if (FSShell::restricted_file_restrict_io(fd, pos, length) < 0)
return -1;
#if !defined(HAIKU_HOST_PLATFORM_FREEBSD)
return readv(fd, systemVecs, count);
#else
@@ -57,6 +64,10 @@ fssh_readv_pos(int fd, fssh_off_t pos, const struct fssh_iovec *vec,
if (!prepare_iovecs(vec, count, systemVecs))
return -1;
fssh_size_t length = 0;
if (FSShell::restricted_file_restrict_io(fd, pos, length) < 0)
return -1;
return readv_pos(fd, pos, systemVecs, count);
}
@@ -68,6 +79,11 @@ fssh_writev(int fd, const struct fssh_iovec *vector, fssh_size_t count)
if (!prepare_iovecs(vector, count, systemVecs))
return -1;
fssh_off_t pos = -1;
fssh_size_t length = 0;
if (FSShell::restricted_file_restrict_io(fd, pos, length) < 0)
return -1;
#if !defined(HAIKU_HOST_PLATFORM_FREEBSD)
return writev(fd, systemVecs, count);
#else
@@ -84,5 +100,9 @@ fssh_writev_pos(int fd, fssh_off_t pos, const struct fssh_iovec *vec,
if (!prepare_iovecs(vec, count, systemVecs))
return -1;
fssh_size_t length = 0;
if (FSShell::restricted_file_restrict_io(fd, pos, length) < 0)
return -1;
return writev_pos(fd, pos, systemVecs, count);
}
+38 -9
View File
@@ -1,5 +1,5 @@
/*
* Copyright 2007, Ingo Weinhold, bonefish@cs.tu-berlin.de.
* Copyright 2007-2008, Ingo Weinhold, ingo_weinhold@gmx.de.
* Distributed under the terms of the MIT License.
*/
@@ -15,6 +15,7 @@
#include "fssh_drivers.h"
#include "fssh_errno.h"
#include "partition_support.h"
#ifdef __BEOS__
# include <Drivers.h>
@@ -86,22 +87,28 @@ fssh_dup(int fd)
{
// Use the _kern_dup() defined in libroot on BeOS incompatible systems.
// Required for proper attribute emulation support.
int newFD;
#if __BEOS__
return dup(fd);
newFD = dup(fd);
#else
int result = _kern_dup(fd);
if (result < 0) {
fssh_set_errno(result);
return -1;
newFD = _kern_dup(fd);
if (newFD < 0) {
fssh_set_errno(newFD);
newFD = -1;
}
return result;
#endif
FSShell::restricted_file_duped(fd, newFD);
return newFD;
}
int
fssh_close(int fd)
{
FSShell::restricted_file_closed(fd);
// Use the _kern_close() defined in libroot on BeOS incompatible systems.
// Required for proper attribute emulation support.
#if __BEOS__
@@ -296,9 +303,16 @@ fssh_ssize_t
fssh_read(int fd, void *buffer, fssh_size_t count)
{
#if !defined(HAIKU_HOST_PLATFORM_FREEBSD)
fssh_off_t pos = -1;
if (FSShell::restricted_file_restrict_io(fd, pos, count) < 0)
return -1;
return read(fd, buffer, count);
#else
return read_pos(fd, lseek(fd, 0, SEEK_CUR), buffer, count);
fssh_ssize_t bytesRead = read_pos(fd, fssh_lseek(fd, 0, FSSH_SEEK_CUR),
buffer, count);
if (bytesRead > 0)
fssh_lseek(fd, bytesRead, FSSH_SEEK_CUR);
return bytesRead;
#endif
}
@@ -306,6 +320,8 @@ fssh_read(int fd, void *buffer, fssh_size_t count)
fssh_ssize_t
fssh_read_pos(int fd, fssh_off_t pos, void *buffer, fssh_size_t count)
{
if (FSShell::restricted_file_restrict_io(fd, pos, count) < 0)
return -1;
return read_pos(fd, pos, buffer, count);
}
@@ -314,20 +330,33 @@ fssh_ssize_t
fssh_write(int fd, const void *buffer, fssh_size_t count)
{
#if !defined(HAIKU_HOST_PLATFORM_FREEBSD)
fssh_off_t pos = -1;
if (FSShell::restricted_file_restrict_io(fd, pos, count) < 0)
return -1;
return write(fd, buffer, count);
#else
return write_pos(fd, lseek(fd, 0, SEEK_CUR), buffer, count);
fssh_ssize_t written = write_pos(fd, fssh_lseek(fd, 0, FSSH_SEEK_CUR),
buffer, count);
if (written > 0)
fssh_lseek(fd, written, FSSH_SEEK_CUR);
return written;
#endif
}
#include <stdio.h>
fssh_ssize_t
fssh_write_pos(int fd, fssh_off_t pos, const void *buffer, fssh_size_t count)
{
if (FSShell::restricted_file_restrict_io(fd, pos, count) < 0)
return -1;
return write_pos(fd, pos, buffer, count);
}
// fssh_lseek() -- implemented in partition_support.cpp
fssh_gid_t
fssh_getegid(void)
{