Commit cc1bcb98 authored by Matti Kosola's avatar Matti Kosola

Merge branch 'jb44353' into 'master'

[preload] Handle O_NOFOLLOW in vperm if flags are used.

See merge request !46
parents 2076d6a9 cc588808
......@@ -249,6 +249,9 @@ void sbox_map_path_at(
res->mres_readonly = 1;
return;
}
if (*virtual_path == '\0') {
goto end;
}
if ((*virtual_path == '/')
#ifdef AT_FDCWD
......@@ -287,6 +290,7 @@ void sbox_map_path_at(
return;
}
end:
/* name not found. Can't do much here, log a warning and return
* the original relative path. That will work if we are lucky, but
* not always.. */
......
......@@ -526,7 +526,38 @@ sub process_wrap_or_gate_modifiers {
my $fn = shift; # structure: parser results
my $all_modifiers = shift;
my @modifiers = split(/\s+/, $all_modifiers);
my @modifiers;
my $inside_braces;
my $build_mod;
# Split by space and then rebuild each modifier
foreach my $mod (split(/\s+/, $all_modifiers))
{
# First check if we are already rebuilding a modifier that previously started
# If not we need to check if a modifier with space is beginning
# but ignore one without space (eg. foo(bar))
if (!$inside_braces && $mod !~ m/(.*)\((.*)\)$/ && ($mod =~ m/([^\(]+)\)$/|| $mod =~ m/(.*)\(([^)]+)/)) {
$build_mod = "$mod ";
$inside_braces=1;
} else {
if ($inside_braces) {
$build_mod .= $mod;
if ($mod =~ m/(.*)\)$/) {
# Modifier with space ends
$inside_braces = 0;
push @modifiers, $build_mod;
undef $build_mod;
} else {
# There has to be space between each word in the middle of the modifier
$build_mod .= " ";
}
} else {
# Just a modifier without space
push @modifiers, $mod;
}
}
}
my $num_modifiers = @modifiers;
# cache some fn parser results to local vars
......@@ -592,7 +623,7 @@ sub process_wrap_or_gate_modifiers {
my $i;
for($i=0; $i < $num_modifiers; $i++) {
if($debug) { printf "\Modifier:'%s'\n", $modifiers[$i]; }
if($debug) { printf "Modifier:'%s'\n", $modifiers[$i]; }
if($modifiers[$i] =~ m/^map\((.*)\)$/) {
my $param_to_be_mapped = $1;
......@@ -1213,7 +1244,6 @@ sub command_wrap_or_gate {
# ..and the actual call.
my $call_line_prefix = "\t";
my $return_statement = ""; # return stmt not needed if fn_type==void
my $log_return_val = "";
if($mods->{'return_expr'}) {
$return_statement .= "\tret = ".$mods->{'return_expr'}.";\n";
}
......
......@@ -184,23 +184,27 @@ GATE: pid_t waitpid(pid_t pid, int *status, int options)
#define OPEN_FLAGS_RW_MODE (O_WRONLY|O_RDWR|O_APPEND|O_CREAT|O_TRUNC)
GATE: int __open(const char *pathname, int flags, ...) : \
dont_resolve_final_symlink_if(flags&O_NOFOLLOW) \
map(pathname) optional_arg_is_create_mode(flags&O_CREAT) \
postprocess(pathname) \
check_and_fail_if_readonly(flags&OPEN_FLAGS_RW_MODE,pathname,-1,EROFS) \
class(OPEN) conditionally_class(flags&O_CREAT,CREAT)
GATE: int __open64(const char *pathname, int flags, ...) : \
dont_resolve_final_symlink_if(flags&O_NOFOLLOW) \
map(pathname) optional_arg_is_create_mode(flags&O_CREAT) \
postprocess(pathname) \
check_and_fail_if_readonly(flags&OPEN_FLAGS_RW_MODE,pathname,-1,EROFS) \
class(OPEN) conditionally_class(flags&O_CREAT,CREAT)
GATE: int open(const char *pathname, int flags, ...) : \
dont_resolve_final_symlink_if(flags&O_NOFOLLOW) \
map(pathname) optional_arg_is_create_mode(flags&O_CREAT) \
postprocess(pathname) \
create_nomap_nolog_version \
check_and_fail_if_readonly(flags&OPEN_FLAGS_RW_MODE,pathname,-1,EROFS) \
class(OPEN) conditionally_class(flags&O_CREAT,CREAT)
GATE: int open64(const char *pathname, int flags, ...) : \
dont_resolve_final_symlink_if(flags&O_NOFOLLOW) \
map(pathname) optional_arg_is_create_mode(flags&O_CREAT) \
postprocess(pathname) \
check_and_fail_if_readonly(flags&OPEN_FLAGS_RW_MODE,pathname,-1,EROFS) \
......@@ -208,11 +212,13 @@ GATE: int open64(const char *pathname, int flags, ...) : \
-- open; variants witout varargs
GATE: int __open_2(const char *pathname, int flags) : \
dont_resolve_final_symlink_if(flags&O_NOFOLLOW) \
map(pathname) \
postprocess(pathname) \
check_and_fail_if_readonly(flags&OPEN_FLAGS_RW_MODE,pathname,-1,EROFS) \
class(OPEN) conditionally_class(flags&O_CREAT,CREAT)
GATE: int __open64_2(const char *pathname, int flags) : \
dont_resolve_final_symlink_if(flags&O_NOFOLLOW) \
map(pathname) \
postprocess(pathname) \
check_and_fail_if_readonly(flags&OPEN_FLAGS_RW_MODE,pathname,-1,EROFS) \
......@@ -220,6 +226,7 @@ GATE: int __open64_2(const char *pathname, int flags) : \
-- openat:
GATE: int openat(int dirfd, const char *pathname, int flags, ...) : \
dont_resolve_final_symlink_if(flags&O_NOFOLLOW) \
map_at(dirfd,pathname) optional_arg_is_create_mode(flags&O_CREAT) \
create_nomap_nolog_version \
postprocess(pathname) \
......@@ -227,6 +234,7 @@ GATE: int openat(int dirfd, const char *pathname, int flags, ...) : \
class(OPEN) conditionally_class(flags&O_CREAT,CREAT)
GATE: int openat64(int dirfd, const char *pathname, int flags, ...) : \
dont_resolve_final_symlink_if(flags&O_NOFOLLOW) \
map_at(dirfd,pathname) optional_arg_is_create_mode(flags&O_CREAT) \
postprocess(pathname) \
check_and_fail_if_readonly(flags&OPEN_FLAGS_RW_MODE,pathname,-1,EROFS) \
......@@ -234,11 +242,13 @@ GATE: int openat64(int dirfd, const char *pathname, int flags, ...) : \
-- openat; variants witout varargs
GATE: int __openat_2(int dirfd, const char *pathname, int flags) : \
dont_resolve_final_symlink_if(flags&O_NOFOLLOW) \
map_at(dirfd,pathname) \
postprocess(pathname) \
check_and_fail_if_readonly(flags&OPEN_FLAGS_RW_MODE,pathname,-1,EROFS) \
class(OPEN) conditionally_class(flags&O_CREAT,CREAT)
GATE: int __openat64_2(int dirfd, const char *pathname, int flags) : \
dont_resolve_final_symlink_if(flags&O_NOFOLLOW) \
map_at(dirfd,pathname) \
postprocess(pathname) \
check_and_fail_if_readonly(flags&OPEN_FLAGS_RW_MODE,pathname,-1,EROFS) \
......
......@@ -1140,11 +1140,11 @@ int mkdirat_gate(int *result_errno_ptr,
static int vperm_multiopen(
int log_enabled,
const char *realfnname,
int (*open_2_ptr)(const char *pathname, int flags),
int (*open_2va_ptr)(const char *pathname, int flags, ...),
int (*openat_3_ptr)(int dirfd, const char *pathname, int flags),
int (*open_3va_ptr)(int dirfd, const char *pathname, int flags, ...),
int (*creat_ptr)(const char *pathname, mode_t mode),
int (*open_2_ptr)(const char *pathname, int flags),
int (*openat_3_ptr)(int dirfd, const char *pathname, int flags),
FILE *(*fopen_ptr)(const char *path, const char *mode),
FILE *(*freopen_ptr)(const char *path, const char *mode, FILE *stream),
FILE **file_ptr, /* in: stream, out:result if function return FILE */
......@@ -1156,20 +1156,31 @@ static int vperm_multiopen(
{
FILE *f = NULL;
if (open_2va_ptr) {
if (log_enabled) {
SB_LOG(SB_LOGLEVEL_DEBUG, "%s: fd=%s(path='%s',flags=0x%X,mode=0%o)",
__func__, realfnname, pathname, flags, modebits);
}
if (log_enabled) {
if (open_2_ptr)
SB_LOG(SB_LOGLEVEL_DEBUG, "%s: fd=%s(path='%s',flags=0x%X)",
__func__, realfnname, pathname, flags);
if (open_2va_ptr)
SB_LOG(SB_LOGLEVEL_DEBUG, "%s: fd=%s(path='%s',flags=0x%X,mode=0%o)",
__func__, realfnname, pathname, flags, modebits);
if (openat_3_ptr)
SB_LOG(SB_LOGLEVEL_DEBUG, "%s: fd=%s(dirfd=%d,path='%s',flags=0x%X)",
__func__, realfnname, dirfd, pathname, flags);
if (open_3va_ptr)
SB_LOG(SB_LOGLEVEL_DEBUG, "%s: fd=%s(dirfd=%d,path='%s',flags=0x%X,mode=0%o)",
__func__, realfnname, dirfd, pathname, flags, modebits);
}
if (open_2_ptr)
return ((*open_2_ptr)(pathname, flags));
if (open_2va_ptr)
return ((*open_2va_ptr)(pathname, flags, modebits));
}
if (open_3va_ptr) {
if (log_enabled) {
SB_LOG(SB_LOGLEVEL_DEBUG, "%s: fd=%s(dirfd=%d,path='%s',flags=0x%X,mode=0%o)",
__func__, realfnname, dirfd, pathname, flags, modebits);
}
if (openat_3_ptr)
return ((*openat_3_ptr)(dirfd, pathname, flags));
if (open_3va_ptr)
return ((*open_3va_ptr)(dirfd, pathname, flags, modebits));
}
if (creat_ptr) {
if (log_enabled) {
SB_LOG(SB_LOGLEVEL_DEBUG, "%s: fd=%s(path='%s',mode=0%o)",
......@@ -1177,20 +1188,7 @@ static int vperm_multiopen(
}
return ((*creat_ptr)(pathname, modebits));
}
if (open_2_ptr) {
if (log_enabled) {
SB_LOG(SB_LOGLEVEL_DEBUG, "%s: fd=%s(path='%s',flags=0x%X)",
__func__, realfnname, pathname, flags);
}
return ((*open_2_ptr)(pathname, flags));
}
if (openat_3_ptr) {
if (log_enabled) {
SB_LOG(SB_LOGLEVEL_DEBUG, "%s: fd=%s(dirfd=%d,path='%s',flags=0x%X)",
__func__, realfnname, dirfd, pathname, flags);
}
return ((*openat_3_ptr)(dirfd, pathname, flags));
}
if (fopen_ptr) {
assert(file_ptr);
if (log_enabled) {
......@@ -1211,6 +1209,7 @@ static int vperm_multiopen(
*file_ptr = f;
return (f ? 0 : -1);
}
SB_LOG(SB_LOGLEVEL_ERROR, "%s: Internal error: 'open' function is missing (%s)",
__func__, realfnname);
return(-1);
......@@ -1250,8 +1249,7 @@ static int vperm_do_open(
/* try to open it */
res_fd = vperm_multiopen(1, realfnname,
open_2va_ptr, open_3va_ptr, creat_ptr,
open_2_ptr, openat_3_ptr,
open_2_ptr, open_2va_ptr, openat_3_ptr, open_3va_ptr, creat_ptr,
fopen_ptr, freopen_ptr, file_ptr, file_mode,
dirfd, mapped_pathname->mres_result_path, flags, modebits);
open_errno = errno;
......@@ -1299,9 +1297,8 @@ static int vperm_do_open(
* try again; if it won't open now,
* we just can't do it. */
res_fd = vperm_multiopen(0, realfnname,
open_2va_ptr, open_3va_ptr, creat_ptr,
open_2_ptr, openat_3_ptr,
fopen_ptr, freopen_ptr, file_ptr, file_mode,
open_2_ptr, open_2va_ptr, openat_3_ptr, open_3va_ptr,
creat_ptr, fopen_ptr, freopen_ptr, file_ptr, file_mode,
dirfd, mapped_pathname->mres_result_path,
flags, modebits);
open_errno = errno;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment