Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[sb2] Add gate for statx. JB#49501 #25

Merged
merged 1 commit into from Jan 29, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
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