Skip to content

Commit

Permalink
[sb2] Add gate for statx. JB#49501
Browse files Browse the repository at this point in the history
  • Loading branch information
mlehtima committed Jan 29, 2024
1 parent 19f8f68 commit 0ecaef5
Show file tree
Hide file tree
Showing 5 changed files with 115 additions and 5 deletions.
1 change: 1 addition & 0 deletions configure.ac
Expand Up @@ -164,6 +164,7 @@ setenv \
setxattr \
stat \
stat64 \
statx \
strchrnul \
symlink \
symlinkat \
Expand Down
4 changes: 4 additions & 0 deletions include/sb2_stat.h
Expand Up @@ -24,6 +24,10 @@ extern int real_fstatat64(int dirfd, const char *path, struct stat64 *statbuf, i
extern int i_virtualize_struct_stat(const char *realfnname,
struct stat *buf, struct stat64 *buf64);

#ifdef HAVE_STATX
extern int i_virtualize_struct_statx(const char *realfnname, struct statx *bufx);
#endif

extern int sb2_stat_file(const char *path, struct stat *buf, int *result_errno_ptr,
int (*statfn_with_ver_ptr)(int ver, const char *filename, struct stat *buf),
int ver,
Expand Down
7 changes: 7 additions & 0 deletions preload/interface.master
Expand Up @@ -667,6 +667,13 @@ WRAP: int stat(const char *file_name, struct stat *buf) : \
create_nomap_nolog_version \
map(file_name) class(STAT)

#ifdef HAVE_STATX
GATE: int statx(int dirfd, const char *__restrict pathname, int flags, \
unsigned int mask, struct statx *__restrict buf) : \
dont_resolve_final_symlink_if(flags&AT_SYMLINK_NOFOLLOW) \
map_at(dirfd,pathname) class(STAT)
#endif

#ifdef HAVE_STAT64
WRAP: int stat64(const char *file_name, struct stat64 *buf) : map(file_name) class(STAT) \
create_nomap_nolog_version
Expand Down
23 changes: 23 additions & 0 deletions preload/vperm_filestatgates.c
Expand Up @@ -254,6 +254,29 @@ int __fxstatat64_gate(int *result_errno_ptr,
return(res);
}

#ifdef HAVE_STATX
int statx_gate(int *result_errno_ptr,
int (*real_statx_ptr)(int dirfd, const char *__restrict pathname, int flags,
unsigned int mask, struct statx *__restrict buf),
const char *realfnname,
int dirfd,
const mapping_results_t *mapped_filename,
int flags,
unsigned int mask,
struct statx *__restrict buf)
{
int res;

res = (*real_statx_ptr)(dirfd, mapped_filename->mres_result_path, flags, mask, buf);
if (res == 0) {
i_virtualize_struct_statx(realfnname, buf);
} else {
*result_errno_ptr = errno;
}
return(res);
}
#endif

/* ======================= chown() variants ======================= */

static void vperm_chown(
Expand Down
85 changes: 80 additions & 5 deletions preload/vperm_statfuncts.c
Expand Up @@ -8,6 +8,7 @@
#include <errno.h>
#include <stdint.h>
#include <string.h>
#include <sys/sysmacros.h>
#include "sb2.h"
#include "sb2_stat.h"
#include "sb2_vperm.h"
Expand Down Expand Up @@ -114,11 +115,15 @@ int real_fstat64(int fd, struct stat64 *statbuf)
}

/* return 0 if not modified, positive if something was virtualized.
* only one of {buf,buf64} should be set; set the other one to NULL */
int i_virtualize_struct_stat(
const char *realfnname,
struct stat *buf,
struct stat64 *buf64)
* only one of {buf,bufx,buf64} should be set; set the other ones to NULL */
int i_virtualize_struct_stat_internal(
const char *realfnname
, struct stat *buf
, struct stat64 *buf64
#ifdef HAVE_STATX
, struct statx *bufx
#endif
)
{
int res = 0;
ruletree_inodestat_handle_t handle;
Expand All @@ -129,6 +134,12 @@ int i_virtualize_struct_stat(
ruletree_clear_inodestat_handle(&handle);
if (buf) {
ruletree_init_inodestat_handle(&handle, buf->st_dev, buf->st_ino);
#ifdef HAVE_STATX
} else if (bufx) {
ruletree_init_inodestat_handle(&handle,
gnu_dev_makedev(bufx->stx_dev_major, bufx->stx_dev_minor),
bufx->stx_ino);
#endif
} else {
ruletree_init_inodestat_handle(&handle, buf64->st_dev, buf64->st_ino);
}
Expand All @@ -145,13 +156,19 @@ int i_virtualize_struct_stat(
"%s/%s: found, set uid to %d",
realfnname, __func__, istat_in_db.inodesimu_uid);
if (buf) buf->st_uid = istat_in_db.inodesimu_uid;
#ifdef HAVE_STATX
else if (bufx) bufx->stx_uid = istat_in_db.inodesimu_uid;
#endif
else buf64->st_uid = istat_in_db.inodesimu_uid;
res++;
} else if (set_uid_gid_of_unknown) {
SB_LOG(SB_LOGLEVEL_DEBUG,
"%s/%s: 'unknown' file, set owner to %d",
realfnname, __func__, uf_uid);
if (buf) buf->st_uid = uf_uid;
#ifdef HAVE_STATX
else if (bufx) bufx->stx_uid = uf_uid;
#endif
else buf64->st_uid = uf_uid;
res++;
}
Expand All @@ -162,13 +179,19 @@ int i_virtualize_struct_stat(
"%s/%s: found, set gid to %d",
realfnname, __func__, istat_in_db.inodesimu_gid);
if (buf) buf->st_gid = istat_in_db.inodesimu_gid;
#ifdef HAVE_STATX
else if (bufx) bufx->stx_gid = istat_in_db.inodesimu_gid;
#endif
else buf64->st_gid = istat_in_db.inodesimu_gid;
res++;
} else if (set_uid_gid_of_unknown) {
SB_LOG(SB_LOGLEVEL_DEBUG,
"%s/%s: 'unknown' file, set group to %d",
realfnname, __func__, uf_gid);
if (buf) buf->st_gid = uf_gid;
#ifdef HAVE_STATX
else if (bufx) bufx->stx_gid = uf_gid;
#endif
else buf64->st_gid = uf_gid;
res++;
}
Expand All @@ -181,6 +204,11 @@ int i_virtualize_struct_stat(
if (buf) buf->st_mode =
(buf->st_mode & S_IFMT) |
(istat_in_db.inodesimu_mode & (~S_IFMT));
#ifdef HAVE_STATX
else if (bufx) bufx->stx_mode =
(bufx->stx_mode & S_IFMT) |
(istat_in_db.inodesimu_mode & (~S_IFMT));
#endif
else buf64->st_mode =
(buf64->st_mode & S_IFMT) |
(istat_in_db.inodesimu_mode & (~S_IFMT));
Expand All @@ -194,6 +222,11 @@ int i_virtualize_struct_stat(
if (buf) buf->st_mode =
(buf->st_mode & ~(S_ISUID | S_ISGID)) |
(istat_in_db.inodesimu_suidsgid & (S_ISUID | S_ISGID));
#ifdef HAVE_STATX
else if (bufx) bufx->stx_mode =
(bufx->stx_mode & ~(S_ISUID | S_ISGID)) |
(istat_in_db.inodesimu_suidsgid & (S_ISUID | S_ISGID));
#endif
else buf64->st_mode =
(buf64->st_mode & ~(S_ISUID | S_ISGID)) |
(istat_in_db.inodesimu_suidsgid & (S_ISUID | S_ISGID));
Expand All @@ -210,6 +243,14 @@ int i_virtualize_struct_stat(
(buf->st_mode & (~S_IFMT)) |
(istat_in_db.inodesimu_devmode & S_IFMT);
buf->st_rdev = istat_in_db.inodesimu_rdev;
#ifdef HAVE_STATX
} else if (bufx) {
bufx->stx_mode =
(bufx->stx_mode & (~S_IFMT)) |
(istat_in_db.inodesimu_devmode & S_IFMT);
bufx->stx_rdev_major = major(istat_in_db.inodesimu_rdev);
bufx->stx_rdev_minor = minor(istat_in_db.inodesimu_rdev);
#endif
} else {
buf64->st_mode =
(buf64->st_mode & (~S_IFMT)) |
Expand All @@ -223,8 +264,14 @@ int i_virtualize_struct_stat(
"%s/%s: 'unknown' file, set owner and group to %d.%d",
realfnname, __func__, uf_uid, uf_gid);
if (buf) buf->st_uid = uf_uid;
#ifdef HAVE_STATX
else if (bufx) bufx->stx_uid = uf_uid;
#endif
else buf64->st_uid = uf_uid;
if (buf) buf->st_gid = uf_gid;
#ifdef HAVE_STATX
else if (bufx) bufx->stx_gid = uf_gid;
#endif
else buf64->st_gid = uf_gid;
res += 2;
}
Expand All @@ -233,6 +280,34 @@ int i_virtualize_struct_stat(
return(res);
}

/* return 0 if not modified, positive if something was virtualized.
* only one of {buf,buf64} should be set; set the other one to NULL */
int i_virtualize_struct_stat(
const char *realfnname,
struct stat *buf,
struct stat64 *buf64)
{
return i_virtualize_struct_stat_internal(realfnname
, buf
, buf64
#ifdef HAVE_STATX
, NULL
#endif
);
}

#ifdef HAVE_STATX
int i_virtualize_struct_statx(
const char *realfnname,
struct statx *buf)
{
return i_virtualize_struct_stat_internal(realfnname
, NULL
, NULL
, buf);
}
#endif

int sb2_stat_file(const char *path, struct stat *buf, int *result_errno_ptr,
int (*statfn_with_ver_ptr)(int ver, const char *filename, struct stat *buf),
int ver,
Expand Down

0 comments on commit 0ecaef5

Please sign in to comment.