Skip to content

Commit

Permalink
Use open instead of fopen to avoid calls to malloc
Browse files Browse the repository at this point in the history
If we are livepatching malloc we must be sure that we don't call it
during the process of writing the prologue, hence use `open` and
file descriptors instead of glibc `fopen`.

Signed-off-by: Giuliano Belinassi <[email protected]>
  • Loading branch information
giulianobelinassi committed Oct 17, 2024
1 parent 1a31aa2 commit 48c311c
Show file tree
Hide file tree
Showing 3 changed files with 21 additions and 16 deletions.
2 changes: 1 addition & 1 deletion include/ulp.h
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,7 @@ int __ulp_apply_patch();
void __ulp_print();

/* functions */
FILE *get_proc_mem(void);
int get_proc_mem(void);

void free_metadata(struct ulp_metadata *ulp);

Expand Down
4 changes: 2 additions & 2 deletions lib/interpose.c
Original file line number Diff line number Diff line change
Expand Up @@ -583,8 +583,8 @@ maybe_disable_livepatching_on_group(void)
static void
check_proc_mem_is_accessibe(void)
{
FILE *f = get_proc_mem();
if (f == NULL) {
int fd = get_proc_mem();
if (fd < 0) {
WARN("/proc/self/mem is inacessible: %s", libpulp_strerror(errno));
set_libpulp_error_state(EPROCMEM);
}
Expand Down
31 changes: 18 additions & 13 deletions lib/ulp.c
Original file line number Diff line number Diff line change
Expand Up @@ -88,30 +88,31 @@ begin(void)
msgq_push("libpulp loaded...\n");
}

/** @brief Attempt to get FILE pointer to /proc/self/mem
/** @brief Attempt to get file descriptor to /proc/self/mem
*
* Chroots may change the path to the /proc folder. This function attempts to
* discover it.
*
* @return file pointer.
*/
FILE *
int
get_proc_mem(void)
{
FILE *file = fopen("/proc/self/mem", "r+");
int fd = open("/proc/self/mem", O_WRONLY);

/* SLE have some processes which chroots into /proc. If the above fopen
fails then try this to check if this is the case. */
if (file == NULL && errno == ENOENT) {
if (fd < 0 && errno == ENOENT) {
/* Process has chroot'ed. Check if it was chroot'ed to /proc itself. */
file = fopen("/self/mem", "r+");
fd = open("/self/mem", O_WRONLY);
}

if (file == NULL) {
if (fd < 0) {
WARN("Attempting to open /proc/self/mem failed: %s", libpulp_strerror(errno));
set_libpulp_error_state(EPROCMEM);
}

return file;
return fd;
}

/** @brief Write into memory bypassing memory protections
Expand All @@ -128,14 +129,18 @@ get_proc_mem(void)
void *
memwrite(void *dest, const void *src, size_t n)
{
FILE *file = get_proc_mem();
libpulp_assert(file);
int fd = get_proc_mem();
off_t dst = (off_t) dest;

libpulp_assert(fseek(file, (size_t)dest, SEEK_SET) == 0);
libpulp_assert(fwrite(src, 1, n, file) == n);
if (fd < 0) {
return NULL;
}

fflush(file);
fclose(file);
libpulp_assert(lseek(fd, dst, SEEK_SET) == dst);
libpulp_assert(write(fd, src, n) == (ssize_t) n);

fsync(fd);
close(fd);

return dest;
}
Expand Down

0 comments on commit 48c311c

Please sign in to comment.