mirror of
https://github.com/freebsd/freebsd-src
synced 2024-10-15 21:05:08 +00:00
Approved, oprócz użycie RESTORE_ERRNO() do ustawiania errno.
Change the nvlist_recv() function to take additional argument that specifies flags expected on the received nvlist. Receiving a nvlist with different set of flags than the ones we expect might lead to undefined behaviour, which might be potentially dangerous. Update consumers of this and related functions and update the tests. Approved by: pjd (mentor) Update man page for nvlist_unpack, nvlist_recv, nvlist_xfer, cap_recv_nvlist and cap_xfer_nvlist. Reviewed by: AllanJude Approved by: pjd (mentor)
This commit is contained in:
parent
1025d8e679
commit
bd1da0a002
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=282346
|
@ -27,7 +27,7 @@
|
|||
.\"
|
||||
.\" $FreeBSD$
|
||||
.\"
|
||||
.Dd April 14, 2014
|
||||
.Dd May 2, 2015
|
||||
.Dt LIBCAPSICUM 3
|
||||
.Os
|
||||
.Sh NAME
|
||||
|
@ -68,9 +68,9 @@
|
|||
.Ft "int"
|
||||
.Fn cap_send_nvlist "const cap_channel_t *chan" "const nvlist_t *nvl"
|
||||
.Ft "nvlist_t *"
|
||||
.Fn cap_recv_nvlist "const cap_channel_t *chan"
|
||||
.Fn cap_recv_nvlist "const cap_channel_t *chan" "int flags"
|
||||
.Ft "nvlist_t *"
|
||||
.Fn cap_xfer_nvlist "const cap_channel_t *chan" "nvlist_t *nvl"
|
||||
.Fn cap_xfer_nvlist "const cap_channel_t *chan" "nvlist_t *nvl" "int flags"
|
||||
.In libcapsicum_service.h
|
||||
.Ft "cap_channel_t *"
|
||||
.Fn cap_service_open "const cap_channel_t *chan" "const char *name"
|
||||
|
@ -171,11 +171,23 @@ Most services should provide higher level API.
|
|||
The
|
||||
.Fn cap_recv_nvlist
|
||||
function receives the given nvlist over the given capability.
|
||||
The
|
||||
.Fa flags
|
||||
argument defines what type the top nvlist is expected to be.
|
||||
If the nvlist flags do not match the flags passed to
|
||||
.Fn cap_recv_nvlist ,
|
||||
the nvlist will not be returned.
|
||||
.Pp
|
||||
The
|
||||
.Fn cap_xfer_nvlist
|
||||
function sends the given nvlist, destroys it and receives new nvlist in
|
||||
response over the given capability.
|
||||
The
|
||||
.Fa flags
|
||||
argument defines what type the top nvlist is expected to be.
|
||||
If the nvlist flags do not match the flags passed to
|
||||
.Fn cap_xfer_nvlist ,
|
||||
the nvlist will not be returned.
|
||||
It does not matter if the function succeeds or fails, the nvlist given
|
||||
for sending will always be destroyed once the function returns.
|
||||
.Pp
|
||||
|
|
|
@ -142,7 +142,7 @@ cap_clone(const cap_channel_t *chan)
|
|||
|
||||
nvl = nvlist_create(0);
|
||||
nvlist_add_string(nvl, "cmd", "clone");
|
||||
nvl = cap_xfer_nvlist(chan, nvl);
|
||||
nvl = cap_xfer_nvlist(chan, nvl, 0);
|
||||
if (nvl == NULL)
|
||||
return (NULL);
|
||||
if (nvlist_get_number(nvl, "error") != 0) {
|
||||
|
@ -195,7 +195,7 @@ cap_limit_set(const cap_channel_t *chan, nvlist_t *limits)
|
|||
nvlmsg = nvlist_create(0);
|
||||
nvlist_add_string(nvlmsg, "cmd", "limit_set");
|
||||
nvlist_add_nvlist(nvlmsg, "limits", limits);
|
||||
nvlmsg = cap_xfer_nvlist(chan, nvlmsg);
|
||||
nvlmsg = cap_xfer_nvlist(chan, nvlmsg, 0);
|
||||
if (nvlmsg == NULL) {
|
||||
nvlist_destroy(limits);
|
||||
return (-1);
|
||||
|
@ -218,7 +218,7 @@ cap_limit_get(const cap_channel_t *chan, nvlist_t **limitsp)
|
|||
|
||||
nvlmsg = nvlist_create(0);
|
||||
nvlist_add_string(nvlmsg, "cmd", "limit_get");
|
||||
nvlmsg = cap_xfer_nvlist(chan, nvlmsg);
|
||||
nvlmsg = cap_xfer_nvlist(chan, nvlmsg, 0);
|
||||
if (nvlmsg == NULL)
|
||||
return (-1);
|
||||
error = (int)nvlist_get_number(nvlmsg, "error");
|
||||
|
@ -246,21 +246,21 @@ cap_send_nvlist(const cap_channel_t *chan, const nvlist_t *nvl)
|
|||
}
|
||||
|
||||
nvlist_t *
|
||||
cap_recv_nvlist(const cap_channel_t *chan)
|
||||
cap_recv_nvlist(const cap_channel_t *chan, int flags)
|
||||
{
|
||||
|
||||
assert(chan != NULL);
|
||||
assert(chan->cch_magic == CAP_CHANNEL_MAGIC);
|
||||
|
||||
return (nvlist_recv(chan->cch_sock));
|
||||
return (nvlist_recv(chan->cch_sock, flags));
|
||||
}
|
||||
|
||||
nvlist_t *
|
||||
cap_xfer_nvlist(const cap_channel_t *chan, nvlist_t *nvl)
|
||||
cap_xfer_nvlist(const cap_channel_t *chan, nvlist_t *nvl, int flags)
|
||||
{
|
||||
|
||||
assert(chan != NULL);
|
||||
assert(chan->cch_magic == CAP_CHANNEL_MAGIC);
|
||||
|
||||
return (nvlist_xfer(chan->cch_sock, nvl));
|
||||
return (nvlist_xfer(chan->cch_sock, nvl, flags));
|
||||
}
|
||||
|
|
|
@ -105,11 +105,11 @@ int cap_send_nvlist(const cap_channel_t *chan, const nvlist_t *nvl);
|
|||
/*
|
||||
* Function receives nvlist over the given capability.
|
||||
*/
|
||||
nvlist_t *cap_recv_nvlist(const cap_channel_t *chan);
|
||||
nvlist_t *cap_recv_nvlist(const cap_channel_t *chan, int flags);
|
||||
/*
|
||||
* Function sends the given nvlist, destroys it and receives new nvlist in
|
||||
* response over the given capability.
|
||||
*/
|
||||
nvlist_t *cap_xfer_nvlist(const cap_channel_t *chan, nvlist_t *nvl);
|
||||
nvlist_t *cap_xfer_nvlist(const cap_channel_t *chan, nvlist_t *nvl, int flags);
|
||||
|
||||
#endif /* !_LIBCAPSICUM_H_ */
|
||||
|
|
|
@ -132,7 +132,7 @@ cap_gethostbyname2(cap_channel_t *chan, const char *name, int type)
|
|||
nvlist_add_string(nvl, "cmd", "gethostbyname");
|
||||
nvlist_add_number(nvl, "family", (uint64_t)type);
|
||||
nvlist_add_string(nvl, "name", name);
|
||||
nvl = cap_xfer_nvlist(chan, nvl);
|
||||
nvl = cap_xfer_nvlist(chan, nvl, 0);
|
||||
if (nvl == NULL) {
|
||||
h_errno = NO_RECOVERY;
|
||||
return (NULL);
|
||||
|
@ -159,7 +159,7 @@ cap_gethostbyaddr(cap_channel_t *chan, const void *addr, socklen_t len,
|
|||
nvlist_add_string(nvl, "cmd", "gethostbyaddr");
|
||||
nvlist_add_binary(nvl, "addr", addr, (size_t)len);
|
||||
nvlist_add_number(nvl, "family", (uint64_t)type);
|
||||
nvl = cap_xfer_nvlist(chan, nvl);
|
||||
nvl = cap_xfer_nvlist(chan, nvl, 0);
|
||||
if (nvl == NULL) {
|
||||
h_errno = NO_RECOVERY;
|
||||
return (NULL);
|
||||
|
@ -233,7 +233,7 @@ cap_getaddrinfo(cap_channel_t *chan, const char *hostname, const char *servname,
|
|||
nvlist_add_number(nvl, "hints.ai_protocol",
|
||||
(uint64_t)hints->ai_protocol);
|
||||
}
|
||||
nvl = cap_xfer_nvlist(chan, nvl);
|
||||
nvl = cap_xfer_nvlist(chan, nvl, 0);
|
||||
if (nvl == NULL)
|
||||
return (EAI_MEMORY);
|
||||
if (nvlist_get_number(nvl, "error") != 0) {
|
||||
|
@ -283,7 +283,7 @@ cap_getnameinfo(cap_channel_t *chan, const struct sockaddr *sa, socklen_t salen,
|
|||
nvlist_add_number(nvl, "servlen", (uint64_t)servlen);
|
||||
nvlist_add_binary(nvl, "sa", sa, (size_t)salen);
|
||||
nvlist_add_number(nvl, "flags", (uint64_t)flags);
|
||||
nvl = cap_xfer_nvlist(chan, nvl);
|
||||
nvl = cap_xfer_nvlist(chan, nvl, 0);
|
||||
if (nvl == NULL)
|
||||
return (EAI_MEMORY);
|
||||
if (nvlist_get_number(nvl, "error") != 0) {
|
||||
|
|
|
@ -195,7 +195,7 @@ cap_getgrcommon_r(cap_channel_t *chan, const char *cmd, const char *name,
|
|||
} else {
|
||||
abort();
|
||||
}
|
||||
nvl = cap_xfer_nvlist(chan, nvl);
|
||||
nvl = cap_xfer_nvlist(chan, nvl, 0);
|
||||
if (nvl == NULL) {
|
||||
assert(errno != 0);
|
||||
*result = NULL;
|
||||
|
@ -319,7 +319,7 @@ cap_setgroupent(cap_channel_t *chan, int stayopen)
|
|||
nvl = nvlist_create(0);
|
||||
nvlist_add_string(nvl, "cmd", "setgroupent");
|
||||
nvlist_add_bool(nvl, "stayopen", stayopen != 0);
|
||||
nvl = cap_xfer_nvlist(chan, nvl);
|
||||
nvl = cap_xfer_nvlist(chan, nvl, 0);
|
||||
if (nvl == NULL)
|
||||
return (0);
|
||||
if (nvlist_get_number(nvl, "error") != 0) {
|
||||
|
@ -339,7 +339,7 @@ cap_setgrent(cap_channel_t *chan)
|
|||
|
||||
nvl = nvlist_create(0);
|
||||
nvlist_add_string(nvl, "cmd", "setgrent");
|
||||
nvl = cap_xfer_nvlist(chan, nvl);
|
||||
nvl = cap_xfer_nvlist(chan, nvl, 0);
|
||||
if (nvl == NULL)
|
||||
return (0);
|
||||
if (nvlist_get_number(nvl, "error") != 0) {
|
||||
|
@ -360,7 +360,7 @@ cap_endgrent(cap_channel_t *chan)
|
|||
nvl = nvlist_create(0);
|
||||
nvlist_add_string(nvl, "cmd", "endgrent");
|
||||
/* Ignore any errors, we have no way to report them. */
|
||||
nvlist_destroy(cap_xfer_nvlist(chan, nvl));
|
||||
nvlist_destroy(cap_xfer_nvlist(chan, nvl, 0));
|
||||
}
|
||||
|
||||
int
|
||||
|
|
|
@ -154,7 +154,7 @@ cap_getpwcommon_r(cap_channel_t *chan, const char *cmd, const char *login,
|
|||
} else {
|
||||
abort();
|
||||
}
|
||||
nvl = cap_xfer_nvlist(chan, nvl);
|
||||
nvl = cap_xfer_nvlist(chan, nvl, 0);
|
||||
if (nvl == NULL) {
|
||||
assert(errno != 0);
|
||||
*result = NULL;
|
||||
|
@ -278,7 +278,7 @@ cap_setpassent(cap_channel_t *chan, int stayopen)
|
|||
nvl = nvlist_create(0);
|
||||
nvlist_add_string(nvl, "cmd", "setpassent");
|
||||
nvlist_add_bool(nvl, "stayopen", stayopen != 0);
|
||||
nvl = cap_xfer_nvlist(chan, nvl);
|
||||
nvl = cap_xfer_nvlist(chan, nvl, 0);
|
||||
if (nvl == NULL)
|
||||
return (0);
|
||||
if (nvlist_get_number(nvl, "error") != 0) {
|
||||
|
@ -299,7 +299,7 @@ cap_set_end_pwent(cap_channel_t *chan, const char *cmd)
|
|||
nvl = nvlist_create(0);
|
||||
nvlist_add_string(nvl, "cmd", cmd);
|
||||
/* Ignore any errors, we have no way to report them. */
|
||||
nvlist_destroy(cap_xfer_nvlist(chan, nvl));
|
||||
nvlist_destroy(cap_xfer_nvlist(chan, nvl, 0));
|
||||
}
|
||||
|
||||
void
|
||||
|
|
|
@ -57,7 +57,7 @@ cap_random_buf(cap_channel_t *chan, void *buf, size_t nbytes)
|
|||
nvlist_add_string(nvl, "cmd", "generate");
|
||||
nvlist_add_number(nvl, "size",
|
||||
(uint64_t)(left > MAXSIZE ? MAXSIZE : left));
|
||||
nvl = cap_xfer_nvlist(chan, nvl);
|
||||
nvl = cap_xfer_nvlist(chan, nvl, 0);
|
||||
if (nvl == NULL)
|
||||
return (-1);
|
||||
if (nvlist_get_number(nvl, "error") != 0) {
|
||||
|
|
|
@ -56,7 +56,7 @@ cap_service_open(const cap_channel_t *chan, const char *name)
|
|||
nvlist_add_string(nvl, "service", name);
|
||||
if (fd_is_valid(STDERR_FILENO))
|
||||
nvlist_add_descriptor(nvl, "stderrfd", STDERR_FILENO);
|
||||
nvl = cap_xfer_nvlist(chan, nvl);
|
||||
nvl = cap_xfer_nvlist(chan, nvl, 0);
|
||||
if (nvl == NULL)
|
||||
return (NULL);
|
||||
error = (int)nvlist_get_number(nvl, "error");
|
||||
|
|
|
@ -63,7 +63,7 @@ cap_sysctlbyname(cap_channel_t *chan, const char *name, void *oldp,
|
|||
nvlist_add_number(nvl, "oldlen", (uint64_t)*oldlenp);
|
||||
if (newp != NULL)
|
||||
nvlist_add_binary(nvl, "newp", newp, newlen);
|
||||
nvl = cap_xfer_nvlist(chan, nvl);
|
||||
nvl = cap_xfer_nvlist(chan, nvl, 0);
|
||||
if (nvl == NULL)
|
||||
return (-1);
|
||||
if (nvlist_get_number(nvl, "error") != 0) {
|
||||
|
|
|
@ -279,7 +279,7 @@ casper_message(const cap_channel_t *capcas, struct service *service)
|
|||
const char *cmd;
|
||||
nvlist_t *nvl;
|
||||
|
||||
nvl = cap_recv_nvlist(capcas);
|
||||
nvl = cap_recv_nvlist(capcas, 0);
|
||||
if (nvl == NULL)
|
||||
pjdlog_exit(1, "Unable to receive message from Casper");
|
||||
cmd = nvlist_get_string(nvl, "cmd");
|
||||
|
@ -297,7 +297,7 @@ service_message(struct service *service, struct service_connection *sconn)
|
|||
const char *cmd;
|
||||
int error;
|
||||
|
||||
nvlin = cap_recv_nvlist(service_connection_get_chan(sconn));
|
||||
nvlin = cap_recv_nvlist(service_connection_get_chan(sconn), 0);
|
||||
if (nvlin == NULL) {
|
||||
if (errno == ENOTCONN) {
|
||||
pjdlog_debug(1, "Connection closed by the client.");
|
||||
|
|
|
@ -28,7 +28,7 @@
|
|||
.\"
|
||||
.\" $FreeBSD$
|
||||
.\"
|
||||
.Dd May 1, 2015
|
||||
.Dd May 2, 2015
|
||||
.Dt NV 3
|
||||
.Os
|
||||
.Sh NAME
|
||||
|
@ -85,14 +85,14 @@
|
|||
.Ft "void *"
|
||||
.Fn nvlist_pack "const nvlist_t *nvl" "size_t *sizep"
|
||||
.Ft "nvlist_t *"
|
||||
.Fn nvlist_unpack "const void *buf" "size_t size"
|
||||
.Fn nvlist_unpack "const void *buf" "size_t size" "int flags"
|
||||
.\"
|
||||
.Ft int
|
||||
.Fn nvlist_send "int sock" "const nvlist_t *nvl"
|
||||
.Ft "nvlist_t *"
|
||||
.Fn nvlist_recv "int sock"
|
||||
.Fn nvlist_recv "int sock" "int flags"
|
||||
.Ft "nvlist_t *"
|
||||
.Fn nvlist_xfer "int sock" "nvlist_t *nvl"
|
||||
.Fn nvlist_xfer "int sock" "nvlist_t *nvl" "int flags"
|
||||
.\"
|
||||
.Ft "const char *"
|
||||
.Fn nvlist_next "const nvlist_t *nvl" "int *typep" "void **cookiep"
|
||||
|
@ -325,6 +325,18 @@ The nvlist must not be in error state.
|
|||
The
|
||||
.Fn nvlist_unpack
|
||||
function converts the given buffer to the nvlist.
|
||||
The
|
||||
.Fa flags
|
||||
argument defines what type of the top level nvlist is expected to be.
|
||||
Flags are set up using the
|
||||
.Fn nvlist_create
|
||||
function.
|
||||
If the nvlist flags do not match the flags passed to
|
||||
.Fn nvlist_unpack ,
|
||||
the nvlist will not be returned.
|
||||
Every nested nvlist list should be checked using
|
||||
.Fn nvlist_flags
|
||||
function.
|
||||
The function returns
|
||||
.Dv NULL
|
||||
in case of an error.
|
||||
|
@ -343,12 +355,36 @@ The
|
|||
function receives nvlist over the socket given by the
|
||||
.Fa sock
|
||||
argument.
|
||||
The
|
||||
.Fa flags
|
||||
argument defines what type of the top level nvlist is expected to be.
|
||||
Flags are set up using the
|
||||
.Fn nvlist_create
|
||||
function.
|
||||
If the nvlist flags do not match the flags passed to
|
||||
.Fn nvlist_recv ,
|
||||
the nvlist will not be returned.
|
||||
Every nested nvlist list should be checked using
|
||||
.Fn nvlist_flags
|
||||
function.
|
||||
.Pp
|
||||
The
|
||||
.Fn nvlist_xfer
|
||||
function sends the given nvlist over the socket given by the
|
||||
.Fa sock
|
||||
argument and receives nvlist over the same socket.
|
||||
The
|
||||
.Fa flags
|
||||
argument defines what type of the top level nvlist is expected to be.
|
||||
Flags are set up using the
|
||||
.Fn nvlist_create
|
||||
function.
|
||||
If the nvlist flags do not match the flags passed to
|
||||
.Fn nvlist_xfer ,
|
||||
the nvlist will not be returned.
|
||||
Every nested nvlist list should be checked using
|
||||
.Fn nvlist_flags
|
||||
function.
|
||||
The given nvlist is always destroyed.
|
||||
.Pp
|
||||
The
|
||||
|
@ -559,7 +595,7 @@ const char *command;
|
|||
char *filename;
|
||||
int fd;
|
||||
|
||||
nvl = nvlist_recv(sock);
|
||||
nvl = nvlist_recv(sock, 0);
|
||||
if (nvl == NULL)
|
||||
err(1, "nvlist_recv() failed");
|
||||
|
||||
|
@ -588,7 +624,7 @@ const char *name;
|
|||
void *cookie;
|
||||
int type;
|
||||
|
||||
nvl = nvlist_recv(sock);
|
||||
nvl = nvlist_recv(sock, 0);
|
||||
if (nvl == NULL)
|
||||
err(1, "nvlist_recv() failed");
|
||||
|
||||
|
@ -617,7 +653,7 @@ const char *name;
|
|||
void *cookie;
|
||||
int type;
|
||||
|
||||
nvl = nvlist_recv(sock);
|
||||
nvl = nvlist_recv(sock, 0);
|
||||
if (nvl == NULL)
|
||||
err(1, "nvlist_recv() failed");
|
||||
|
||||
|
|
|
@ -440,7 +440,7 @@ ATF_TEST_CASE_BODY(nvlist_pack__empty_nvlist)
|
|||
packed = nvlist_pack(nvl, &packed_size);
|
||||
ATF_REQUIRE(packed != NULL);
|
||||
|
||||
unpacked = nvlist_unpack(packed, packed_size);
|
||||
unpacked = nvlist_unpack(packed, packed_size, 0);
|
||||
ATF_REQUIRE(unpacked != NULL);
|
||||
ATF_REQUIRE(unpacked != nvl);
|
||||
ATF_REQUIRE(nvlist_empty(unpacked));
|
||||
|
@ -534,7 +534,7 @@ ATF_TEST_CASE_BODY(nvlist_pack__multiple_values)
|
|||
packed = nvlist_pack(nvl, &packed_size);
|
||||
ATF_REQUIRE(packed != NULL);
|
||||
|
||||
unpacked = nvlist_unpack(packed, packed_size);
|
||||
unpacked = nvlist_unpack(packed, packed_size, 0);
|
||||
ATF_REQUIRE(unpacked != 0);
|
||||
|
||||
it = NULL;
|
||||
|
@ -614,7 +614,7 @@ ATF_TEST_CASE_BODY(nvlist_unpack__duplicate_key)
|
|||
ATF_REQUIRE(keypos != NULL);
|
||||
memcpy(keypos, key2, keylen);
|
||||
|
||||
unpacked = nvlist_unpack(packed, size);
|
||||
unpacked = nvlist_unpack(packed, size, 0);
|
||||
ATF_REQUIRE(nvlist_error(unpacked) != 0);
|
||||
|
||||
free(packed);
|
||||
|
|
|
@ -95,7 +95,7 @@ parent(int sock)
|
|||
int type, ctype;
|
||||
size_t size;
|
||||
|
||||
nvl = nvlist_recv(sock);
|
||||
nvl = nvlist_recv(sock, 0);
|
||||
CHECK(nvlist_error(nvl) == 0);
|
||||
if (nvlist_error(nvl) != 0)
|
||||
err(1, "nvlist_recv() failed");
|
||||
|
|
|
@ -357,7 +357,7 @@ service_external_execute(int chanfd)
|
|||
int stderrfd, execfd, procfd;
|
||||
nvlist_t *nvl;
|
||||
|
||||
nvl = nvlist_recv(chanfd);
|
||||
nvl = nvlist_recv(chanfd, 0);
|
||||
if (nvl == NULL)
|
||||
pjdlog_exit(1, "Unable to receive nvlist");
|
||||
service = nvlist_take_string(nvl, "service");
|
||||
|
|
|
@ -91,7 +91,7 @@ zygote_clone(zygote_func_t *func, int flags, int *chanfdp, int *procfdp)
|
|||
nvl = nvlist_create(0);
|
||||
nvlist_add_number(nvl, "func", (uint64_t)(uintptr_t)func);
|
||||
nvlist_add_number(nvl, "flags", (uint64_t)flags);
|
||||
nvl = nvlist_xfer(zygote_sock, nvl);
|
||||
nvl = nvlist_xfer(zygote_sock, nvl, 0);
|
||||
if (nvl == NULL)
|
||||
return (-1);
|
||||
if (nvlist_exists_number(nvl, "error")) {
|
||||
|
@ -134,7 +134,7 @@ zygote_main(int sock)
|
|||
closefrom(sock + 1);
|
||||
|
||||
for (;;) {
|
||||
nvlin = nvlist_recv(sock);
|
||||
nvlin = nvlist_recv(sock, 0);
|
||||
if (nvlin == NULL) {
|
||||
if (errno == ENOTCONN) {
|
||||
/* Casperd exited. */
|
||||
|
|
|
@ -386,7 +386,7 @@ pci_iov_parse_config(struct pcicfg_iov *iov, struct pci_iov_arg *arg,
|
|||
if (error != 0)
|
||||
goto out;
|
||||
|
||||
config = nvlist_unpack(packed_config, arg->len);
|
||||
config = nvlist_unpack(packed_config, arg->len, NV_FLAG_IGNORE_CASE);
|
||||
if (config == NULL) {
|
||||
error = EINVAL;
|
||||
goto out;
|
||||
|
|
|
@ -774,7 +774,8 @@ nvlist_unpack_header(nvlist_t *nvl, const unsigned char *ptr, size_t nfds,
|
|||
}
|
||||
|
||||
static nvlist_t *
|
||||
nvlist_xunpack(const void *buf, size_t size, const int *fds, size_t nfds)
|
||||
nvlist_xunpack(const void *buf, size_t size, const int *fds, size_t nfds,
|
||||
int flags)
|
||||
{
|
||||
const unsigned char *ptr;
|
||||
nvlist_t *nvl, *retnvl, *tmpnvl;
|
||||
|
@ -782,6 +783,8 @@ nvlist_xunpack(const void *buf, size_t size, const int *fds, size_t nfds)
|
|||
size_t left;
|
||||
bool isbe;
|
||||
|
||||
PJDLOG_ASSERT((flags & ~(NV_FLAG_PUBLIC_MASK)) == 0);
|
||||
|
||||
left = size;
|
||||
ptr = buf;
|
||||
|
||||
|
@ -793,6 +796,10 @@ nvlist_xunpack(const void *buf, size_t size, const int *fds, size_t nfds)
|
|||
ptr = nvlist_unpack_header(nvl, ptr, nfds, &isbe, &left);
|
||||
if (ptr == NULL)
|
||||
goto failed;
|
||||
if (nvl->nvl_flags != flags) {
|
||||
ERRNO_SET(EILSEQ);
|
||||
goto failed;
|
||||
}
|
||||
|
||||
while (left > 0) {
|
||||
ptr = nvpair_unpack(isbe, ptr, &left, &nvp);
|
||||
|
@ -849,10 +856,10 @@ nvlist_xunpack(const void *buf, size_t size, const int *fds, size_t nfds)
|
|||
}
|
||||
|
||||
nvlist_t *
|
||||
nvlist_unpack(const void *buf, size_t size)
|
||||
nvlist_unpack(const void *buf, size_t size, int flags)
|
||||
{
|
||||
|
||||
return (nvlist_xunpack(buf, size, NULL, 0));
|
||||
return (nvlist_xunpack(buf, size, NULL, 0, flags));
|
||||
}
|
||||
|
||||
#ifndef _KERNEL
|
||||
|
@ -900,7 +907,7 @@ nvlist_send(int sock, const nvlist_t *nvl)
|
|||
}
|
||||
|
||||
nvlist_t *
|
||||
nvlist_recv(int sock)
|
||||
nvlist_recv(int sock, int flags)
|
||||
{
|
||||
struct nvlist_header nvlhdr;
|
||||
nvlist_t *nvl, *ret;
|
||||
|
@ -937,7 +944,7 @@ nvlist_recv(int sock)
|
|||
goto out;
|
||||
}
|
||||
|
||||
nvl = nvlist_xunpack(buf, size, fds, nfds);
|
||||
nvl = nvlist_xunpack(buf, size, fds, nfds, flags);
|
||||
if (nvl == NULL) {
|
||||
ERRNO_SAVE();
|
||||
for (i = 0; i < nfds; i++)
|
||||
|
@ -957,7 +964,7 @@ nvlist_recv(int sock)
|
|||
}
|
||||
|
||||
nvlist_t *
|
||||
nvlist_xfer(int sock, nvlist_t *nvl)
|
||||
nvlist_xfer(int sock, nvlist_t *nvl, int flags)
|
||||
{
|
||||
|
||||
if (nvlist_send(sock, nvl) < 0) {
|
||||
|
@ -965,7 +972,7 @@ nvlist_xfer(int sock, nvlist_t *nvl)
|
|||
return (NULL);
|
||||
}
|
||||
nvlist_destroy(nvl);
|
||||
return (nvlist_recv(sock));
|
||||
return (nvlist_recv(sock, flags));
|
||||
}
|
||||
#endif
|
||||
|
||||
|
|
|
@ -87,11 +87,11 @@ void nvlist_fdump(const nvlist_t *nvl, FILE *fp);
|
|||
|
||||
size_t nvlist_size(const nvlist_t *nvl);
|
||||
void *nvlist_pack(const nvlist_t *nvl, size_t *sizep);
|
||||
nvlist_t *nvlist_unpack(const void *buf, size_t size);
|
||||
nvlist_t *nvlist_unpack(const void *buf, size_t size, int flags);
|
||||
|
||||
int nvlist_send(int sock, const nvlist_t *nvl);
|
||||
nvlist_t *nvlist_recv(int sock);
|
||||
nvlist_t *nvlist_xfer(int sock, nvlist_t *nvl);
|
||||
nvlist_t *nvlist_recv(int sock, int flags);
|
||||
nvlist_t *nvlist_xfer(int sock, nvlist_t *nvl, int flags);
|
||||
|
||||
const char *nvlist_next(const nvlist_t *nvl, int *typep, void **cookiep);
|
||||
|
||||
|
|
|
@ -80,7 +80,7 @@ get_schema(int fd)
|
|||
err(1, "Could not fetch config schema");
|
||||
}
|
||||
|
||||
schema = nvlist_unpack(arg.schema, arg.len);
|
||||
schema = nvlist_unpack(arg.schema, arg.len, NV_FLAG_IGNORE_CASE);
|
||||
if (schema == NULL)
|
||||
err(1, "Could not unpack schema");
|
||||
|
||||
|
|
Loading…
Reference in a new issue