Skip to content

Commit

Permalink
Add user control of the permissions that are set on the shared mem files
Browse files Browse the repository at this point in the history
Signed-off-by: Angus Salkeld <asalkeld@redhat.com>
  • Loading branch information
asalkeld committed Jun 12, 2012
1 parent e70e790 commit 22569f5
Show file tree
Hide file tree
Showing 7 changed files with 116 additions and 42 deletions.
19 changes: 19 additions & 0 deletions include/qb/qbipcs.h
Expand Up @@ -117,6 +117,8 @@ struct qb_ipcs_poll_handlers {
* The type of checks you should do are authentication, service availabilty
* or process resource constraints.
* @return 0 to accept or -errno to indicate a failure (sent back to the client)
*
* @note you can call qb_ipcs_connection_auth_set() within this function.
*/
typedef int32_t (*qb_ipcs_connection_accept_fn) (qb_ipcs_connection_t *c,
uid_t uid, gid_t gid);
Expand Down Expand Up @@ -377,6 +379,23 @@ qb_ipcs_connection_t * qb_ipcs_connection_first_get(qb_ipcs_service_t* pt);
qb_ipcs_connection_t * qb_ipcs_connection_next_get(qb_ipcs_service_t* pt,
qb_ipcs_connection_t *current);

/**
* Set the permissions on and shared memory files so that both processes can
* read and write to them.
*
* @param conn connection instance
* @param uid the user id to set.
* @param gid the group id to set.
* @param mode the mode to set.
*
* @see chmod() chown()
* @note this must be called within the qb_ipcs_connection_accept_fn()
* callback.
*/
void qb_ipcs_connection_auth_set(qb_ipcs_connection_t *conn, uid_t uid,
gid_t gid, mode_t mode);


/* *INDENT-OFF* */
#ifdef __cplusplus
}
Expand Down
8 changes: 8 additions & 0 deletions include/qb/qbrb.h
Expand Up @@ -285,6 +285,14 @@ qb_ringbuffer_t *qb_rb_create_from_file(int32_t fd, uint32_t flags);
*/
int32_t qb_rb_chown(qb_ringbuffer_t * rb, uid_t owner, gid_t group);

/**
* Like 'chmod' it changes the mode of the ringbuffers resources.
* @param mode mode to change to
* @param rb ringbuffer instance
* @retval 0 == ok
* @retval -errno for error
*/
int32_t qb_rb_chmod(qb_ringbuffer_t * rb, mode_t mode);

/* *INDENT-OFF* */
#ifdef __cplusplus
Expand Down
7 changes: 7 additions & 0 deletions lib/ipc_int.h
Expand Up @@ -156,12 +156,19 @@ enum qb_ipcs_connection_state {

#define CONNECTION_DESCRIPTION (16)

struct qb_ipcs_connection_auth {
uid_t uid;
gid_t gid;
mode_t mode;
};

struct qb_ipcs_connection {
enum qb_ipcs_connection_state state;
int32_t refcount;
pid_t pid;
uid_t euid;
gid_t egid;
struct qb_ipcs_connection_auth auth;
struct qb_ipc_one_way setup;
struct qb_ipc_one_way request;
struct qb_ipc_one_way response;
Expand Down
80 changes: 41 additions & 39 deletions lib/ipc_shm.c
Expand Up @@ -233,6 +233,40 @@ qb_ipcs_shm_disconnect(struct qb_ipcs_connection *c)
}
}

static int32_t
qb_ipcs_shm_rb_open(struct qb_ipcs_connection *c,
struct qb_ipc_one_way *ow,
const char *rb_name)
{
int32_t res = 0;

ow->u.shm.rb = qb_rb_open(rb_name,
ow->max_msg_size,
QB_RB_FLAG_CREATE |
QB_RB_FLAG_SHARED_PROCESS,
sizeof(int32_t));
if (ow->u.shm.rb == NULL) {
res = -errno;
qb_util_perror(LOG_ERR, "qb_rb_open:%s", rb_name);
return res;
}
res = qb_rb_chown(ow->u.shm.rb, c->auth.uid, c->auth.gid);
if (res != 0) {
qb_util_perror(LOG_ERR, "qb_rb_chown:%s", rb_name);
goto cleanup;
}
res = qb_rb_chmod(ow->u.shm.rb, c->auth.mode);
if (res != 0) {
qb_util_perror(LOG_ERR, "qb_rb_chmod:%s", rb_name);
goto cleanup;
}
return res;

cleanup:
qb_rb_close(ow->u.shm.rb);
return res;
}

