From d6249e1891ddd47b52231811da145d5d74d09865 Mon Sep 17 00:00:00 2001 From: Lukas Slebodnik Date: Thu, 16 Jun 2016 17:40:50 +0200 Subject: [PATCH] Downcast to errno_t after tevent_req_is_error Functions tevent_req_is_error and _tevent_req_error use type uint64_t for error code. SSSD uses errno_t which is an alias for int. Therefore complier assumes that macro TEVENT_REQ_RETURN_ON_ERROR can return 0 due to implicit down casting from uint64_t -> int. This patch makes down casting explicit and returns EINVAL if result of downcasting is 0. --- src/providers/ldap/sdap_async_connection.c | 20 +++++++++++++++----- src/responder/common/responder_dp.c | 10 ++++++++-- src/util/util.h | 9 +++++++-- 3 files changed, 30 insertions(+), 9 deletions(-) diff --git a/src/providers/ldap/sdap_async_connection.c b/src/providers/ldap/sdap_async_connection.c index 5045a1d19b1112fdfed1167367a5a298f1601005..a8d4262b52c4b2d2810450d68794f00558ea5c2d 100644 --- a/src/providers/ldap/sdap_async_connection.c +++ b/src/providers/ldap/sdap_async_connection.c @@ -1254,10 +1254,15 @@ static errno_t sdap_kinit_recv(struct tevent_req *req, struct sdap_kinit_state *state = tevent_req_data(req, struct sdap_kinit_state); enum tevent_req_state tstate; - uint64_t err = ERR_INTERNAL; + uint64_t err_uint64 = ERR_INTERNAL; + errno_t err; - if (tevent_req_is_error(req, &tstate, &err)) { + if (tevent_req_is_error(req, &tstate, &err_uint64)) { if (tstate != TEVENT_REQ_IN_PROGRESS) { + err = (errno_t)err_uint64; + if (err == EOK) { + return ERR_INTERNAL; + } return err; } } @@ -2027,16 +2032,17 @@ int sdap_cli_connect_recv(struct tevent_req *req, struct sdap_cli_connect_state *state = tevent_req_data(req, struct sdap_cli_connect_state); enum tevent_req_state tstate; - uint64_t err; + uint64_t err_uint64; + int err; if (can_retry) { *can_retry = true; } - if (tevent_req_is_error(req, &tstate, &err)) { + if (tevent_req_is_error(req, &tstate, &err_uint64)) { /* mark the server as bad if connection failed */ if (state->srv) { DEBUG(SSSDBG_OP_FAILURE, "Unable to establish connection " - "[%"PRIu64"]: %s\n", err, sss_strerror(err)); + "[%"PRIu64"]: %s\n", err_uint64, sss_strerror(err_uint64)); be_fo_set_port_status(state->be, state->service->name, state->srv, PORT_NOT_WORKING); @@ -2047,6 +2053,10 @@ int sdap_cli_connect_recv(struct tevent_req *req, } if (tstate == TEVENT_REQ_USER_ERROR) { + err = (int)err_uint64; + if (err == EOK) { + return EINVAL; + } return err; } return EIO; diff --git a/src/responder/common/responder_dp.c b/src/responder/common/responder_dp.c index f53c7d23206dffe4b78d5ec88ab1506e3ce8baf3..fed47a0682c32e5fbc0d0687359799d5a4fc7443 100644 --- a/src/responder/common/responder_dp.c +++ b/src/responder/common/responder_dp.c @@ -397,14 +397,20 @@ sss_dp_req_recv(TALLOC_CTX *mem_ctx, tevent_req_data(sidereq, struct sss_dp_req_state); enum tevent_req_state TRROEstate; - uint64_t TRROEerr; + uint64_t TRROEuint64; + errno_t TRROEerr; *dp_err = state->dp_err; *dp_ret = state->dp_ret; *err_msg = talloc_steal(mem_ctx, state->err_msg); - if (tevent_req_is_error(sidereq, &TRROEstate, &TRROEerr)) { + if (tevent_req_is_error(sidereq, &TRROEstate, &TRROEuint64)) { + TRROEerr = (errno_t)TRROEuint64; + if (TRROEstate == TEVENT_REQ_USER_ERROR) { + if (TRROEerr == 0) { + return ERR_INTERNAL; + } *dp_err = DP_ERR_FATAL; *dp_ret = TRROEerr; } else { diff --git a/src/util/util.h b/src/util/util.h index d36bb6086fa90dd5dcf10b5c31bc3f6fc1ad771c..a8b4776be6756e10018db57c5cf03755cfb7f57e 100644 --- a/src/util/util.h +++ b/src/util/util.h @@ -112,10 +112,15 @@ #define TEVENT_REQ_RETURN_ON_ERROR(req) do { \ enum tevent_req_state TRROEstate; \ - uint64_t TRROEerr; \ + uint64_t TRROEuint64; \ + errno_t TRROEerr; \ \ - if (tevent_req_is_error(req, &TRROEstate, &TRROEerr)) { \ + if (tevent_req_is_error(req, &TRROEstate, &TRROEuint64)) { \ + TRROEerr = (errno_t)TRROEuint64; \ if (TRROEstate == TEVENT_REQ_USER_ERROR) { \ + if (TRROEerr == 0) { \ + return ERR_INTERNAL; \ + } \ return TRROEerr; \ } \ return ERR_INTERNAL; \ -- 2.7.4