Контроль доступа к общей памяти

Я предполагаю, что этот вопрос адресован специалистам по системному программированию Linux / Unix (к сожалению, я еще не из таких;)).

Я создаю систему, которая работает на многоядерной машине Linux / Unix, в которой процессы взаимодействуют друг с другом через разделяемую память (важна скорость - минимальное количество обращений к ядру, насколько это возможно). «Каналы» общей памяти для связи динамически создаются, когда процесс запрашивает связь с другим - у каждого процесса есть поток прослушивания, который принимает и «принимает» эти запросы, а затем создает / инициализирует каналы общей памяти. Для процессов a и b создаются два канала (области общей памяти) - один канал используется как "вывод" из a и "ввод "на b и другое наоборот.

При создании каналов связи обязательно, чтобы процесс a имел доступ R / W к соответствующему «выходному» каналу и только R-доступ к соответствующему «входному» каналу. Другие процессы не должны иметь возможность получить W-доступ к каналам, совместно используемым другими парами процессов (желательно, чтобы у них не было даже R-доступа).

Какое решение вы можете предложить?

Я думал о:

  1. определение моих собственных системных вызовов (на данный момент не желательно)
  2. использование прав доступа к файлам, присущих файловой системе, для наложения этих прав доступа

Для второго решения идея состоит в том, чтобы запускать процессы под разными идентификаторами пользователей и использовать динамическое создание групп для каждой пары процессов и соответственно назначать права доступа к файлам для каждого дескриптора разделяемой памяти (R для группы, R / W для процесса записи, - для отдыхать).

Возможно ли второе решение? Есть ли лучшие решения (например, которые включают некоторые системные вызовы, о которых я не знаю)?

Большое спасибо за ваше время и помощь.


person ivcha    schedule 09.12.2010    source источник
comment
Вы рассматривали mmap-файлы или именованные каналы? Они намного проще, чем SysV ipc.   -  person J-16 SDiZ    schedule 09.12.2010
comment
да, на самом деле используется отображение объекта разделяемой памяти   -  person ivcha    schedule 09.12.2010


Ответы (1)


Вы не можете использовать группы для этого, потому что невозможно добавить дополнительные группы к уже запущенному процессу. Однако механизм, основанный на пользователях, будет работать нормально.

Запускайте каждый процесс под своим uid. Чтобы создать канал совместно используемой памяти, отправляющая сторона создает объект совместно используемой памяти с shm_open(), указывая O_RDWR | O_CREAT | O_EXCL и режим 0600. Таким образом, это единственный процесс, в котором он открыт, и только его uid может открывать его. Затем отправляющая сторона открывает второй файловый дескриптор для того же сегмента разделяемой памяти, на этот раз с использованием O_RDONLY. Он отправляет этот второй файловый дескриптор, доступный только для чтения, принимающему процессу, используя сообщение SCM_RIGHTS через сокет домена unix. Затем он может закрыть дескриптор файла, доступный только для чтения.

Затем процесс отправки и получения mmap() разделяется памятью. Принимающий процесс имеет доступ только для чтения и не имеет прав на его обновление до чтения и записи. Никакие другие процессы не могут его открыть вообще.

person caf    schedule 09.12.2010
comment
это добавляет лишь несколько системных вызовов на инициализацию парного соединения, что отлично. Спасибо за Ваш ответ! - person ivcha; 11.12.2010
comment
@kaptoxic: Действительно, и я бы посоветовал использовать сокеты домена UNIX для запроса канала сообщений, чтобы вы могли отправлять дескрипторы файлов общей памяти поверх этого. - person caf; 12.12.2010