int filemngt_create_file_space(char *filename, size_t size, void **buffer_out, int *fd_out) { int result; *fd_out = open(filename, O_CREAT | O_EXCL | O_RDWR, 0700); if (*fd_out == -1) { err_printf("Could not create local file %s: %s\n", filename, strerror(errno)); return -1; } if (size == 0) { size = getpagesize(); debug_printf2("growing empty file to size %d", (int) size); } result = ftruncate(*fd_out, size); if (result == -1) { err_printf("Could not grow local file %s to %lu (out of memory?): %s\n", filename, size, strerror(errno)); close(*fd_out); return -1; } *buffer_out = mmap(NULL, size, PROT_READ | PROT_WRITE, MAP_SHARED, *fd_out, 0); if (*buffer_out == MAP_FAILED) { err_printf("Could not mmap file %s: %s\n", filename, strerror(errno)); close(*fd_out); return -1; } assert(*buffer_out); return 0; }
int ldcs_audit_server_fe_md_open ( char **hostlist, int numhosts, unsigned int port, unsigned int num_ports, unsigned int shared_secret, void **data ) { int rc=0; int *portlist; int root_fd, ack; int i; assert(num_ports >= 1); portlist = malloc(sizeof(int) * (num_ports+1)); for (i = 0; i < num_ports; i++) { portlist[i] = port + i; } portlist[num_ports] = 0; debug_printf2("Opening with port %d - %d\n", portlist[0], portlist[num_ports-1]); cobo_server_open(shared_secret, hostlist, numhosts, portlist, num_ports); free(portlist); cobo_server_get_root_socket(&root_fd); ldcs_cobo_read_fd(root_fd, &ack, sizeof(ack)); return(rc); }
static ssize_t readlink_worker(const char *path, char *buf, size_t bufsiz, char *newbuf, ssize_t rl_result) { char newpath[MAX_PATH_LEN+1]; char spindle_id[32]; int location_len; location_len = strlen(location); snprintf(spindle_id, sizeof(spindle_id), "spindle.%d", number); if (!strstr(newbuf, spindle_id) || strncmp(location, newbuf, location_len) != 0) { debug_printf3("readlink not intercepting, %s not prefixed by %s\n", newbuf, location); int len = strlen(newbuf); if (len > bufsiz) len = bufsiz; memcpy(buf, newbuf, len); return len; } send_orig_path_request(ldcsid, newbuf+location_len+1, newpath); int len = strlen(newpath); if (len > bufsiz) len = bufsiz; memcpy(buf, newpath, len); debug_printf2("readlink translated %s to %s to %s\n", path, newbuf, newpath); return len; }
int get_existance_test(int fd, const char *path, int *exists) { int use_cache = (opts & OPT_SHMCACHE) && (shm_cachesize > 0); int found_file, result; char cache_name[MAX_PATH_LEN+2]; char *exist_str; if (use_cache) { debug_printf2("Looking up file existance for %s in shared cache\n", path); get_cache_name(path, "&", cache_name); cache_name[sizeof(cache_name)-1] = '\0'; found_file = fetch_from_cache(cache_name, &exist_str); if (found_file) { *exists = (exist_str[0] == 'y'); return 0; } } result = send_existance_test(fd, (char *) path, exists); if (result == -1) return -1; if (use_cache) { exist_str = *exists ? "y" : "n"; shmcache_update(cache_name, exist_str); } return 0; }
int ldcs_audit_server_md_init(unsigned int port, unsigned int num_ports, unique_id_t unique_id, ldcs_process_data_t *data) { int rc=0; unsigned int *portlist; int my_rank, ranks, fanout; int i; portlist = malloc(sizeof(unsigned int) * (num_ports + 1)); for (i = 0; i < num_ports; i++) { portlist[i] = port + i; } portlist[num_ports] = 0; /* initialize the client (read environment variables) */ debug_printf2("Opening cobo with port %d - %d\n", portlist[0], portlist[num_ports-1]); if (cobo_open(unique_id, (int *) portlist, num_ports, &my_rank, &ranks) != COBO_SUCCESS) { printf("Failed to init\n"); exit(1); } debug_printf2("cobo_open complete. Cobo rank %d/%d\n", my_rank, ranks); free(portlist); data->server_stat.md_rank = data->md_rank = my_rank; data->server_stat.md_size = data->md_size = ranks; data->md_listen_to_parent = 0; cobo_get_num_childs(&fanout); data->server_stat.md_fan_out = data->md_fan_out = fanout; cobo_barrier(); /* send ack about being ready */ if (data->md_rank == 0) { int root_fd, ack=13; /* send fe client signal to stop (ack) */ cobo_get_parent_socket(&root_fd); ldcs_cobo_write_fd(root_fd, &ack, sizeof(ack)); debug_printf3("sent FE client signal that server are ready %d\n",ack); } return(rc); }
void *filemngt_sync_file_space(void *buffer, int fd, char *pathname, size_t size, size_t newsize) { /* Linux gets annoying here. We can't just mprotect the buffer to read-only, Linux considers the file still open for writing (and thus throws ETXTBUSY on exec's) as long as we still have the buffer mmaped from a fd that was opened with write. That means we've got to close the file, unmap the buffer, then re-open the file read-only, then re-map the buffer to the same place. Ugh. */ int result; char *buffer2; if (size == 0) { newsize = size = getpagesize(); debug_printf2("growing empty file to size %d", (int) size); } result = munmap(buffer, size); if (result == -1) { err_printf("Error unmapping buffer for %s\n", pathname); return NULL; } if (size != newsize) { assert(newsize < size); /* The file shrunk after we read it, probably because we stripped it as we read. Shrink the local file on disk and shrink the mapped region */ result = ftruncate(fd, newsize); if (result == -1) { err_printf("Could not shrink file in local disk\n"); return NULL; } } close(fd); fd = open(pathname, O_RDONLY); if (fd == -1) { err_printf("Failed to re-open file %s: %s\n", pathname, strerror(errno)); return NULL; } buffer2 = mmap(buffer, newsize, PROT_READ, MAP_SHARED | MAP_FIXED, fd, 0); if (buffer2 == MAP_FAILED) { debug_printf("Failure re-mapping file %s: %s. Retrying.\n", pathname, strerror(errno)); buffer2 = mmap(NULL, newsize, PROT_READ, MAP_SHARED, fd, 0); if (buffer2 == MAP_FAILED) { debug_printf("Could not re-mapping file %s: %s\n", pathname, strerror(errno)); return NULL; } } close(fd); return buffer2; }
int filemngt_read_file(char *filename, void *buffer, size_t *size, int strip, int *errcode) { FILE *f; int result = 0; debug_printf2("Reading file %s from disk\n", filename); f = fopen(filename, "r"); if (!f) { *errcode = errno; debug_printf2("Could not read file %s from disk, errcode = %d\n", filename, *errcode); return 0; } result = read_file_and_strip(f, buffer, size, strip); if (result == -1) err_printf("Error reading from file %s: %s\n", filename, strerror(errno)); fclose(f); return result; }
int client_done() { check_for_fork(); if (ldcsid == -1 || !use_ldcs) return 0; debug_printf2("Done. Closing connection %d\n", ldcsid); send_end(ldcsid); client_close_connection(ldcsid); return 0; }
void patch_on_load_success(const char *rewritten_name, const char *orig_name) { if (!(opts & OPT_DEBUG)) { return; } if (last_orig_name) spindle_free(last_orig_name); last_rewritten_name = (char *) rewritten_name; last_orig_name = spindle_strdup(orig_name); debug_printf2("Patching link map %s -> %s\n", rewritten_name, orig_name); }
size_t filemngt_get_file_size(char *pathname, int *errcode) { struct stat st; int result; result = stat(pathname, &st); if (result == -1) { if (errcode) *errcode = errno; debug_printf2("Could not stat file %s, perhaps bad symlink\n", pathname); return (size_t) -1; } return (size_t) st.st_size; }
int get_relocated_file(int fd, const char *name, char** newname, int *errorcode) { int found_file = 0; int use_cache = (opts & OPT_SHMCACHE) && (shm_cachesize > 0); char cache_name[MAX_PATH_LEN+1]; if (use_cache) { debug_printf2("Looking up %s in shared cache\n", name); get_cache_name(name, "", cache_name); cache_name[sizeof(cache_name)-1] = '\0'; found_file = fetch_from_cache(cache_name, newname); } if (!found_file) { debug_printf2("Send file request to server: %s\n", name); send_file_query(fd, (char *) name, newname, errorcode); debug_printf2("Recv file from server: %s\n", *newname ? *newname : "NONE"); if (use_cache) shmcache_update(cache_name, *newname); } return 0; }
static int execvp_wrapper(const char *path, char *const argv[]) { char newpath[MAX_PATH_LEN+1]; char **new_argv = NULL; int result, error; debug_printf2("Intercepted execvp on %s\n", path); find_exec_pathsearch(path, (char **) argv, newpath, MAX_PATH_LEN+1, &new_argv); debug_printf("execvp redirection of %s to %s\n", path, newpath); result = orig_execvp(newpath, new_argv ? new_argv : argv); error = errno; if (new_argv) spindle_free(new_argv); set_errno(error); return result; }
int readlinkat_wrapper(int dirfd, const char *path, char *buf, size_t bufsiz) { char newbuf[MAX_PATH_LEN+1]; ssize_t rl_result; debug_printf2("Intercepted readlink on %s\n", path); check_for_fork(); memset(newbuf, 0, MAX_PATH_LEN+1); rl_result = (ssize_t) orig_readlinkat(dirfd, path, newbuf, MAX_PATH_LEN); if (rl_result == -1) { return -1; } return (int) readlink_worker(path, buf, bufsiz, newbuf, rl_result); }
int get_ldso_metadata(signed int *binding_offset) { ldso_info_t info; int result; char filename[MAX_PATH_LEN+1]; find_interp_name(); debug_printf2("Requesting interpreter metadata for %s\n", interp_name); result = send_ldso_info_request(ldcsid, interp_name, filename); if (result == -1) return -1; read_ldso_metadata(filename, &info); *binding_offset = info.binding_offset; return 0; }
static int execlp_wrapper(const char *path, const char *arg0, ...) { int error, result; char newpath[MAX_PATH_LEN+1]; VARARG_TO_ARGV; debug_printf2("Intercepted execlp on %s\n", path); find_exec_pathsearch(path, argv, newpath, MAX_PATH_LEN+1, &new_argv); debug_printf("execlp redirection of %s to %s\n", path, newpath); result = execv(newpath, new_argv ? new_argv : argv); error = errno; VARARG_TO_ARGV_CLEANUP; set_errno(error); return result; }
int ldcs_recv_msg_static_pipe(int fd, ldcs_message_t *msg, ldcs_read_block_t block) { int n; int rc=0; msg->header.type=LDCS_MSG_UNKNOWN; msg->header.len=0; if ((fd<0) || (fd>fdlist_pipe_size) ) _error("wrong fd"); n = _ldcs_read_pipe(fdlist_pipe[fd].in_fd,&msg->header,sizeof(msg->header), block); if (n == 0) { /* Disconnect. Return an artificial client end message */ debug_printf2("Client disconnected. Returning END message\n"); msg->header.type = LDCS_MSG_END; msg->header.len = 0; msg->data = NULL; return(rc); } if (n < 0) _error("ERROR reading header from connection"); if(msg->header.len>0) { n = _ldcs_read_pipe(fdlist_pipe[fd].in_fd,msg->data,msg->header.len, LDCS_READ_BLOCK); if (n == 0) return(rc); if (n < 0) { int error = errno; err_printf("Error during read of pipe: %s (%d)\n", strerror(error), error); return -1; } if (n != msg->header.len) { int error = errno; err_printf("Partial read on pipe. Got %u / %u: %s (%d)\n", (unsigned) n, (unsigned) msg->header.len, strerror(error), error); return -1; } } else { *msg->data = '\0'; } debug_printf3("received message of type: %s len=%d data=%s ...\n", _message_type_to_str(msg->header.type), msg->header.len, msg->data ); return(rc); }
int get_stat_result(int fd, const char *path, int is_lstat, int *exists, struct stat *buf) { int result; char buffer[MAX_PATH_LEN+1]; char cache_name[MAX_PATH_LEN+3]; char *newpath; int use_cache = (opts & OPT_SHMCACHE) && (shm_cachesize > 0); int found_file = 0; if (use_cache) { debug_printf2("Looking up %sstat for %s in shared cache\n", is_lstat ? "l" : "", path); get_cache_name(path, is_lstat ? "**" : "*", cache_name); cache_name[sizeof(cache_name)-1] = '\0'; found_file = fetch_from_cache(cache_name, &newpath); } if (!found_file) { result = send_stat_request(fd, (char *) path, is_lstat, buffer); if (result == -1) { *exists = 0; return -1; } newpath = buffer[0] != '\0' ? buffer : NULL; if (use_cache) shmcache_update(cache_name, newpath); } if (newpath == NULL) { *exists = 0; return 0; } *exists = 1; test_log(newpath); result = read_stat(newpath, buf); if (result == -1) { err_printf("Failed to read stat info for %s from %s\n", path, newpath); *exists = 0; return -1; } return 0; }
ssize_t fd_read_ignoreEOF(int d, void *buf, size_t nbytes) { ssize_t left; ssize_t io_ret; char *s = (char*)buf; for (left = nbytes; left > 0; left -= io_ret){ fd_can_read_blocked(d); io_ret = read(d, s, left); if (io_ret <= 0 || exit_req == 1){ if (io_ret == 0){ debug_printf2("PIPE_EOF_EOF\n"); } return PIPE_ERROR; } s += io_ret; } return nbytes; }
static int execle_wrapper(const char *path, const char *arg0, ...) { int error, result; char **envp; char newpath[MAX_PATH_LEN+1]; VARARG_TO_ARGV; envp = va_arg(arglist, char **); debug_printf2("Intercepted execle on %s\n", path); find_exec(path, argv, newpath, MAX_PATH_LEN+1, &new_argv); debug_printf("execle redirection of %s to %s\n", path, newpath); result = execve(newpath, new_argv ? new_argv : argv, envp); error = errno; VARARG_TO_ARGV_CLEANUP; set_errno(error); return result; }
static int find_exec(const char *filepath, char **argv, char *newpath, int newpath_size, char ***new_argv) { char *newname = NULL; if (!filepath) { newpath[0] = '\0'; return 0; } check_for_fork(); if (ldcsid < 0 || !use_ldcs || exec_filter(filepath) != REDIRECT) { strncpy(newpath, filepath, newpath_size); newpath[newpath_size-1] = '\0'; return 0; } sync_cwd(); debug_printf2("Exec operation requesting file: %s\n", filepath); send_file_query(ldcsid, (char *) filepath, &newname); debug_printf("Exec file request returned %s -> %s\n", filepath, newname ? newname : "NULL"); return prep_exec(filepath, argv, newname, newpath, newpath_size, new_argv); }
static int fetch_from_cache(const char *name, char **newname) { int result; char *result_name; result = shmcache_lookup_or_add(name, &result_name); if (result == -1) return 0; debug_printf2("Shared cache has mapping from %s (%p) to %s (%p)\n", name, name, (result_name == in_progress) ? "[IN PROGRESS]" : (result_name ? result_name : "[NOT PRESENT]"), result_name); if (result_name == in_progress) { debug_printf("Waiting for update to %s\n", name); result = shmcache_waitfor_update(name, &result_name); if (result == -1) { debug_printf("Entry for %s deleted while waiting for update\n", name); return 0; } } *newname = result_name ? spindle_strdup(result_name) : NULL; return 1; }
void debug_assert_fail(const char *module, const int mlen, const char *function, const int flen, const char *file, int line, const char *expr) { debug_printf2(0, module, mlen, function, flen, 1, "%s:%d assertion failed:%s\n", file, line, expr); abort(); }