1
0
mirror of https://github.com/samba-team/samba.git synced 2025-02-02 09:47:23 +03:00

messaging_dgm: Avoid talloc_tos()

Signed-off-by: Volker Lendecke <vl@samba.org>
Reviewed-by: Stefan Metzmacher <metze@samba.org>
This commit is contained in:
Volker Lendecke 2014-09-10 09:58:00 +02:00 committed by Stefan Metzmacher
parent 2858c666b5
commit c3f98b9789

View File

@ -27,6 +27,13 @@
#include "poll_funcs/poll_funcs_tevent.h" #include "poll_funcs/poll_funcs_tevent.h"
#include "unix_msg/unix_msg.h" #include "unix_msg/unix_msg.h"
struct sun_path_buf {
/*
* This will carry enough for a socket path
*/
char buf[sizeof(struct sockaddr_un)];
};
struct messaging_dgm_context { struct messaging_dgm_context {
pid_t pid; pid_t pid;
struct poll_funcs *msg_callbacks; struct poll_funcs *msg_callbacks;
@ -47,12 +54,18 @@ static void messaging_dgm_recv(struct unix_msg_ctx *ctx,
uint8_t *msg, size_t msg_len, uint8_t *msg, size_t msg_len,
void *private_data); void *private_data);
static char *messaging_dgm_lockfile_name(TALLOC_CTX *mem_ctx, static int messaging_dgm_lockfile_name(struct sun_path_buf *buf,
const char *cache_dir, const char *cache_dir,
pid_t pid) pid_t pid)
{ {
return talloc_asprintf(mem_ctx, "%s/lck/%u", cache_dir, int ret;
(unsigned)pid);
ret = snprintf(buf->buf, sizeof(buf->buf), "%s/lck/%u", cache_dir,
(unsigned)pid);
if (ret >= sizeof(buf->buf)) {
return ENAMETOOLONG;
}
return 0;
} }
static int messaging_dgm_context_destructor(struct messaging_dgm_context *c); static int messaging_dgm_context_destructor(struct messaging_dgm_context *c);
@ -63,21 +76,23 @@ static int messaging_dgm_lockfile_create(TALLOC_CTX *tmp_ctx,
int *plockfile_fd, uint64_t unique) int *plockfile_fd, uint64_t unique)
{ {
fstring buf; fstring buf;
char *dir; struct sun_path_buf dir;
char *lockfile_name; struct sun_path_buf lockfile_name;
int lockfile_fd; int lockfile_fd;
struct flock lck; struct flock lck;
int unique_len, ret; int unique_len, ret;
ssize_t written; ssize_t written;
bool ok; bool ok;
dir = talloc_asprintf(tmp_ctx, "%s/lck", cache_dir); ret = messaging_dgm_lockfile_name(&lockfile_name, cache_dir, pid);
if (dir == NULL) { if (ret != 0) {
return ENOMEM; return ret;
} }
ok = directory_create_or_exist_strict(dir, dir_owner, 0755); /* shorter than lockfile_name, can't overflow */
TALLOC_FREE(dir); snprintf(dir.buf, sizeof(dir.buf), "%s/lck", cache_dir);
ok = directory_create_or_exist_strict(dir.buf, dir_owner, 0755);
if (!ok) { if (!ok) {
ret = errno; ret = errno;
DEBUG(1, ("%s: Could not create lock directory: %s\n", DEBUG(1, ("%s: Could not create lock directory: %s\n",
@ -85,18 +100,14 @@ static int messaging_dgm_lockfile_create(TALLOC_CTX *tmp_ctx,
return ret; return ret;
} }
lockfile_name = messaging_dgm_lockfile_name(tmp_ctx, cache_dir, pid);
if (lockfile_name == NULL) {
return ENOMEM;
}
/* no O_EXCL, existence check is via the fcntl lock */ /* no O_EXCL, existence check is via the fcntl lock */
lockfile_fd = open(lockfile_name, O_NONBLOCK|O_CREAT|O_WRONLY, 0644); lockfile_fd = open(lockfile_name.buf, O_NONBLOCK|O_CREAT|O_WRONLY,
0644);
if (lockfile_fd == -1) { if (lockfile_fd == -1) {
ret = errno; ret = errno;
DEBUG(1, ("%s: open failed: %s\n", __func__, strerror(errno))); DEBUG(1, ("%s: open failed: %s\n", __func__, strerror(errno)));
goto fail_free; return ret;
} }
lck = (struct flock) { lck = (struct flock) {
@ -130,38 +141,34 @@ static int messaging_dgm_lockfile_create(TALLOC_CTX *tmp_ctx,
goto fail_unlink; goto fail_unlink;
} }
TALLOC_FREE(lockfile_name);
*plockfile_fd = lockfile_fd; *plockfile_fd = lockfile_fd;
return 0; return 0;
fail_unlink: fail_unlink:
unlink(lockfile_name); unlink(lockfile_name.buf);
fail_close: fail_close:
close(lockfile_fd); close(lockfile_fd);
fail_free:
TALLOC_FREE(lockfile_name);
return ret; return ret;
} }
static int messaging_dgm_lockfile_remove(TALLOC_CTX *tmp_ctx, static int messaging_dgm_lockfile_remove(TALLOC_CTX *tmp_ctx,
const char *cache_dir, pid_t pid) const char *cache_dir, pid_t pid)
{ {
char *lockfile_name; struct sun_path_buf lockfile_name;
int ret; int ret;
lockfile_name = messaging_dgm_lockfile_name(tmp_ctx, cache_dir, pid); ret = messaging_dgm_lockfile_name(&lockfile_name, cache_dir, pid);
if (lockfile_name == NULL) { if (ret != 0) {
return ENOMEM; return ret;
} }
ret = unlink(lockfile_name); ret = unlink(lockfile_name.buf);
if (ret == -1) { if (ret == -1) {
ret = errno; ret = errno;
DEBUG(10, ("%s: unlink(%s) failed: %s\n", __func__, DEBUG(10, ("%s: unlink(%s) failed: %s\n", __func__,
lockfile_name, strerror(ret))); lockfile_name.buf, strerror(ret)));
} }
TALLOC_FREE(lockfile_name);
return ret; return ret;
} }
@ -320,30 +327,26 @@ static void messaging_dgm_recv(struct unix_msg_ctx *ctx,
int messaging_dgm_cleanup(struct messaging_dgm_context *ctx, pid_t pid) int messaging_dgm_cleanup(struct messaging_dgm_context *ctx, pid_t pid)
{ {
char *lockfile_name, *socket_name; struct sun_path_buf lockfile_name, socket_name;
int fd, ret; int fd, ret;
struct flock lck = {}; struct flock lck = {};
lockfile_name = messaging_dgm_lockfile_name( ret = messaging_dgm_lockfile_name(&lockfile_name, ctx->cache_dir, pid);
talloc_tos(), ctx->cache_dir, pid); if (ret != 0) {
if (lockfile_name == NULL) { return ret;
return ENOMEM;
}
socket_name = talloc_asprintf(lockfile_name, "%s/msg/%u",
ctx->cache_dir, (unsigned)pid);
if (socket_name == NULL) {
TALLOC_FREE(lockfile_name);
return ENOMEM;
} }
fd = open(lockfile_name, O_NONBLOCK|O_WRONLY, 0); /* same length as lockfile_name, can't overflow */
snprintf(socket_name.buf, sizeof(socket_name.buf), "%s/msg/%u",
ctx->cache_dir, (unsigned)pid);
fd = open(lockfile_name.buf, O_NONBLOCK|O_WRONLY, 0);
if (fd == -1) { if (fd == -1) {
ret = errno; ret = errno;
if (ret != ENOENT) { if (ret != ENOENT) {
DEBUG(10, ("%s: open(%s) failed: %s\n", __func__, DEBUG(10, ("%s: open(%s) failed: %s\n", __func__,
lockfile_name, strerror(ret))); lockfile_name.buf, strerror(ret)));
} }
TALLOC_FREE(lockfile_name);
return ret; return ret;
} }
@ -357,22 +360,19 @@ int messaging_dgm_cleanup(struct messaging_dgm_context *ctx, pid_t pid)
ret = errno; ret = errno;
DEBUG(10, ("%s: Could not get lock: %s\n", __func__, DEBUG(10, ("%s: Could not get lock: %s\n", __func__,
strerror(ret))); strerror(ret)));
TALLOC_FREE(lockfile_name);
close(fd); close(fd);
return ret; return ret;
} }
(void)unlink(socket_name); (void)unlink(socket_name.buf);
(void)unlink(lockfile_name); (void)unlink(lockfile_name.buf);
(void)close(fd); (void)close(fd);
TALLOC_FREE(lockfile_name);
return 0; return 0;
} }
int messaging_dgm_wipe(struct messaging_dgm_context *ctx) int messaging_dgm_wipe(struct messaging_dgm_context *ctx)
{ {
char *msgdir_name; struct sun_path_buf msgdir_name;
DIR *msgdir; DIR *msgdir;
struct dirent *dp; struct dirent *dp;
pid_t our_pid = getpid(); pid_t our_pid = getpid();
@ -384,18 +384,17 @@ int messaging_dgm_wipe(struct messaging_dgm_context *ctx)
* and fcntl(SETLK). * and fcntl(SETLK).
*/ */
msgdir_name = talloc_asprintf(talloc_tos(), "%s/msg", ctx->cache_dir); ret = snprintf(msgdir_name.buf, sizeof(msgdir_name.buf),
if (msgdir_name == NULL) { "%s/msg", ctx->cache_dir);
return ENOMEM; if (ret >= sizeof(msgdir_name.buf)) {
return ENAMETOOLONG;
} }
msgdir = opendir(msgdir_name); msgdir = opendir(msgdir_name.buf);
if (msgdir == NULL) { if (msgdir == NULL) {
ret = errno; ret = errno;
TALLOC_FREE(msgdir_name);
return ret; return ret;
} }
TALLOC_FREE(msgdir_name);
while ((dp = readdir(msgdir)) != NULL) { while ((dp = readdir(msgdir)) != NULL) {
unsigned long pid; unsigned long pid;