mirror of
https://github.com/openvswitch/ovs
synced 2025-08-22 09:58:01 +00:00
This commit adds zero-initializations by changing `SFL_ALLOC` from `malloc` to `xzalloc`, adding a `memset` call to `sflAlloc`, initializing a `pollfd` struct variable with zeroes, and changing some calls to `xmalloc` to `xzalloc`. This is to prevent potential data leaks or undefined behavior from potentially uninitialized variables. Some variables would always be initialized by either the code flow or the compiler. Thus, some of the associated Coverity reports might be false positives. That said, it is still considered best practice to zero-initialize variables upfront just in case to ensure the overall resilience and security of OVS, as long as they do not impact performance-critical code. As a bonus, it would also make static analyzer tools, such as Coverity, happy. Reviewed-by: Simon Horman <simon.horman@corigine.com> Signed-off-by: James Raphael Tiovalen <jamestiotio@gmail.com> Signed-off-by: Ilya Maximets <i.maximets@ovn.org>
96 lines
2.3 KiB
C
96 lines
2.3 KiB
C
/*
|
|
* Copyright (c) 2013 Nicira, Inc.
|
|
*
|
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
* you may not use this file except in compliance with the License.
|
|
* You may obtain a copy of the License at:
|
|
*
|
|
* http://www.apache.org/licenses/LICENSE-2.0
|
|
*
|
|
* Unless required by applicable law or agreed to in writing, software
|
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
* See the License for the specific language governing permissions and
|
|
* limitations under the License.
|
|
*/
|
|
|
|
#include <config.h>
|
|
|
|
#include "latch.h"
|
|
#include <errno.h>
|
|
#include <poll.h>
|
|
#include <unistd.h>
|
|
#include "openvswitch/poll-loop.h"
|
|
#include "socket-util.h"
|
|
|
|
/* Initializes 'latch' as initially unset. */
|
|
void
|
|
latch_init(struct latch *latch)
|
|
{
|
|
xpipe_nonblocking(latch->fds);
|
|
}
|
|
|
|
/* Destroys 'latch'. */
|
|
void
|
|
latch_destroy(struct latch *latch)
|
|
{
|
|
close(latch->fds[0]);
|
|
close(latch->fds[1]);
|
|
}
|
|
|
|
/* Resets 'latch' to the unset state. Returns true if 'latch' was previously
|
|
* set, false otherwise. */
|
|
bool
|
|
latch_poll(struct latch *latch)
|
|
{
|
|
char latch_buffer[16];
|
|
bool result = false;
|
|
int ret;
|
|
|
|
do {
|
|
ret = read(latch->fds[0], &latch_buffer, sizeof latch_buffer);
|
|
result |= ret > 0;
|
|
/* Repeat as long as read() reads a full buffer. */
|
|
} while (ret == sizeof latch_buffer);
|
|
|
|
return result;
|
|
}
|
|
|
|
/* Sets 'latch'.
|
|
*
|
|
* Calls are not additive: a single latch_poll() clears out any number of
|
|
* latch_set(). */
|
|
void
|
|
latch_set(struct latch *latch)
|
|
{
|
|
ignore(write(latch->fds[1], "", 1));
|
|
}
|
|
|
|
/* Returns true if 'latch' is set, false otherwise. Does not reset 'latch'
|
|
* to the unset state. */
|
|
bool
|
|
latch_is_set(const struct latch *latch)
|
|
{
|
|
struct pollfd pfd = {0};
|
|
int retval;
|
|
|
|
pfd.fd = latch->fds[0];
|
|
pfd.events = POLLIN;
|
|
do {
|
|
retval = poll(&pfd, 1, 0);
|
|
} while (retval < 0 && errno == EINTR);
|
|
|
|
return pfd.revents & POLLIN;
|
|
}
|
|
|
|
/* Causes the next poll_block() to wake up when 'latch' is set.
|
|
*
|
|
* ('where' is used in debug logging. Commonly one would use latch_wait() to
|
|
* automatically provide the caller's source file and line number for
|
|
* 'where'.) */
|
|
void
|
|
latch_wait_at(const struct latch *latch, const char *where)
|
|
{
|
|
poll_fd_wait_at(latch->fds[0], POLLIN, where);
|
|
}
|