static int32_t
qb_ipcs_shm_connect(struct qb_ipcs_service *s,
struct qb_ipcs_connection *c,
Expand All @@ -249,59 +283,27 @@ qb_ipcs_shm_connect(struct qb_ipcs_service *s,
snprintf(r->event, NAME_MAX, "%s-event-%s",
s->name, c->description);

c->request.u.shm.rb = qb_rb_open(r->request,
c->request.max_msg_size,
QB_RB_FLAG_CREATE |
QB_RB_FLAG_SHARED_PROCESS,
sizeof(int32_t));
if (c->request.u.shm.rb == NULL) {
res = -errno;
qb_util_perror(LOG_ERR, "qb_rb_open:%s", r->request);
goto cleanup;
}
res = qb_rb_chown(c->request.u.shm.rb, c->euid, c->egid);
res = qb_ipcs_shm_rb_open(c, &c->request,
r->request);
if (res != 0) {
qb_util_perror(LOG_ERR, "qb_rb_chown:%s", r->request);
goto cleanup;
}

c->response.u.shm.rb = qb_rb_open(r->response,
c->response.max_msg_size,
QB_RB_FLAG_CREATE |
QB_RB_FLAG_SHARED_PROCESS, 0);
if (c->response.u.shm.rb == NULL) {
res = -errno;
qb_util_perror(LOG_ERR, "qb_rb_open:%s", r->response);
goto cleanup_request;
}
res = qb_rb_chown(c->response.u.shm.rb, c->euid, c->egid);
res = qb_ipcs_shm_rb_open(c, &c->response,
r->response);
if (res != 0) {
qb_util_perror(LOG_ERR, "qb_rb_chown:%s", r->response);
goto cleanup_request;
}

c->event.u.shm.rb = qb_rb_open(r->event,
c->event.max_msg_size,
QB_RB_FLAG_CREATE |
QB_RB_FLAG_SHARED_PROCESS, 0);

if (c->event.u.shm.rb == NULL) {
res = -errno;
qb_util_perror(LOG_ERR, "qb_rb_open:%s", r->event);
goto cleanup_request_response;
}
res = qb_rb_chown(c->event.u.shm.rb, c->euid, c->egid);
res = qb_ipcs_shm_rb_open(c, &c->event,
r->event);
if (res != 0) {
qb_util_perror(LOG_ERR, "qb_rb_chown:%s", r->event);
goto cleanup_all;
goto cleanup_request_response;
}

r->hdr.error = 0;
return 0;

cleanup_all:
qb_rb_close(c->event.u.shm.rb);

cleanup_request_response:
qb_rb_close(c->request.u.shm.rb);

Expand Down
14 changes: 11 additions & 3 deletions lib/ipc_us.c
Expand Up @@ -615,8 +615,9 @@ handle_new_connection(struct qb_ipcs_service *s,
c->response.max_msg_size = req->max_msg_size;
c->event.max_msg_size = req->max_msg_size;
c->pid = ugp->pid;
c->euid = ugp->uid;
c->egid = ugp->gid;
c->auth.uid = c->euid = ugp->uid;
c->auth.gid = c->egid = ugp->gid;
c->auth.mode = 0600;
c->stats.client_pid = ugp->pid;
snprintf(c->description, CONNECTION_DESCRIPTION,
"%d-%d-%d", s->pid, ugp->pid,
Expand Down Expand Up @@ -949,12 +950,19 @@ qb_ipcs_us_connect(struct qb_ipcs_service *s,
}
(void)strlcpy(r->request, path, PATH_MAX);
(void)strlcpy(c->request.u.us.shared_file_name, r->request, NAME_MAX);
res = chown(r->request, c->euid, c->egid);
res = chown(r->request, c->auth.uid, c->auth.gid);
if (res != 0) {
/* ignore res, this is just for the compiler warnings.
*/
res = 0;
}
res = chmod(r->request, c->auth.mode);
if (res != 0) {
/* ignore res, this is just for the compiler warnings.
*/
res = 0;
}

shm_ptr = mmap(0, SHM_CONTROL_SIZE,
PROT_READ | PROT_WRITE, MAP_SHARED, fd_hdr, 0);

Expand Down
11 changes: 11 additions & 0 deletions lib/ipcs.c
Expand Up @@ -864,3 +864,14 @@ qb_ipcs_stats_get(struct qb_ipcs_service * s,
}
return 0;
}

void
qb_ipcs_connection_auth_set(qb_ipcs_connection_t *c, uid_t uid,
gid_t gid, mode_t mode)
{
if (c) {
c->auth.uid = uid;
c->auth.gid = gid;
c->auth.mode = mode;
}
}
19 changes: 19 additions & 0 deletions lib/ringbuffer.c
Expand Up @@ -769,3 +769,22 @@ qb_rb_chown(struct qb_ringbuffer_s * rb, uid_t owner, gid_t group)
}
return 0;
}

int32_t
qb_rb_chmod(qb_ringbuffer_t * rb, mode_t mode)
{
int32_t res;

if (rb == NULL) {
return -EINVAL;
}
res = chmod(rb->shared_hdr->data_path, mode);
if (res < 0) {
return -errno;
}
res = chmod(rb->shared_hdr->hdr_path, mode);
if (res < 0) {
return -errno;
}
return 0;
}

0 comments on commit 22569f5

Please sign in to comment.