shm_create_handle()
Create a handle so a specific process can access a shared memory object
Synopsis:
#include <fcntl.h>
#include <sys/mman.h>
int shm_create_handle( int fd,
pid_t pid,
int flags,
shm_handle_t* handlep,
unsigned options );
Arguments:
- fd
- The file descriptor for the shared object. This file descriptor can be created first by open(), shm_open(), or shm_open_handle().
- pid
- The ID of the process that you want to access the shared object.
- flags
- You must specify exactly one of the following file access modes (defined in
<fcntl.h>) in the value of
flags:
- O_RDONLY — open for read access only.
- O_RDWR — open for read and write access.
- O_WRONLY — open for write access only.
Note:For the function call to succeed, the flags must specify an access mode that's as privileged as or less privileged than the mode specified when the file descriptor in fd was created; for details, see the shm_open() description.
Setting a more privileged access mode or any flags other than the ones listed above causes the function call to fail.
- handlep
- A pointer to a location for storing the handle to the shared object.
- options
- A bitmask configuring options for the shared object. Currently, the only supported flag is:
- SHM_CREATE_HANDLE_OPT_NOFD — prevent the shared memory object handle from being converted to a file descriptor using shm_open_handle(). This improves security because the creator can share an object with a recipient process in such a way that prevents the recipient from accessing the object after the creator revokes its access to it. This flag is meant to be used after setting the SHMCTL_REVOCABLE flag on the object via shm_ctl(), and before giving the handle to the recipient so it can use the object until the creator calls shm_revoke() to revoke its access.
Library:
libc
Use the -l c option to qcc to link against this library. This library is usually included automatically.
Description:
The shm_create_handle() function takes a file descriptor (fd) for a shared memory object and returns a unique single-use handle for it. The handle can be used only once, and only by the process specified by pid to access the object in a mode that's as privileged as or less privileged than what's indicated in flags. For example, if flags is set to O_RDWR when creating the handle, the recipient process can open the object (using shm_open_handle()) with O_RDWR, O_RDONLY, or O_WRONLY access. But if flags is set to O_RDONLY, the recipient can open the object with O_RDONLY access but not O_RDWR or O_WRONLY access.
The shm_create_handle() function provides a means for one process to provide another with access to a shared memory object without having to share a path. Sharing a path is difficult because of the variable length of pathnames, and is hard to do securely, because the shared memory object resides in the global path space and could be interfered with by processes that aren't meant to access it.
For the steps to follow when using shm_revoke() and handles for shared memory objects, see
Secure buffer management
in the Shared Memory
chapter of the QNX OS Programmer's Guide.
For an example of how a server can create a shared memory object handle and provide it to a client so it can access the object from its own process, see below.
Returns:
0 on success, or -1 if an error occurred (errno is set).
Errors:
- EACCES
- Permission to create the handle is denied because the access modes specified by flags are denied.
- EAGAIN
- The process has created a number of handles that have not been consumed (opened, mapped, or deleted) greater than its allowed limit specified for RLIMIT_SHM_HANDLES_NP (refer to prlimit()).
- EBADF
- The specified file descriptor does not exist.
- EINVAL
- An illegal flag, meaning a flag other than one indicating the access mode, was given in flags (see the parameter description).
- ENOMEM
- There's insufficient memory to create a shared object handle.
- ESRCH
- The process ID in pid is invalid.
Example:
int shm_fd;
int chid;
rcvid_t rcvid;
// Your application will likely have its own data structure for representing messages
// received from clients.
mymsg_t msg;
shm_handle_t handle = 0;
struct _msg_info info;
void* ptr;
// Create a shared memory object and truncate its size.
shm_fd = shm_open(SHM_ANON, O_RDWR | O_CREAT | O_TRUNC, 0600);
ftruncate(shm_fd, __PAGESIZE);
// Map the memory object into our own address space.
ptr = mmap(0, __PAGESIZE, PROT_READ | PROT_WRITE, MAP_SHARED, shm_fd, 0);
// Populate the shared memory.
snprintf(ptr, __PAGESIZE, "Hello from %d", getpid());
// Create a channel to receive client messages.
chid = ChannelCreate(0);
// Wait for a message from the client.
rcvid = MsgReceive(chid, &msg, sizeof(msg), &info);
// Create a client-specific, read-only handle for the object.
shm_create_handle(shm_fd, info.pid, O_RDONLY, &handle, 0);
// Tell the client about the handle.
MsgReply(rcvid, 0, &handle, sizeof(handle));
Classification:
Safety: | |
---|---|
Cancellation point | No |
Signal handler | Yes |
Thread | Yes |