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

Auto mount in Docker containers (#1416) #1440

Merged
merged 30 commits into from
Jun 14, 2023
Merged
Show file tree
Hide file tree
Changes from 8 commits
Commits
Show all changes
30 commits
Select commit Hold shift + click to select a range
fe0076f
Initial support. Scope all processes in a docker container. Debug and…
iapaddler Apr 11, 2023
9aebf88
Use the defined libdir. Create intermediate dirs before a mount. Writ…
iapaddler Apr 12, 2023
d3828c5
Resolve an issue where subsequent docker run commands did not mount. …
iapaddler Apr 13, 2023
e5bc522
Mount the Edge socket from within a container.
iapaddler Apr 18, 2023
f62f9a9
Merge branch 'release/1.4' into feature/dockerd-mount-1416
iapaddler Apr 18, 2023
c836ad9
Support the case where some Go execs add the interface version, .abi0…
iapaddler Apr 19, 2023
8262c12
Applied review comments.
iapaddler Apr 19, 2023
84f58ef
Use the internal libc for mount.
iapaddler Apr 20, 2023
fd8f445
Merge branch 'release/1.4' into feature/dockerd-mount-1416
iapaddler May 8, 2023
365ab72
Resolved an issue with a unit test.
iapaddler May 8, 2023
add7847
Minor updates intended for clarity.
iapaddler May 8, 2023
20a69f1
WIP: startAutoMount() works, debug needs to be removed and the functi…
iapaddler May 9, 2023
2b62807
WIP: Auto mount from libscope.
iapaddler May 12, 2023
da43893
Added interposition of forkExec in wrap_go.c. Prepping for applying u…
iapaddler May 23, 2023
46625f4
Unit test enablement.
iapaddler May 23, 2023
ff6faff
Add arm64 asm changes
michalbiesek May 26, 2023
36b4f58
Add OCI test
michalbiesek May 29, 2023
59203f3
Add OCI rewrite
michalbiesek May 29, 2023
eff5287
Testing with alternate pclntab location.
iapaddler Jun 5, 2023
cacc545
Tested locating .gopclntab sections in Go 12, 16 & 20.
iapaddler Jun 5, 2023
3779fba
Located the embedded pclntab and update container config from OCI bac…
iapaddler Jun 7, 2023
b131cd9
Merge pull request #1498 from criblio/feat-oci-json-manipulation
iapaddler Jun 7, 2023
0366e69
Merged OCI config. Remove auto mount code from libscope and loader.
iapaddler Jun 7, 2023
aebfe69
Merge with relkease/1.4
iapaddler Jun 7, 2023
9f975a4
Resolved conflicts in start.go
iapaddler Jun 7, 2023
c4f730b
Removed mount from redfine list and a tap entry for forkExec.
iapaddler Jun 7, 2023
f4f5628
Fixed a copy/pasta error getting symbols from pclntab in Go 16/17.
iapaddler Jun 8, 2023
ad7ce02
Missed a free.
iapaddler Jun 14, 2023
79e9881
Merged with release/1.4
iapaddler Jun 14, 2023
6c77ea9
Remove console debug enable and a comment clarfication.
iapaddler Jun 14, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions contrib/redefine_syms.lst
Original file line number Diff line number Diff line change
Expand Up @@ -117,3 +117,4 @@ usleep scopelibc_usleep
vfprintf scopelibc_vfprintf
vsnprintf scopelibc_vsnprintf
write scopelibc_write
mount scopelibc_mount
1 change: 1 addition & 0 deletions src/dbg.c
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ bool g_ismusl = FALSE;
bool g_isstatic = FALSE;
bool g_isgo = FALSE;
bool g_issighandler = FALSE;
char g_libpath[PATH_MAX] = {};

void
dbgInit()
Expand Down
1 change: 1 addition & 0 deletions src/dbg.h
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,7 @@ extern bool g_ismusl;
extern bool g_isstatic;
extern bool g_isgo;
extern bool g_issighandler;
extern char g_libpath[];

void scopeLog(cfg_log_level_t, const char *, ...) PRINTF_FORMAT(2,3);
void scopeLogHex(cfg_log_level_t, const void *, size_t, const char *, ...) PRINTF_FORMAT(4,5);
Expand Down
2 changes: 2 additions & 0 deletions src/gocontext.S
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,8 @@
je 2f
cmp $SYS_close, %eax
je 2f
cmp $SYS_mount, %eax
je 2f

lea \retptr@GOTPCREL(%rip), %r13
mov (%r13), %r13
Expand Down
2 changes: 2 additions & 0 deletions src/gocontext_arm.S
Original file line number Diff line number Diff line change
Expand Up @@ -121,6 +121,8 @@
b.eq 2f
cmp x8, #SYS_close
b.eq 2f
cmp x8, #SYS_mount
b.eq 2f

ldr x17, =\retptr
ldr x17, [x17]
Expand Down
8 changes: 8 additions & 0 deletions src/scopestdlib.c
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,7 @@ extern int scopelibc_rename(const char *, const char *);
extern int scopelibc_remove(const char *);
extern int scopelibc_pipe2(int [2], int);
extern void scopelibc_setbuf(FILE *, char *);
extern int scopelibc_mount(const char *, const char *, const char *, unsigned long, const void *);

// String handling operations
extern char * scopelibc_realpath(const char *, char *);
Expand Down Expand Up @@ -518,6 +519,13 @@ scope_mkdir(const char *pathname, mode_t mode) {
return scopelibc_mkdir(pathname, mode);
}

int
scope_mount(const char *source, const char *target,
const char *fstype, unsigned long flags,
const void *data) {
return scopelibc_mount(source, target, fstype, flags, data);
}

int
scope_chdir(const char *path) {
return scopelibc_chdir(path);
Expand Down
1 change: 1 addition & 0 deletions src/scopestdlib.h
Original file line number Diff line number Diff line change
Expand Up @@ -162,6 +162,7 @@ int scope_fileno(FILE *);
int scope_flock(int, int);
int scope_fstat(int, struct stat *);
int scope_mkdir(const char *, mode_t);
int scope_mount(const char *, const char *, const char *, unsigned long, const void *);
int scope_chdir(const char *);
int scope_rmdir(const char *);
char* scope_get_current_dir_name(void);
Expand Down
2 changes: 2 additions & 0 deletions src/scopetypes.h
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,8 @@ typedef enum {CFG_MTC_FS,
#define SM_NAME "scope_anon"
#define SCOPE_FILTER_USR_PATH ("/usr/lib/appscope/scope_filter")
#define SCOPE_FILTER_TMP_PATH ("/tmp/appscope/scope_filter")
#define SCOPE_SYS_PATH "/usr/lib/appscope/"
#define SCOPE_TMP_PATH "/tmp/appscope/"

typedef unsigned int bool;
#define TRUE 1
Expand Down
32 changes: 1 addition & 31 deletions src/transport.c
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
#include "scopestdlib.h"
#include "fn.h"
#include "transport.h"
#include "utils.h"

// Yuck. Avoids naming conflict between our src/wrap.c and libssl.a
#define SSL_read SCOPE_SSL_read
Expand Down Expand Up @@ -1018,37 +1019,6 @@ transportConnectFile(transport_t *t)
return 1;
}

#define EDGE_PATH_DOCKER "/var/run/appscope/appscope.sock"
#define EDGE_PATH_DEFAULT "/opt/cribl/state/appscope.sock"
#define READ_AND_WRITE (R_OK|W_OK)
static char*
edgePath(void){
// 1) If EDGE_PATH_DOCKER can be accessed, return that.
if (scope_access(EDGE_PATH_DOCKER, READ_AND_WRITE) == 0) {
return scope_strdup(EDGE_PATH_DOCKER);
}

// 2) If CRIBL_HOME is defined and can be accessed,
// return $CRIBL_HOME/state/appscope.sock
const char *cribl_home = getenv("CRIBL_HOME");
if (cribl_home) {
char *new_path = NULL;
if (scope_asprintf(&new_path, "%s/%s", cribl_home, "state/appscope.sock") > 0) {
if (scope_access(new_path, READ_AND_WRITE) == 0) {
return new_path;
}
scope_free(new_path);
}
}

// 3) If EDGE_PATH_DEFAULT can be accessed, return it
if (scope_access(EDGE_PATH_DEFAULT, READ_AND_WRITE) == 0) {
return scope_strdup(EDGE_PATH_DEFAULT);
}

return NULL;
}

int
transportConnect(transport_t *trans)
{
Expand Down
102 changes: 102 additions & 0 deletions src/utils.c
Original file line number Diff line number Diff line change
Expand Up @@ -494,3 +494,105 @@ sigSafeWriteNumber(int fd, long val, int base) {
return scope_write(fd, buf ,msgLen);
}

/*
* Returns normalized version string
* - "dev" for unofficial release
* - "%d.%d.%d" for official release (e.g. "1.3.0" for "v1.3.0")
* - "%d.%d.%d-%s%d" for candidate release (e.g. "1.3.0-rc0" for "v1.3.0-rc0")
*/
const char *
libVersion(const char *version) {

if ((version == NULL) || (*version != 'v')) {
return "dev";
}

++version;
size_t versionSize = scope_strlen(version);

for (int i = 0; i < versionSize; ++i) {
// Only digit and "." are accepted
if ((scope_isdigit(version[i]) == 0) && version[i] != '.' &&
version[i] != '-' && version[i] != 't' && version[i] != 'c' &&
version[i] != 'r') {
return "dev";
}
if (i == 0 || i == versionSize) {
// First and last character must be number
if (scope_isdigit(version[i]) == 0) {
return "dev";
}
}
}
return version;
}

/*
* The mkdir system call does not support the creation of intermediate dirs.
* This will walk the path and create all dirs one at a time.
*/
bool
makeIntermediateDirs(const char *path, mode_t mode) {
michalbiesek marked this conversation as resolved.
Show resolved Hide resolved
char *dup_path = scope_strdup(path);
if (!dup_path) {
return FALSE;
}

char *curr = dup_path;
char *slash;

while ((slash = scope_strrchr(curr, '/'))) {
*slash = '\0';
if (scope_mkdir(dup_path, mode) == -1) {
if (scope_errno != EEXIST) {
scope_free(dup_path);
return FALSE;
}
}

*slash = '/';
curr = slash + 1;
}

if (scope_mkdir(dup_path, mode) == -1) {
if (scope_errno != EEXIST) {
scope_free(dup_path);
return FALSE;
}
}

scope_free(dup_path);
return TRUE;
}

#define EDGE_PATH_DOCKER "/var/run/appscope/appscope.sock"
#define EDGE_PATH_DEFAULT "/opt/cribl/state/appscope.sock"
#define READ_AND_WRITE (R_OK|W_OK)

char *
edgePath(void) {
// 1) If EDGE_PATH_DOCKER can be accessed, return that.
if (scope_access(EDGE_PATH_DOCKER, READ_AND_WRITE) == 0) {
return scope_strdup(EDGE_PATH_DOCKER);
}

// 2) If CRIBL_HOME is defined and can be accessed,
// return $CRIBL_HOME/state/appscope.sock
const char *cribl_home = getenv("CRIBL_HOME");
if (cribl_home) {
char *new_path = NULL;
if (scope_asprintf(&new_path, "%s/%s", cribl_home, "state/appscope.sock") > 0) {
if (scope_access(new_path, READ_AND_WRITE) == 0) {
return new_path;
}
scope_free(new_path);
}
}

// 3) If EDGE_PATH_DEFAULT can be accessed, return it
if (scope_access(EDGE_PATH_DEFAULT, READ_AND_WRITE) == 0) {
return scope_strdup(EDGE_PATH_DEFAULT);
}

return NULL;
}
4 changes: 4 additions & 0 deletions src/utils.h
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,10 @@ int endsWith(const char *, const char *);
void setUUID(char *);
void setMachineID(char *);

char *edgePath(void);
bool makeIntermediateDirs(const char *, mode_t);
const char *libVersion(const char *);

// Signal Safe API
int sigSafeNanosleep(const struct timespec *);
void sigSafeUtoa(unsigned long, char *, int, int *);
Expand Down
18 changes: 18 additions & 0 deletions src/wrap.c
Original file line number Diff line number Diff line change
Expand Up @@ -1731,6 +1731,24 @@ init(void)
bool scopedFlag = FALSE;
bool skipReadCfg = FALSE;

/*
* This might be able to merge with the filter file check below.
* However, we dont want to check a specific file. We may update
* how we define the filter file. So, for now, leaving them
* distinct.
*
* Would be nice to use an env var without the need to access
* a file. However, we don't rely on something like SCOPE_LIB_PATH
* when LD_PRELOAD alone is used.
*/
if (!scope_access(SCOPE_SYS_PATH, R_OK)) {
scope_strncpy(g_libpath, SCOPE_SYS_PATH, sizeof(SCOPE_SYS_PATH));
} else if (!scope_access(SCOPE_TMP_PATH, R_OK)) {
scope_strncpy(g_libpath, SCOPE_TMP_PATH, sizeof(SCOPE_TMP_PATH));
}

scope_strncat(g_libpath, libVersion(SCOPE_VER), sizeof(SCOPE_VER));

if (attachedFlag) {
scopedFlag = TRUE;
} else {
Expand Down
Loading