2006-08-18 19:46:20 +00:00
|
|
|
/***
|
2007-10-28 19:13:50 +00:00
|
|
|
This file is part of PulseAudio.
|
2007-01-04 13:43:45 +00:00
|
|
|
|
2007-10-28 19:13:50 +00:00
|
|
|
Copyright 2006 Lennart Poettering
|
|
|
|
|
Copyright 2006 Pierre Ossman <ossman@cendio.se> for Cendio AB
|
2007-02-13 15:35:19 +00:00
|
|
|
|
2007-10-28 19:13:50 +00:00
|
|
|
PulseAudio is free software; you can redistribute it and/or modify
|
|
|
|
|
it under the terms of the GNU Lesser General Public License as
|
|
|
|
|
published by the Free Software Foundation; either version 2.1 of the
|
|
|
|
|
License, or (at your option) any later version.
|
2007-01-04 13:43:45 +00:00
|
|
|
|
2007-10-28 19:13:50 +00:00
|
|
|
PulseAudio is distributed in the hope that it will be useful, but
|
|
|
|
|
WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
|
|
|
Lesser General Public License for more details.
|
2007-01-04 13:43:45 +00:00
|
|
|
|
2007-10-28 19:13:50 +00:00
|
|
|
You should have received a copy of the GNU Lesser General Public
|
2014-11-26 14:14:51 +01:00
|
|
|
License along with PulseAudio; if not, see <http://www.gnu.org/licenses/>.
|
2006-08-18 19:46:20 +00:00
|
|
|
***/
|
|
|
|
|
|
2006-08-19 17:27:27 +00:00
|
|
|
#ifdef HAVE_CONFIG_H
|
|
|
|
|
#include <config.h>
|
|
|
|
|
#endif
|
|
|
|
|
|
2006-08-18 19:46:20 +00:00
|
|
|
#include <stdlib.h>
|
|
|
|
|
#include <unistd.h>
|
|
|
|
|
#include <fcntl.h>
|
|
|
|
|
#include <stdio.h>
|
|
|
|
|
#include <errno.h>
|
|
|
|
|
#include <string.h>
|
|
|
|
|
#include <sys/stat.h>
|
2007-10-28 19:13:50 +00:00
|
|
|
#include <sys/types.h>
|
|
|
|
|
#include <dirent.h>
|
|
|
|
|
#include <signal.h>
|
2006-08-18 19:46:20 +00:00
|
|
|
|
2006-08-22 11:41:14 +00:00
|
|
|
#ifdef HAVE_SYS_MMAN_H
|
|
|
|
|
#include <sys/mman.h>
|
|
|
|
|
#endif
|
|
|
|
|
|
2009-06-24 22:08:41 +02:00
|
|
|
/* This is deprecated on glibc but is still used by FreeBSD */
|
|
|
|
|
#if !defined(MAP_ANONYMOUS) && defined(MAP_ANON)
|
|
|
|
|
# define MAP_ANONYMOUS MAP_ANON
|
|
|
|
|
#endif
|
|
|
|
|
|
2007-10-28 19:13:50 +00:00
|
|
|
#include <pulse/xmalloc.h>
|
2008-05-15 23:34:41 +00:00
|
|
|
#include <pulse/gccmacro.h>
|
2007-10-28 19:13:50 +00:00
|
|
|
|
pulsecore: Introduce memfd support
Memfd is a simple memory sharing mechanism, added by the systemd/kdbus
developers, to share pages between processes in an anonymous, no global
registry needed, no mount-point required, relatively secure, manner.
This patch introduces the necessary building blocks for using memfd
shared memory transfers in PulseAudio.
Memfd support shall also help us in laying out the necessary (but not
yet sufficient) groundwork for application sandboxing, protecting PA
from its clients, and protecting clients data from each other.
We plan to exclusively use memfds, instead of POSIX SHM, on the way
forward.
Signed-off-by: Ahmed S. Darwish <darwish.07@gmail.com>
2016-03-13 01:04:18 +02:00
|
|
|
#include <pulsecore/memfd-wrappers.h>
|
2006-08-18 19:46:20 +00:00
|
|
|
#include <pulsecore/core-error.h>
|
|
|
|
|
#include <pulsecore/log.h>
|
|
|
|
|
#include <pulsecore/random.h>
|
2007-10-28 19:13:50 +00:00
|
|
|
#include <pulsecore/core-util.h>
|
|
|
|
|
#include <pulsecore/macro.h>
|
|
|
|
|
#include <pulsecore/atomic.h>
|
2016-03-13 00:57:06 +02:00
|
|
|
#include <pulsecore/mem.h>
|
2006-08-18 19:46:20 +00:00
|
|
|
|
|
|
|
|
#include "shm.h"
|
|
|
|
|
|
|
|
|
|
#if defined(__linux__) && !defined(MADV_REMOVE)
|
|
|
|
|
#define MADV_REMOVE 9
|
2007-01-04 13:43:45 +00:00
|
|
|
#endif
|
2006-08-18 19:46:20 +00:00
|
|
|
|
2009-08-14 04:14:35 +02:00
|
|
|
/* 1 GiB at max */
|
|
|
|
|
#define MAX_SHM_SIZE (PA_ALIGN(1024*1024*1024))
|
2007-10-28 19:13:50 +00:00
|
|
|
|
|
|
|
|
#ifdef __linux__
|
|
|
|
|
/* On Linux we know that the shared memory blocks are files in
|
|
|
|
|
* /dev/shm. We can use that information to list all blocks and
|
|
|
|
|
* cleanup unused ones */
|
|
|
|
|
#define SHM_PATH "/dev/shm/"
|
2013-01-04 16:31:57 +02:00
|
|
|
#define SHM_ID_LEN 10
|
|
|
|
|
#elif defined(__sun)
|
|
|
|
|
#define SHM_PATH "/tmp"
|
|
|
|
|
#define SHM_ID_LEN 15
|
2007-10-28 19:13:50 +00:00
|
|
|
#else
|
|
|
|
|
#undef SHM_PATH
|
2013-01-04 16:31:57 +02:00
|
|
|
#undef SHM_ID_LEN
|
2007-10-28 19:13:50 +00:00
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
#define SHM_MARKER ((int) 0xbeefcafe)
|
|
|
|
|
|
2008-05-15 23:34:41 +00:00
|
|
|
/* We now put this SHM marker at the end of each segment. It's
|
2009-05-14 19:51:05 +02:00
|
|
|
* optional, to not require a reboot when upgrading, though. Note that
|
|
|
|
|
* on multiarch systems 32bit and 64bit processes might access this
|
2011-08-24 18:24:46 +02:00
|
|
|
* region simultaneously. The header fields need to be independent
|
2009-05-14 19:51:05 +02:00
|
|
|
* from the process' word with */
|
2009-02-13 18:02:47 +01:00
|
|
|
struct shm_marker {
|
2007-10-28 19:13:50 +00:00
|
|
|
pa_atomic_t marker; /* 0xbeefcafe */
|
|
|
|
|
pa_atomic_t pid;
|
2008-11-01 21:41:07 +01:00
|
|
|
uint64_t _reserved1;
|
|
|
|
|
uint64_t _reserved2;
|
|
|
|
|
uint64_t _reserved3;
|
|
|
|
|
uint64_t _reserved4;
|
2009-02-13 18:02:47 +01:00
|
|
|
} PA_GCC_PACKED;
|
2006-08-18 19:46:20 +00:00
|
|
|
|
2016-06-17 21:54:54 +02:00
|
|
|
static inline size_t shm_marker_size(pa_mem_type_t type) {
|
|
|
|
|
if (type == PA_MEM_TYPE_SHARED_POSIX)
|
pulsecore: Introduce memfd support
Memfd is a simple memory sharing mechanism, added by the systemd/kdbus
developers, to share pages between processes in an anonymous, no global
registry needed, no mount-point required, relatively secure, manner.
This patch introduces the necessary building blocks for using memfd
shared memory transfers in PulseAudio.
Memfd support shall also help us in laying out the necessary (but not
yet sufficient) groundwork for application sandboxing, protecting PA
from its clients, and protecting clients data from each other.
We plan to exclusively use memfds, instead of POSIX SHM, on the way
forward.
Signed-off-by: Ahmed S. Darwish <darwish.07@gmail.com>
2016-03-13 01:04:18 +02:00
|
|
|
return PA_ALIGN(sizeof(struct shm_marker));
|
|
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
2009-05-14 19:51:05 +02:00
|
|
|
|
2011-03-02 12:41:23 +01:00
|
|
|
#ifdef HAVE_SHM_OPEN
|
2006-08-18 19:46:20 +00:00
|
|
|
static char *segment_name(char *fn, size_t l, unsigned id) {
|
2007-10-28 19:13:50 +00:00
|
|
|
pa_snprintf(fn, l, "/pulse-shm-%u", id);
|
2006-08-18 19:46:20 +00:00
|
|
|
return fn;
|
|
|
|
|
}
|
2011-03-02 12:41:23 +01:00
|
|
|
#endif
|
2006-08-18 19:46:20 +00:00
|
|
|
|
2016-03-13 01:01:38 +02:00
|
|
|
static int privatemem_create(pa_shm *m, size_t size) {
|
|
|
|
|
pa_assert(m);
|
|
|
|
|
pa_assert(size > 0);
|
|
|
|
|
|
pulsecore: Introduce memfd support
Memfd is a simple memory sharing mechanism, added by the systemd/kdbus
developers, to share pages between processes in an anonymous, no global
registry needed, no mount-point required, relatively secure, manner.
This patch introduces the necessary building blocks for using memfd
shared memory transfers in PulseAudio.
Memfd support shall also help us in laying out the necessary (but not
yet sufficient) groundwork for application sandboxing, protecting PA
from its clients, and protecting clients data from each other.
We plan to exclusively use memfds, instead of POSIX SHM, on the way
forward.
Signed-off-by: Ahmed S. Darwish <darwish.07@gmail.com>
2016-03-13 01:04:18 +02:00
|
|
|
m->type = PA_MEM_TYPE_PRIVATE;
|
2016-03-13 01:01:38 +02:00
|
|
|
m->id = 0;
|
|
|
|
|
m->size = size;
|
|
|
|
|
m->do_unlink = false;
|
pulsecore: Introduce memfd support
Memfd is a simple memory sharing mechanism, added by the systemd/kdbus
developers, to share pages between processes in an anonymous, no global
registry needed, no mount-point required, relatively secure, manner.
This patch introduces the necessary building blocks for using memfd
shared memory transfers in PulseAudio.
Memfd support shall also help us in laying out the necessary (but not
yet sufficient) groundwork for application sandboxing, protecting PA
from its clients, and protecting clients data from each other.
We plan to exclusively use memfds, instead of POSIX SHM, on the way
forward.
Signed-off-by: Ahmed S. Darwish <darwish.07@gmail.com>
2016-03-13 01:04:18 +02:00
|
|
|
m->fd = -1;
|
2016-03-13 01:01:38 +02:00
|
|
|
|
|
|
|
|
#ifdef MAP_ANONYMOUS
|
|
|
|
|
if ((m->ptr = mmap(NULL, m->size, PROT_READ|PROT_WRITE, MAP_ANONYMOUS|MAP_PRIVATE, -1, (off_t) 0)) == MAP_FAILED) {
|
|
|
|
|
pa_log("mmap() failed: %s", pa_cstrerror(errno));
|
|
|
|
|
return -1;
|
|
|
|
|
}
|
|
|
|
|
#elif defined(HAVE_POSIX_MEMALIGN)
|
|
|
|
|
{
|
|
|
|
|
int r;
|
|
|
|
|
|
2016-08-18 01:06:47 +02:00
|
|
|
if ((r = posix_memalign(&m->ptr, pa_page_size(), size)) < 0) {
|
2016-03-13 01:01:38 +02:00
|
|
|
pa_log("posix_memalign() failed: %s", pa_cstrerror(r));
|
|
|
|
|
return r;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
#else
|
|
|
|
|
m->ptr = pa_xmalloc(m->size);
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
pulsecore: Introduce memfd support
Memfd is a simple memory sharing mechanism, added by the systemd/kdbus
developers, to share pages between processes in an anonymous, no global
registry needed, no mount-point required, relatively secure, manner.
This patch introduces the necessary building blocks for using memfd
shared memory transfers in PulseAudio.
Memfd support shall also help us in laying out the necessary (but not
yet sufficient) groundwork for application sandboxing, protecting PA
from its clients, and protecting clients data from each other.
We plan to exclusively use memfds, instead of POSIX SHM, on the way
forward.
Signed-off-by: Ahmed S. Darwish <darwish.07@gmail.com>
2016-03-13 01:04:18 +02:00
|
|
|
static int sharedmem_create(pa_shm *m, pa_mem_type_t type, size_t size, mode_t mode) {
|
|
|
|
|
#if defined(HAVE_SHM_OPEN) || defined(HAVE_MEMFD)
|
2006-08-18 19:46:20 +00:00
|
|
|
char fn[32];
|
|
|
|
|
int fd = -1;
|
2016-03-13 01:01:38 +02:00
|
|
|
struct shm_marker *marker;
|
pulsecore: Introduce memfd support
Memfd is a simple memory sharing mechanism, added by the systemd/kdbus
developers, to share pages between processes in an anonymous, no global
registry needed, no mount-point required, relatively secure, manner.
This patch introduces the necessary building blocks for using memfd
shared memory transfers in PulseAudio.
Memfd support shall also help us in laying out the necessary (but not
yet sufficient) groundwork for application sandboxing, protecting PA
from its clients, and protecting clients data from each other.
We plan to exclusively use memfds, instead of POSIX SHM, on the way
forward.
Signed-off-by: Ahmed S. Darwish <darwish.07@gmail.com>
2016-03-13 01:04:18 +02:00
|
|
|
bool do_unlink = false;
|
2007-10-28 19:13:50 +00:00
|
|
|
|
|
|
|
|
/* Each time we create a new SHM area, let's first drop all stale
|
|
|
|
|
* ones */
|
|
|
|
|
pa_shm_cleanup();
|
|
|
|
|
|
pulsecore: Introduce memfd support
Memfd is a simple memory sharing mechanism, added by the systemd/kdbus
developers, to share pages between processes in an anonymous, no global
registry needed, no mount-point required, relatively secure, manner.
This patch introduces the necessary building blocks for using memfd
shared memory transfers in PulseAudio.
Memfd support shall also help us in laying out the necessary (but not
yet sufficient) groundwork for application sandboxing, protecting PA
from its clients, and protecting clients data from each other.
We plan to exclusively use memfds, instead of POSIX SHM, on the way
forward.
Signed-off-by: Ahmed S. Darwish <darwish.07@gmail.com>
2016-03-13 01:04:18 +02:00
|
|
|
pa_random(&m->id, sizeof(m->id));
|
2007-01-04 13:43:45 +00:00
|
|
|
|
pulsecore: Introduce memfd support
Memfd is a simple memory sharing mechanism, added by the systemd/kdbus
developers, to share pages between processes in an anonymous, no global
registry needed, no mount-point required, relatively secure, manner.
This patch introduces the necessary building blocks for using memfd
shared memory transfers in PulseAudio.
Memfd support shall also help us in laying out the necessary (but not
yet sufficient) groundwork for application sandboxing, protecting PA
from its clients, and protecting clients data from each other.
We plan to exclusively use memfds, instead of POSIX SHM, on the way
forward.
Signed-off-by: Ahmed S. Darwish <darwish.07@gmail.com>
2016-03-13 01:04:18 +02:00
|
|
|
switch (type) {
|
2006-08-22 12:45:43 +00:00
|
|
|
#ifdef HAVE_SHM_OPEN
|
pulsecore: Introduce memfd support
Memfd is a simple memory sharing mechanism, added by the systemd/kdbus
developers, to share pages between processes in an anonymous, no global
registry needed, no mount-point required, relatively secure, manner.
This patch introduces the necessary building blocks for using memfd
shared memory transfers in PulseAudio.
Memfd support shall also help us in laying out the necessary (but not
yet sufficient) groundwork for application sandboxing, protecting PA
from its clients, and protecting clients data from each other.
We plan to exclusively use memfds, instead of POSIX SHM, on the way
forward.
Signed-off-by: Ahmed S. Darwish <darwish.07@gmail.com>
2016-03-13 01:04:18 +02:00
|
|
|
case PA_MEM_TYPE_SHARED_POSIX:
|
|
|
|
|
segment_name(fn, sizeof(fn), m->id);
|
|
|
|
|
fd = shm_open(fn, O_RDWR|O_CREAT|O_EXCL, mode);
|
|
|
|
|
do_unlink = true;
|
|
|
|
|
break;
|
|
|
|
|
#endif
|
|
|
|
|
#ifdef HAVE_MEMFD
|
|
|
|
|
case PA_MEM_TYPE_SHARED_MEMFD:
|
|
|
|
|
fd = memfd_create("pulseaudio", MFD_ALLOW_SEALING);
|
|
|
|
|
break;
|
|
|
|
|
#endif
|
|
|
|
|
default:
|
|
|
|
|
goto fail;
|
|
|
|
|
}
|
2006-08-22 12:45:43 +00:00
|
|
|
|
pulsecore: Introduce memfd support
Memfd is a simple memory sharing mechanism, added by the systemd/kdbus
developers, to share pages between processes in an anonymous, no global
registry needed, no mount-point required, relatively secure, manner.
This patch introduces the necessary building blocks for using memfd
shared memory transfers in PulseAudio.
Memfd support shall also help us in laying out the necessary (but not
yet sufficient) groundwork for application sandboxing, protecting PA
from its clients, and protecting clients data from each other.
We plan to exclusively use memfds, instead of POSIX SHM, on the way
forward.
Signed-off-by: Ahmed S. Darwish <darwish.07@gmail.com>
2016-03-13 01:04:18 +02:00
|
|
|
if (fd < 0) {
|
|
|
|
|
pa_log("%s open() failed: %s", pa_mem_type_to_string(type), pa_cstrerror(errno));
|
2016-03-13 01:01:38 +02:00
|
|
|
goto fail;
|
|
|
|
|
}
|
2007-01-04 13:43:45 +00:00
|
|
|
|
pulsecore: Introduce memfd support
Memfd is a simple memory sharing mechanism, added by the systemd/kdbus
developers, to share pages between processes in an anonymous, no global
registry needed, no mount-point required, relatively secure, manner.
This patch introduces the necessary building blocks for using memfd
shared memory transfers in PulseAudio.
Memfd support shall also help us in laying out the necessary (but not
yet sufficient) groundwork for application sandboxing, protecting PA
from its clients, and protecting clients data from each other.
We plan to exclusively use memfds, instead of POSIX SHM, on the way
forward.
Signed-off-by: Ahmed S. Darwish <darwish.07@gmail.com>
2016-03-13 01:04:18 +02:00
|
|
|
m->type = type;
|
2016-06-17 21:54:54 +02:00
|
|
|
m->size = size + shm_marker_size(type);
|
pulsecore: Introduce memfd support
Memfd is a simple memory sharing mechanism, added by the systemd/kdbus
developers, to share pages between processes in an anonymous, no global
registry needed, no mount-point required, relatively secure, manner.
This patch introduces the necessary building blocks for using memfd
shared memory transfers in PulseAudio.
Memfd support shall also help us in laying out the necessary (but not
yet sufficient) groundwork for application sandboxing, protecting PA
from its clients, and protecting clients data from each other.
We plan to exclusively use memfds, instead of POSIX SHM, on the way
forward.
Signed-off-by: Ahmed S. Darwish <darwish.07@gmail.com>
2016-03-13 01:04:18 +02:00
|
|
|
m->do_unlink = do_unlink;
|
2007-10-28 19:13:50 +00:00
|
|
|
|
2016-03-13 01:01:38 +02:00
|
|
|
if (ftruncate(fd, (off_t) m->size) < 0) {
|
|
|
|
|
pa_log("ftruncate() failed: %s", pa_cstrerror(errno));
|
|
|
|
|
goto fail;
|
|
|
|
|
}
|
2007-01-04 13:43:45 +00:00
|
|
|
|
2010-02-02 08:51:44 +01:00
|
|
|
#ifndef MAP_NORESERVE
|
|
|
|
|
#define MAP_NORESERVE 0
|
|
|
|
|
#endif
|
|
|
|
|
|
2016-03-13 01:01:38 +02:00
|
|
|
if ((m->ptr = mmap(NULL, PA_PAGE_ALIGN(m->size), PROT_READ|PROT_WRITE, MAP_SHARED|MAP_NORESERVE, fd, (off_t) 0)) == MAP_FAILED) {
|
|
|
|
|
pa_log("mmap() failed: %s", pa_cstrerror(errno));
|
|
|
|
|
goto fail;
|
|
|
|
|
}
|
2006-08-18 19:46:20 +00:00
|
|
|
|
pulsecore: Introduce memfd support
Memfd is a simple memory sharing mechanism, added by the systemd/kdbus
developers, to share pages between processes in an anonymous, no global
registry needed, no mount-point required, relatively secure, manner.
This patch introduces the necessary building blocks for using memfd
shared memory transfers in PulseAudio.
Memfd support shall also help us in laying out the necessary (but not
yet sufficient) groundwork for application sandboxing, protecting PA
from its clients, and protecting clients data from each other.
We plan to exclusively use memfds, instead of POSIX SHM, on the way
forward.
Signed-off-by: Ahmed S. Darwish <darwish.07@gmail.com>
2016-03-13 01:04:18 +02:00
|
|
|
if (type == PA_MEM_TYPE_SHARED_POSIX) {
|
|
|
|
|
/* We store our PID at the end of the shm block, so that we
|
|
|
|
|
* can check for dead shm segments later */
|
2016-06-17 21:54:54 +02:00
|
|
|
marker = (struct shm_marker*) ((uint8_t*) m->ptr + m->size - shm_marker_size(type));
|
pulsecore: Introduce memfd support
Memfd is a simple memory sharing mechanism, added by the systemd/kdbus
developers, to share pages between processes in an anonymous, no global
registry needed, no mount-point required, relatively secure, manner.
This patch introduces the necessary building blocks for using memfd
shared memory transfers in PulseAudio.
Memfd support shall also help us in laying out the necessary (but not
yet sufficient) groundwork for application sandboxing, protecting PA
from its clients, and protecting clients data from each other.
We plan to exclusively use memfds, instead of POSIX SHM, on the way
forward.
Signed-off-by: Ahmed S. Darwish <darwish.07@gmail.com>
2016-03-13 01:04:18 +02:00
|
|
|
pa_atomic_store(&marker->pid, (int) getpid());
|
|
|
|
|
pa_atomic_store(&marker->marker, SHM_MARKER);
|
|
|
|
|
}
|
2007-10-28 19:13:50 +00:00
|
|
|
|
pulsecore: Introduce memfd support
Memfd is a simple memory sharing mechanism, added by the systemd/kdbus
developers, to share pages between processes in an anonymous, no global
registry needed, no mount-point required, relatively secure, manner.
This patch introduces the necessary building blocks for using memfd
shared memory transfers in PulseAudio.
Memfd support shall also help us in laying out the necessary (but not
yet sufficient) groundwork for application sandboxing, protecting PA
from its clients, and protecting clients data from each other.
We plan to exclusively use memfds, instead of POSIX SHM, on the way
forward.
Signed-off-by: Ahmed S. Darwish <darwish.07@gmail.com>
2016-03-13 01:04:18 +02:00
|
|
|
/* For memfds, we keep the fd open until we pass it
|
|
|
|
|
* to the other PA endpoint over unix domain socket. */
|
2016-08-10 21:43:32 +05:30
|
|
|
if (type != PA_MEM_TYPE_SHARED_MEMFD) {
|
pulsecore: Introduce memfd support
Memfd is a simple memory sharing mechanism, added by the systemd/kdbus
developers, to share pages between processes in an anonymous, no global
registry needed, no mount-point required, relatively secure, manner.
This patch introduces the necessary building blocks for using memfd
shared memory transfers in PulseAudio.
Memfd support shall also help us in laying out the necessary (but not
yet sufficient) groundwork for application sandboxing, protecting PA
from its clients, and protecting clients data from each other.
We plan to exclusively use memfds, instead of POSIX SHM, on the way
forward.
Signed-off-by: Ahmed S. Darwish <darwish.07@gmail.com>
2016-03-13 01:04:18 +02:00
|
|
|
pa_assert_se(pa_close(fd) == 0);
|
|
|
|
|
m->fd = -1;
|
|
|
|
|
}
|
2017-03-07 16:29:30 +01:00
|
|
|
#ifdef HAVE_MEMFD
|
2016-08-10 21:43:32 +05:30
|
|
|
else
|
|
|
|
|
m->fd = fd;
|
|
|
|
|
#endif
|
2007-01-04 13:43:45 +00:00
|
|
|
|
2006-08-18 19:46:20 +00:00
|
|
|
return 0;
|
2007-01-04 13:43:45 +00:00
|
|
|
|
2006-08-18 19:46:20 +00:00
|
|
|
fail:
|
|
|
|
|
if (fd >= 0) {
|
pulsecore: Introduce memfd support
Memfd is a simple memory sharing mechanism, added by the systemd/kdbus
developers, to share pages between processes in an anonymous, no global
registry needed, no mount-point required, relatively secure, manner.
This patch introduces the necessary building blocks for using memfd
shared memory transfers in PulseAudio.
Memfd support shall also help us in laying out the necessary (but not
yet sufficient) groundwork for application sandboxing, protecting PA
from its clients, and protecting clients data from each other.
We plan to exclusively use memfds, instead of POSIX SHM, on the way
forward.
Signed-off-by: Ahmed S. Darwish <darwish.07@gmail.com>
2016-03-13 01:04:18 +02:00
|
|
|
#ifdef HAVE_SHM_OPEN
|
|
|
|
|
if (type == PA_MEM_TYPE_SHARED_POSIX)
|
|
|
|
|
shm_unlink(fn);
|
|
|
|
|
#endif
|
2007-10-28 19:13:50 +00:00
|
|
|
pa_close(fd);
|
2006-08-18 19:46:20 +00:00
|
|
|
}
|
pulsecore: Introduce memfd support
Memfd is a simple memory sharing mechanism, added by the systemd/kdbus
developers, to share pages between processes in an anonymous, no global
registry needed, no mount-point required, relatively secure, manner.
This patch introduces the necessary building blocks for using memfd
shared memory transfers in PulseAudio.
Memfd support shall also help us in laying out the necessary (but not
yet sufficient) groundwork for application sandboxing, protecting PA
from its clients, and protecting clients data from each other.
We plan to exclusively use memfds, instead of POSIX SHM, on the way
forward.
Signed-off-by: Ahmed S. Darwish <darwish.07@gmail.com>
2016-03-13 01:04:18 +02:00
|
|
|
#endif /* defined(HAVE_SHM_OPEN) || defined(HAVE_MEMFD) */
|
2006-08-18 19:46:20 +00:00
|
|
|
|
|
|
|
|
return -1;
|
|
|
|
|
}
|
|
|
|
|
|
pulsecore: Introduce memfd support
Memfd is a simple memory sharing mechanism, added by the systemd/kdbus
developers, to share pages between processes in an anonymous, no global
registry needed, no mount-point required, relatively secure, manner.
This patch introduces the necessary building blocks for using memfd
shared memory transfers in PulseAudio.
Memfd support shall also help us in laying out the necessary (but not
yet sufficient) groundwork for application sandboxing, protecting PA
from its clients, and protecting clients data from each other.
We plan to exclusively use memfds, instead of POSIX SHM, on the way
forward.
Signed-off-by: Ahmed S. Darwish <darwish.07@gmail.com>
2016-03-13 01:04:18 +02:00
|
|
|
int pa_shm_create_rw(pa_shm *m, pa_mem_type_t type, size_t size, mode_t mode) {
|
|
|
|
|
pa_assert(m);
|
|
|
|
|
pa_assert(size > 0);
|
|
|
|
|
pa_assert(size <= MAX_SHM_SIZE);
|
|
|
|
|
pa_assert(!(mode & ~0777));
|
|
|
|
|
pa_assert(mode >= 0600);
|
|
|
|
|
|
|
|
|
|
/* Round up to make it page aligned */
|
|
|
|
|
size = PA_PAGE_ALIGN(size);
|
|
|
|
|
|
|
|
|
|
if (type == PA_MEM_TYPE_PRIVATE)
|
|
|
|
|
return privatemem_create(m, size);
|
|
|
|
|
|
|
|
|
|
return sharedmem_create(m, type, size, mode);
|
|
|
|
|
}
|
|
|
|
|
|
2016-03-13 01:01:38 +02:00
|
|
|
static void privatemem_free(pa_shm *m) {
|
|
|
|
|
pa_assert(m);
|
|
|
|
|
pa_assert(m->ptr);
|
|
|
|
|
pa_assert(m->size > 0);
|
|
|
|
|
|
|
|
|
|
#ifdef MAP_ANONYMOUS
|
|
|
|
|
if (munmap(m->ptr, m->size) < 0)
|
|
|
|
|
pa_log("munmap() failed: %s", pa_cstrerror(errno));
|
|
|
|
|
#elif defined(HAVE_POSIX_MEMALIGN)
|
|
|
|
|
free(m->ptr);
|
|
|
|
|
#else
|
|
|
|
|
pa_xfree(m->ptr);
|
|
|
|
|
#endif
|
|
|
|
|
}
|
|
|
|
|
|
2006-08-18 19:46:20 +00:00
|
|
|
void pa_shm_free(pa_shm *m) {
|
2007-10-28 19:13:50 +00:00
|
|
|
pa_assert(m);
|
|
|
|
|
pa_assert(m->ptr);
|
|
|
|
|
pa_assert(m->size > 0);
|
2006-08-18 19:46:20 +00:00
|
|
|
|
2006-08-22 12:45:43 +00:00
|
|
|
#ifdef MAP_FAILED
|
2007-10-28 19:13:50 +00:00
|
|
|
pa_assert(m->ptr != MAP_FAILED);
|
2006-08-22 12:45:43 +00:00
|
|
|
#endif
|
|
|
|
|
|
2016-03-13 01:01:38 +02:00
|
|
|
if (m->type == PA_MEM_TYPE_PRIVATE) {
|
|
|
|
|
privatemem_free(m);
|
|
|
|
|
goto finish;
|
|
|
|
|
}
|
2006-08-18 19:46:20 +00:00
|
|
|
|
pulsecore: Introduce memfd support
Memfd is a simple memory sharing mechanism, added by the systemd/kdbus
developers, to share pages between processes in an anonymous, no global
registry needed, no mount-point required, relatively secure, manner.
This patch introduces the necessary building blocks for using memfd
shared memory transfers in PulseAudio.
Memfd support shall also help us in laying out the necessary (but not
yet sufficient) groundwork for application sandboxing, protecting PA
from its clients, and protecting clients data from each other.
We plan to exclusively use memfds, instead of POSIX SHM, on the way
forward.
Signed-off-by: Ahmed S. Darwish <darwish.07@gmail.com>
2016-03-13 01:04:18 +02:00
|
|
|
#if defined(HAVE_SHM_OPEN) || defined(HAVE_MEMFD)
|
2016-03-13 01:01:38 +02:00
|
|
|
if (munmap(m->ptr, PA_PAGE_ALIGN(m->size)) < 0)
|
|
|
|
|
pa_log("munmap() failed: %s", pa_cstrerror(errno));
|
2006-08-22 12:45:43 +00:00
|
|
|
|
pulsecore: Introduce memfd support
Memfd is a simple memory sharing mechanism, added by the systemd/kdbus
developers, to share pages between processes in an anonymous, no global
registry needed, no mount-point required, relatively secure, manner.
This patch introduces the necessary building blocks for using memfd
shared memory transfers in PulseAudio.
Memfd support shall also help us in laying out the necessary (but not
yet sufficient) groundwork for application sandboxing, protecting PA
from its clients, and protecting clients data from each other.
We plan to exclusively use memfds, instead of POSIX SHM, on the way
forward.
Signed-off-by: Ahmed S. Darwish <darwish.07@gmail.com>
2016-03-13 01:04:18 +02:00
|
|
|
#ifdef HAVE_SHM_OPEN
|
|
|
|
|
if (m->type == PA_MEM_TYPE_SHARED_POSIX && m->do_unlink) {
|
2016-03-13 01:01:38 +02:00
|
|
|
char fn[32];
|
2007-01-04 13:43:45 +00:00
|
|
|
|
2016-03-13 01:01:38 +02:00
|
|
|
segment_name(fn, sizeof(fn), m->id);
|
|
|
|
|
if (shm_unlink(fn) < 0)
|
|
|
|
|
pa_log(" shm_unlink(%s) failed: %s", fn, pa_cstrerror(errno));
|
|
|
|
|
}
|
pulsecore: Introduce memfd support
Memfd is a simple memory sharing mechanism, added by the systemd/kdbus
developers, to share pages between processes in an anonymous, no global
registry needed, no mount-point required, relatively secure, manner.
This patch introduces the necessary building blocks for using memfd
shared memory transfers in PulseAudio.
Memfd support shall also help us in laying out the necessary (but not
yet sufficient) groundwork for application sandboxing, protecting PA
from its clients, and protecting clients data from each other.
We plan to exclusively use memfds, instead of POSIX SHM, on the way
forward.
Signed-off-by: Ahmed S. Darwish <darwish.07@gmail.com>
2016-03-13 01:04:18 +02:00
|
|
|
#endif
|
|
|
|
|
#ifdef HAVE_MEMFD
|
|
|
|
|
if (m->type == PA_MEM_TYPE_SHARED_MEMFD && m->fd != -1)
|
|
|
|
|
pa_assert_se(pa_close(m->fd) == 0);
|
|
|
|
|
#endif
|
|
|
|
|
|
2006-08-22 12:45:43 +00:00
|
|
|
#else
|
pulsecore: Introduce memfd support
Memfd is a simple memory sharing mechanism, added by the systemd/kdbus
developers, to share pages between processes in an anonymous, no global
registry needed, no mount-point required, relatively secure, manner.
This patch introduces the necessary building blocks for using memfd
shared memory transfers in PulseAudio.
Memfd support shall also help us in laying out the necessary (but not
yet sufficient) groundwork for application sandboxing, protecting PA
from its clients, and protecting clients data from each other.
We plan to exclusively use memfds, instead of POSIX SHM, on the way
forward.
Signed-off-by: Ahmed S. Darwish <darwish.07@gmail.com>
2016-03-13 01:04:18 +02:00
|
|
|
/* We shouldn't be here without shm or memfd support */
|
2016-03-13 01:01:38 +02:00
|
|
|
pa_assert_not_reached();
|
2006-08-22 12:45:43 +00:00
|
|
|
#endif
|
2006-08-18 19:46:20 +00:00
|
|
|
|
2016-03-13 01:01:38 +02:00
|
|
|
finish:
|
2009-05-14 19:51:05 +02:00
|
|
|
pa_zero(*m);
|
2006-08-18 19:46:20 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void pa_shm_punch(pa_shm *m, size_t offset, size_t size) {
|
|
|
|
|
void *ptr;
|
2009-05-14 19:51:05 +02:00
|
|
|
size_t o;
|
2016-08-18 01:06:47 +02:00
|
|
|
const size_t page_size = pa_page_size();
|
2007-01-04 13:43:45 +00:00
|
|
|
|
2007-10-28 19:13:50 +00:00
|
|
|
pa_assert(m);
|
|
|
|
|
pa_assert(m->ptr);
|
|
|
|
|
pa_assert(m->size > 0);
|
|
|
|
|
pa_assert(offset+size <= m->size);
|
2006-08-18 19:46:20 +00:00
|
|
|
|
2006-08-22 12:45:43 +00:00
|
|
|
#ifdef MAP_FAILED
|
2007-10-28 19:13:50 +00:00
|
|
|
pa_assert(m->ptr != MAP_FAILED);
|
2006-08-22 12:45:43 +00:00
|
|
|
#endif
|
|
|
|
|
|
2006-08-18 19:46:20 +00:00
|
|
|
/* You're welcome to implement this as NOOP on systems that don't
|
|
|
|
|
* support it */
|
|
|
|
|
|
2009-05-14 19:51:05 +02:00
|
|
|
/* Align the pointer up to multiples of the page size */
|
2006-08-18 19:46:20 +00:00
|
|
|
ptr = (uint8_t*) m->ptr + offset;
|
2008-08-19 22:39:54 +02:00
|
|
|
o = (size_t) ((uint8_t*) ptr - (uint8_t*) PA_PAGE_ALIGN_PTR(ptr));
|
2007-01-04 13:43:45 +00:00
|
|
|
|
2006-08-18 19:46:20 +00:00
|
|
|
if (o > 0) {
|
2016-08-18 01:06:47 +02:00
|
|
|
size_t delta = page_size - o;
|
2009-05-14 19:51:05 +02:00
|
|
|
ptr = (uint8_t*) ptr + delta;
|
|
|
|
|
size -= delta;
|
2006-08-18 19:46:20 +00:00
|
|
|
}
|
2007-01-04 13:43:45 +00:00
|
|
|
|
2009-05-14 19:51:05 +02:00
|
|
|
/* Align the size down to multiples of page size */
|
2016-08-18 01:06:47 +02:00
|
|
|
size = (size / page_size) * page_size;
|
2009-05-14 19:51:05 +02:00
|
|
|
|
2006-08-18 19:46:20 +00:00
|
|
|
#ifdef MADV_REMOVE
|
|
|
|
|
if (madvise(ptr, size, MADV_REMOVE) >= 0)
|
|
|
|
|
return;
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
#ifdef MADV_FREE
|
|
|
|
|
if (madvise(ptr, size, MADV_FREE) >= 0)
|
|
|
|
|
return;
|
2007-01-04 13:43:45 +00:00
|
|
|
#endif
|
|
|
|
|
|
2006-08-18 19:46:20 +00:00
|
|
|
#ifdef MADV_DONTNEED
|
2009-05-14 19:51:05 +02:00
|
|
|
madvise(ptr, size, MADV_DONTNEED);
|
2007-10-28 19:13:50 +00:00
|
|
|
#elif defined(POSIX_MADV_DONTNEED)
|
2009-05-14 19:51:05 +02:00
|
|
|
posix_madvise(ptr, size, POSIX_MADV_DONTNEED);
|
2006-08-18 19:46:20 +00:00
|
|
|
#endif
|
|
|
|
|
}
|
|
|
|
|
|
pulsecore: Introduce memfd support
Memfd is a simple memory sharing mechanism, added by the systemd/kdbus
developers, to share pages between processes in an anonymous, no global
registry needed, no mount-point required, relatively secure, manner.
This patch introduces the necessary building blocks for using memfd
shared memory transfers in PulseAudio.
Memfd support shall also help us in laying out the necessary (but not
yet sufficient) groundwork for application sandboxing, protecting PA
from its clients, and protecting clients data from each other.
We plan to exclusively use memfds, instead of POSIX SHM, on the way
forward.
Signed-off-by: Ahmed S. Darwish <darwish.07@gmail.com>
2016-03-13 01:04:18 +02:00
|
|
|
static int shm_attach(pa_shm *m, pa_mem_type_t type, unsigned id, int memfd_fd, bool writable, bool for_cleanup) {
|
|
|
|
|
#if defined(HAVE_SHM_OPEN) || defined(HAVE_MEMFD)
|
2006-08-18 19:46:20 +00:00
|
|
|
char fn[32];
|
|
|
|
|
int fd = -1;
|
2014-04-25 13:58:26 +02:00
|
|
|
int prot;
|
2006-08-18 19:46:20 +00:00
|
|
|
struct stat st;
|
|
|
|
|
|
2007-10-28 19:13:50 +00:00
|
|
|
pa_assert(m);
|
2006-08-18 19:46:20 +00:00
|
|
|
|
pulsecore: Introduce memfd support
Memfd is a simple memory sharing mechanism, added by the systemd/kdbus
developers, to share pages between processes in an anonymous, no global
registry needed, no mount-point required, relatively secure, manner.
This patch introduces the necessary building blocks for using memfd
shared memory transfers in PulseAudio.
Memfd support shall also help us in laying out the necessary (but not
yet sufficient) groundwork for application sandboxing, protecting PA
from its clients, and protecting clients data from each other.
We plan to exclusively use memfds, instead of POSIX SHM, on the way
forward.
Signed-off-by: Ahmed S. Darwish <darwish.07@gmail.com>
2016-03-13 01:04:18 +02:00
|
|
|
switch (type) {
|
|
|
|
|
#ifdef HAVE_SHM_OPEN
|
|
|
|
|
case PA_MEM_TYPE_SHARED_POSIX:
|
|
|
|
|
pa_assert(memfd_fd == -1);
|
|
|
|
|
segment_name(fn, sizeof(fn), id);
|
|
|
|
|
if ((fd = shm_open(fn, writable ? O_RDWR : O_RDONLY, 0)) < 0) {
|
|
|
|
|
if ((errno != EACCES && errno != ENOENT) || !for_cleanup)
|
|
|
|
|
pa_log("shm_open() failed: %s", pa_cstrerror(errno));
|
|
|
|
|
goto fail;
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
#endif
|
|
|
|
|
#ifdef HAVE_MEMFD
|
|
|
|
|
case PA_MEM_TYPE_SHARED_MEMFD:
|
|
|
|
|
pa_assert(memfd_fd != -1);
|
|
|
|
|
fd = memfd_fd;
|
|
|
|
|
break;
|
|
|
|
|
#endif
|
|
|
|
|
default:
|
2006-08-18 19:46:20 +00:00
|
|
|
goto fail;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (fstat(fd, &st) < 0) {
|
2006-08-18 21:38:40 +00:00
|
|
|
pa_log("fstat() failed: %s", pa_cstrerror(errno));
|
2006-08-18 19:46:20 +00:00
|
|
|
goto fail;
|
|
|
|
|
}
|
|
|
|
|
|
2008-05-15 23:34:41 +00:00
|
|
|
if (st.st_size <= 0 ||
|
2016-06-17 21:54:54 +02:00
|
|
|
st.st_size > (off_t) MAX_SHM_SIZE + (off_t) shm_marker_size(type) ||
|
2008-05-15 23:34:41 +00:00
|
|
|
PA_ALIGN((size_t) st.st_size) != (size_t) st.st_size) {
|
2006-08-18 21:38:40 +00:00
|
|
|
pa_log("Invalid shared memory segment size");
|
2006-08-18 19:46:20 +00:00
|
|
|
goto fail;
|
|
|
|
|
}
|
|
|
|
|
|
2014-04-25 13:58:26 +02:00
|
|
|
prot = writable ? PROT_READ | PROT_WRITE : PROT_READ;
|
pulsecore: Introduce memfd support
Memfd is a simple memory sharing mechanism, added by the systemd/kdbus
developers, to share pages between processes in an anonymous, no global
registry needed, no mount-point required, relatively secure, manner.
This patch introduces the necessary building blocks for using memfd
shared memory transfers in PulseAudio.
Memfd support shall also help us in laying out the necessary (but not
yet sufficient) groundwork for application sandboxing, protecting PA
from its clients, and protecting clients data from each other.
We plan to exclusively use memfds, instead of POSIX SHM, on the way
forward.
Signed-off-by: Ahmed S. Darwish <darwish.07@gmail.com>
2016-03-13 01:04:18 +02:00
|
|
|
if ((m->ptr = mmap(NULL, PA_PAGE_ALIGN(st.st_size), prot, MAP_SHARED, fd, (off_t) 0)) == MAP_FAILED) {
|
2006-08-18 21:38:40 +00:00
|
|
|
pa_log("mmap() failed: %s", pa_cstrerror(errno));
|
2006-08-18 19:46:20 +00:00
|
|
|
goto fail;
|
|
|
|
|
}
|
|
|
|
|
|
pulsecore: Introduce memfd support
Memfd is a simple memory sharing mechanism, added by the systemd/kdbus
developers, to share pages between processes in an anonymous, no global
registry needed, no mount-point required, relatively secure, manner.
This patch introduces the necessary building blocks for using memfd
shared memory transfers in PulseAudio.
Memfd support shall also help us in laying out the necessary (but not
yet sufficient) groundwork for application sandboxing, protecting PA
from its clients, and protecting clients data from each other.
We plan to exclusively use memfds, instead of POSIX SHM, on the way
forward.
Signed-off-by: Ahmed S. Darwish <darwish.07@gmail.com>
2016-03-13 01:04:18 +02:00
|
|
|
/* In case of attaching to memfd areas, _the caller_ maintains
|
|
|
|
|
* ownership of the passed fd and has the sole responsibility
|
|
|
|
|
* of closing it down.. For other types, we're the code path
|
|
|
|
|
* which created the fd in the first place and we're thus the
|
|
|
|
|
* ones responsible for closing it down */
|
|
|
|
|
if (type != PA_MEM_TYPE_SHARED_MEMFD)
|
|
|
|
|
pa_assert_se(pa_close(fd) == 0);
|
2007-01-04 13:43:45 +00:00
|
|
|
|
pulsecore: Introduce memfd support
Memfd is a simple memory sharing mechanism, added by the systemd/kdbus
developers, to share pages between processes in an anonymous, no global
registry needed, no mount-point required, relatively secure, manner.
This patch introduces the necessary building blocks for using memfd
shared memory transfers in PulseAudio.
Memfd support shall also help us in laying out the necessary (but not
yet sufficient) groundwork for application sandboxing, protecting PA
from its clients, and protecting clients data from each other.
We plan to exclusively use memfds, instead of POSIX SHM, on the way
forward.
Signed-off-by: Ahmed S. Darwish <darwish.07@gmail.com>
2016-03-13 01:04:18 +02:00
|
|
|
m->type = type;
|
|
|
|
|
m->id = id;
|
|
|
|
|
m->size = (size_t) st.st_size;
|
|
|
|
|
m->do_unlink = false;
|
|
|
|
|
m->fd = -1;
|
2007-01-04 13:43:45 +00:00
|
|
|
|
2006-08-18 19:46:20 +00:00
|
|
|
return 0;
|
2007-01-04 13:43:45 +00:00
|
|
|
|
2006-08-18 19:46:20 +00:00
|
|
|
fail:
|
pulsecore: Introduce memfd support
Memfd is a simple memory sharing mechanism, added by the systemd/kdbus
developers, to share pages between processes in an anonymous, no global
registry needed, no mount-point required, relatively secure, manner.
This patch introduces the necessary building blocks for using memfd
shared memory transfers in PulseAudio.
Memfd support shall also help us in laying out the necessary (but not
yet sufficient) groundwork for application sandboxing, protecting PA
from its clients, and protecting clients data from each other.
We plan to exclusively use memfds, instead of POSIX SHM, on the way
forward.
Signed-off-by: Ahmed S. Darwish <darwish.07@gmail.com>
2016-03-13 01:04:18 +02:00
|
|
|
/* In case of memfds, caller maintains fd ownership */
|
|
|
|
|
if (fd >= 0 && type != PA_MEM_TYPE_SHARED_MEMFD)
|
2007-10-28 19:13:50 +00:00
|
|
|
pa_close(fd);
|
2006-08-18 19:46:20 +00:00
|
|
|
|
pulsecore: Introduce memfd support
Memfd is a simple memory sharing mechanism, added by the systemd/kdbus
developers, to share pages between processes in an anonymous, no global
registry needed, no mount-point required, relatively secure, manner.
This patch introduces the necessary building blocks for using memfd
shared memory transfers in PulseAudio.
Memfd support shall also help us in laying out the necessary (but not
yet sufficient) groundwork for application sandboxing, protecting PA
from its clients, and protecting clients data from each other.
We plan to exclusively use memfds, instead of POSIX SHM, on the way
forward.
Signed-off-by: Ahmed S. Darwish <darwish.07@gmail.com>
2016-03-13 01:04:18 +02:00
|
|
|
#endif /* defined(HAVE_SHM_OPEN) || defined(HAVE_MEMFD) */
|
|
|
|
|
|
2006-08-18 19:46:20 +00:00
|
|
|
return -1;
|
|
|
|
|
}
|
2006-08-22 11:41:14 +00:00
|
|
|
|
pulsecore: Introduce memfd support
Memfd is a simple memory sharing mechanism, added by the systemd/kdbus
developers, to share pages between processes in an anonymous, no global
registry needed, no mount-point required, relatively secure, manner.
This patch introduces the necessary building blocks for using memfd
shared memory transfers in PulseAudio.
Memfd support shall also help us in laying out the necessary (but not
yet sufficient) groundwork for application sandboxing, protecting PA
from its clients, and protecting clients data from each other.
We plan to exclusively use memfds, instead of POSIX SHM, on the way
forward.
Signed-off-by: Ahmed S. Darwish <darwish.07@gmail.com>
2016-03-13 01:04:18 +02:00
|
|
|
/* Caller owns passed @memfd_fd and must close it down when appropriate. */
|
2016-03-13 01:07:27 +02:00
|
|
|
int pa_shm_attach(pa_shm *m, pa_mem_type_t type, unsigned id, int memfd_fd, bool writable) {
|
pulsecore: Introduce memfd support
Memfd is a simple memory sharing mechanism, added by the systemd/kdbus
developers, to share pages between processes in an anonymous, no global
registry needed, no mount-point required, relatively secure, manner.
This patch introduces the necessary building blocks for using memfd
shared memory transfers in PulseAudio.
Memfd support shall also help us in laying out the necessary (but not
yet sufficient) groundwork for application sandboxing, protecting PA
from its clients, and protecting clients data from each other.
We plan to exclusively use memfds, instead of POSIX SHM, on the way
forward.
Signed-off-by: Ahmed S. Darwish <darwish.07@gmail.com>
2016-03-13 01:04:18 +02:00
|
|
|
return shm_attach(m, type, id, memfd_fd, writable, false);
|
2015-09-28 15:41:15 +02:00
|
|
|
}
|
|
|
|
|
|
2007-10-28 19:13:50 +00:00
|
|
|
int pa_shm_cleanup(void) {
|
|
|
|
|
|
2008-02-15 13:38:12 +00:00
|
|
|
#ifdef HAVE_SHM_OPEN
|
2007-10-28 19:13:50 +00:00
|
|
|
#ifdef SHM_PATH
|
|
|
|
|
DIR *d;
|
|
|
|
|
struct dirent *de;
|
|
|
|
|
|
|
|
|
|
if (!(d = opendir(SHM_PATH))) {
|
|
|
|
|
pa_log_warn("Failed to read "SHM_PATH": %s", pa_cstrerror(errno));
|
|
|
|
|
return -1;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
while ((de = readdir(d))) {
|
|
|
|
|
pa_shm seg;
|
|
|
|
|
unsigned id;
|
|
|
|
|
pid_t pid;
|
|
|
|
|
char fn[128];
|
|
|
|
|
struct shm_marker *m;
|
|
|
|
|
|
2013-01-04 16:31:57 +02:00
|
|
|
#if defined(__sun)
|
|
|
|
|
if (strncmp(de->d_name, ".SHMDpulse-shm-", SHM_ID_LEN))
|
|
|
|
|
#else
|
|
|
|
|
if (strncmp(de->d_name, "pulse-shm-", SHM_ID_LEN))
|
|
|
|
|
#endif
|
2007-10-28 19:13:50 +00:00
|
|
|
continue;
|
|
|
|
|
|
2013-01-04 16:31:57 +02:00
|
|
|
if (pa_atou(de->d_name + SHM_ID_LEN, &id) < 0)
|
2007-10-28 19:13:50 +00:00
|
|
|
continue;
|
|
|
|
|
|
pulsecore: Introduce memfd support
Memfd is a simple memory sharing mechanism, added by the systemd/kdbus
developers, to share pages between processes in an anonymous, no global
registry needed, no mount-point required, relatively secure, manner.
This patch introduces the necessary building blocks for using memfd
shared memory transfers in PulseAudio.
Memfd support shall also help us in laying out the necessary (but not
yet sufficient) groundwork for application sandboxing, protecting PA
from its clients, and protecting clients data from each other.
We plan to exclusively use memfds, instead of POSIX SHM, on the way
forward.
Signed-off-by: Ahmed S. Darwish <darwish.07@gmail.com>
2016-03-13 01:04:18 +02:00
|
|
|
if (shm_attach(&seg, PA_MEM_TYPE_SHARED_POSIX, id, -1, false, true) < 0)
|
2007-10-28 19:13:50 +00:00
|
|
|
continue;
|
|
|
|
|
|
2016-06-17 21:54:54 +02:00
|
|
|
if (seg.size < shm_marker_size(seg.type)) {
|
2007-10-28 19:13:50 +00:00
|
|
|
pa_shm_free(&seg);
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
|
2016-06-17 21:54:54 +02:00
|
|
|
m = (struct shm_marker*) ((uint8_t*) seg.ptr + seg.size - shm_marker_size(seg.type));
|
2007-10-28 19:13:50 +00:00
|
|
|
|
|
|
|
|
if (pa_atomic_load(&m->marker) != SHM_MARKER) {
|
|
|
|
|
pa_shm_free(&seg);
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (!(pid = (pid_t) pa_atomic_load(&m->pid))) {
|
|
|
|
|
pa_shm_free(&seg);
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (kill(pid, 0) == 0 || errno != ESRCH) {
|
|
|
|
|
pa_shm_free(&seg);
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
pa_shm_free(&seg);
|
|
|
|
|
|
|
|
|
|
/* Ok, the owner of this shms segment is dead, so, let's remove the segment */
|
|
|
|
|
segment_name(fn, sizeof(fn), id);
|
|
|
|
|
|
2008-05-15 23:34:41 +00:00
|
|
|
if (shm_unlink(fn) < 0 && errno != EACCES && errno != ENOENT)
|
2016-08-16 07:03:25 +02:00
|
|
|
pa_log_warn("Failed to remove SHM segment %s: %s", fn, pa_cstrerror(errno));
|
2007-10-28 19:13:50 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
closedir(d);
|
2008-02-15 13:38:12 +00:00
|
|
|
#endif /* SHM_PATH */
|
|
|
|
|
#endif /* HAVE_SHM_OPEN */
|
2007-10-28 19:13:50 +00:00
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
|
}
|