Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
Merge branch 'jb44353' into 'master'
[preload] Handle O_NOFOLLOW in vperm if flags are used.

See merge request mer-core/scratchbox2!46
  • Loading branch information
Matti Kosola committed Feb 8, 2021
2 parents 2076d6a + cc58880 commit cc1bcb9
Show file tree
Hide file tree
Showing 4 changed files with 77 additions and 36 deletions.
4 changes: 4 additions & 0 deletions scratchbox2/pathmapping/pathmapping_interf.c
Expand Up @@ -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
Expand Down Expand Up @@ -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.. */
Expand Down
36 changes: 33 additions & 3 deletions scratchbox2/preload/gen-interface.pl
Expand Up @@ -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
Expand Down Expand Up @@ -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;

Expand Down Expand Up @@ -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";
}
Expand Down
10 changes: 10 additions & 0 deletions scratchbox2/preload/interface.master
Expand Up @@ -184,61 +184,71 @@ 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) \
class(OPEN) conditionally_class(flags&O_CREAT,CREAT)

-- 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) \
class(OPEN) conditionally_class(flags&O_CREAT,CREAT)

-- 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) \
check_and_fail_if_readonly(flags&OPEN_FLAGS_RW_MODE,pathname,-1,EROFS) \
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) \
class(OPEN) conditionally_class(flags&O_CREAT,CREAT)

-- 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) \
Expand Down
63 changes: 30 additions & 33 deletions scratchbox2/preload/vperm_filestatgates.c
Expand Up @@ -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 */
Expand All @@ -1156,41 +1156,39 @@ 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)",
__func__, realfnname, pathname, modebits);
}
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) {
Expand All @@ -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);
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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;
Expand Down

0 comments on commit cc1bcb9

Please sign in to comment.