Reputation: 2735
Just got confused when I am learning the virtual memory system in Linux.
Since each process has its own virtual address space and its own page table translating its virtual address to physical address(am I right?), how can it possibly try to falsely access other process's memory? There should be no entry in the page table, right?
Upvotes: 5
Views: 9752
Reputation: 400
In addition to procfs, it is also possible to access other process memory using process_vm_writev and process_vm_readv
This program will read a given nubmer of bytes from a given address of a given process (removed some error checks to improve readability):
#define _GNU_SOURCE
#include <sys/uio.h>
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
int remote_process_read(pid_t remote_pid, void *address, char *buffer, size_t len)
{
struct iovec local[1] = {};
struct iovec remote[1] = {};
int errsv = 0;
ssize_t nread = 0;
local[0].iov_len = len;
local[0].iov_base = (void *)buffer;
remote[0].iov_base = address;
remote[0].iov_len = local[0].iov_len;
nread = process_vm_readv(remote_pid, local, 2, remote, 1, 0);
if (nread != local[0].iov_len)
{
errsv = errno;
fprintf(stderr, "Failed reading. process_vm_readv returned: %ld. Errno: %d\n", nread, errsv);
return errsv;
}
return errno;
}
enum
{
ARG_APP_NAME = 0,
ARG_PID,
ARG_ADDRESS,
ARG_BYTES_TO_READ,
ARG_COUNT
};
int main(int argc, char *argv[])
{
pid_t remote_pid = 0;
size_t len = 0;
int ret = 1;
char *buffer = NULL;
void *remote_address = NULL;
if (ARG_COUNT != argc)
{
fprintf(stderr, "Usage: %s <PID> <address (hex)> <num of bytes to read (hex)>\n", argv[ARG_APP_NAME]);
goto clean;
}
remote_pid = strtol(argv[ARG_PID], NULL, 10);
remote_address = (void *)strtoul(argv[ARG_ADDRESS], NULL, 16);
len = strtoul(argv[ARG_BYTES_TO_READ], NULL, 16);
buffer = malloc(len);
if (0 != remote_process_read(remote_pid, remote_address, buffer, len))
{
goto clean;
}
printf("Read Successfully!\n");
for (size_t i = 0; i < len; i++)
{
printf("%02X", buffer[i]);
}
printf("\n");
ret = 0;
clean:
free(buffer);
return ret;
}
Upvotes: 5
Reputation: 126185
A linux process can access another process's memory via the special file /proc/pid/mem. For example, here's a little program call poke
:
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <unistd.h>
int main(int ac, char **av) {
char name[64];
int fd;
if (ac != 3) {
fprintf(stderr, "usage: %s pid address value\n", av[1]);
exit(1); }
sprintf(name, "/proc/%.10s/mem", av[1]);
if ((fd = open(name, O_WRONLY)) < 0) {
fprintf(stderr, "Can't access pid %s", av[1]);
perror(":");
exit(1); }
lseek(fd, strtol(av[2], 0, 0), SEEK_SET);
if (write(fd, av[3], strlen(av[3])) < 0)
perror("write");
return 0;
}
It will write a string into another process's memory (probably causing it to crash)...
Upvotes: 17
Reputation: 182753
Unless specifically arranged, there should be no virtual address one process can access that will modify memory assigned to another process.
Upvotes: 1