1
0
mirror of https://github.com/samba-team/samba.git synced 2025-01-06 13:18:07 +03:00
samba-mirror/source3/winbindd/winbindd_wins_byip.c
Andreas Schneider dfbd950a1d s3:winbind: Fix heap buffer overflow in winbind
==36258==ERROR: AddressSanitizer: heap-buffer-overflow on address 0x51300000b096 at pc 0x7fb6b4880b46 bp 0x7ffc67d44b40 sp 0x7ffc67d44300
READ of size 1 at 0x51300000b096 thread T0
    #0 0x7fb6b4880b45 in strlen ../../../../libsanitizer/sanitizer_common/sanitizer_common_interceptors.inc:391
    #1 0x560fe898cde3 in winbindd_wins_byip_done ../../source3/winbindd/winbindd_wins_byip.c:111
    #2 0x7fb6b4ef8ae5 in _tevent_req_notify_callback ../../lib/tevent/tevent_req.c:177
    #3 0x7fb6b4ef8d1c in tevent_req_finish ../../lib/tevent/tevent_req.c:234
    #4 0x7fb6b4ef8d84 in _tevent_req_done ../../lib/tevent/tevent_req.c:240
    #5 0x7fb6b1e24c80 in node_status_query_done ../../source3/libsmb/namequery.c:904
    #6 0x7fb6b4ef8ae5 in _tevent_req_notify_callback ../../lib/tevent/tevent_req.c:177
    #7 0x7fb6b4ef8d1c in tevent_req_finish ../../lib/tevent/tevent_req.c:234
    #8 0x7fb6b4ef8d84 in _tevent_req_done ../../lib/tevent/tevent_req.c:240
    #9 0x7fb6b1e250bc in nb_trans_done ../../source3/libsmb/namequery.c:756
    #10 0x7fb6b4ef8ae5 in _tevent_req_notify_callback ../../lib/tevent/tevent_req.c:177
    #11 0x7fb6b4ef8d1c in tevent_req_finish ../../lib/tevent/tevent_req.c:234
    #12 0x7fb6b4ef8d84 in _tevent_req_done ../../lib/tevent/tevent_req.c:240
    #13 0x7fb6b1e270af in sock_packet_read_got_socket ../../source3/libsmb/namequery.c:537
    #14 0x7fb6b4ef8ae5 in _tevent_req_notify_callback ../../lib/tevent/tevent_req.c:177
    #15 0x7fb6b4ef8d1c in tevent_req_finish ../../lib/tevent/tevent_req.c:234
    #16 0x7fb6b4ef8d84 in _tevent_req_done ../../lib/tevent/tevent_req.c:240
    #17 0x7fb6b33db183 in tdgram_recvfrom_done ../../lib/tsocket/tsocket.c:240
    #18 0x7fb6b4ef8ae5 in _tevent_req_notify_callback ../../lib/tevent/tevent_req.c:177
    #19 0x7fb6b4ef8d1c in tevent_req_finish ../../lib/tevent/tevent_req.c:234
    #20 0x7fb6b4ef8d84 in _tevent_req_done ../../lib/tevent/tevent_req.c:240
    #21 0x7fb6b33e0d99 in tdgram_bsd_recvfrom_handler ../../lib/tsocket/tsocket_bsd.c:1087
    #22 0x7fb6b33e0263 in tdgram_bsd_fde_handler ../../lib/tsocket/tsocket_bsd.c:811
    #23 0x7fb6b4ef5ac1 in tevent_common_invoke_fd_handler ../../lib/tevent/tevent_fd.c:174
    #24 0x7fb6b4f0b185 in epoll_event_loop ../../lib/tevent/tevent_epoll.c:696
    #25 0x7fb6b4f0b185 in epoll_event_loop_once ../../lib/tevent/tevent_epoll.c:926
    #26 0x7fb6b4f037b8 in std_event_loop_once ../../lib/tevent/tevent_standard.c:110
    #27 0x7fb6b4ef3549 in _tevent_loop_once ../../lib/tevent/tevent.c:820
    #28 0x560fe8a15198 in main ../../source3/winbindd/winbindd.c:1729
    #29 0x7fb6afe2a2ad in __libc_start_call_main ../sysdeps/nptl/libc_start_call_main.h:58
    #30 0x7fb6afe2a378 in __libc_start_main_impl ../csu/libc-start.c:360
    #31 0x560fe89454e4 in _start ../sysdeps/x86_64/start.S:115

0x51300000b096 is located 12 bytes after 330-byte region [0x51300000af40,0x51300000b08a)
allocated by thread T0 here:
    #0 0x7fb6b48fc777 in malloc ../../../../libsanitizer/asan/asan_malloc_linux.cpp:69
    #1 0x7fb6b3a64c57 in __talloc_with_prefix ../../lib/talloc/talloc.c:783
    #2 0x7fb6b3a66acf in __talloc ../../lib/talloc/talloc.c:825
    #3 0x7fb6b3a66acf in _talloc_named_const ../../lib/talloc/talloc.c:982
    #4 0x7fb6b3a66acf in _talloc_array ../../lib/talloc/talloc.c:2784
    #5 0x7fb6b1e2b43e in parse_node_status ../../source3/libsmb/namequery.c:337
    #6 0x7fb6b1e2b43e in node_status_query_recv ../../source3/libsmb/namequery.c:921
    #7 0x560fe898cc4f in winbindd_wins_byip_done ../../source3/winbindd/winbindd_wins_byip.c:87
    #8 0x7fb6b4ef8ae5 in _tevent_req_notify_callback ../../lib/tevent/tevent_req.c:177
    #9 0x7fb6b4ef8d1c in tevent_req_finish ../../lib/tevent/tevent_req.c:234
    #10 0x7fb6b4ef8d84 in _tevent_req_done ../../lib/tevent/tevent_req.c:240
    #11 0x7fb6b1e24c80 in node_status_query_done ../../source3/libsmb/namequery.c:904
    #12 0x7fb6b4ef8ae5 in _tevent_req_notify_callback ../../lib/tevent/tevent_req.c:177
    #13 0x7fb6b4ef8d1c in tevent_req_finish ../../lib/tevent/tevent_req.c:234
    #14 0x7fb6b4ef8d84 in _tevent_req_done ../../lib/tevent/tevent_req.c:240
    #15 0x7fb6b1e250bc in nb_trans_done ../../source3/libsmb/namequery.c:756
    #16 0x7fb6b4ef8ae5 in _tevent_req_notify_callback ../../lib/tevent/tevent_req.c:177
    #17 0x7fb6b4ef8d1c in tevent_req_finish ../../lib/tevent/tevent_req.c:234
    #18 0x7fb6b4ef8d84 in _tevent_req_done ../../lib/tevent/tevent_req.c:240
    #19 0x7fb6b1e270af in sock_packet_read_got_socket ../../source3/libsmb/namequery.c:537
    #20 0x7fb6b4ef8ae5 in _tevent_req_notify_callback ../../lib/tevent/tevent_req.c:177
    #21 0x7fb6b4ef8d1c in tevent_req_finish ../../lib/tevent/tevent_req.c:234
    #22 0x7fb6b4ef8d84 in _tevent_req_done ../../lib/tevent/tevent_req.c:240
    #23 0x7fb6b33db183 in tdgram_recvfrom_done ../../lib/tsocket/tsocket.c:240
    #24 0x7fb6b4ef8ae5 in _tevent_req_notify_callback ../../lib/tevent/tevent_req.c:177
    #25 0x7fb6b4ef8d1c in tevent_req_finish ../../lib/tevent/tevent_req.c:234
    #26 0x7fb6b4ef8d84 in _tevent_req_done ../../lib/tevent/tevent_req.c:240
    #27 0x7fb6b33e0d99 in tdgram_bsd_recvfrom_handler ../../lib/tsocket/tsocket_bsd.c:1087
    #28 0x7fb6b33e0263 in tdgram_bsd_fde_handler ../../lib/tsocket/tsocket_bsd.c:811
    #29 0x7fb6b4ef5ac1 in tevent_common_invoke_fd_handler ../../lib/tevent/tevent_fd.c:174
    #30 0x7fb6b4f0b185 in epoll_event_loop ../../lib/tevent/tevent_epoll.c:696
    #31 0x7fb6b4f0b185 in epoll_event_loop_once ../../lib/tevent/tevent_epoll.c:926
    #32 0x7fb6b4f037b8 in std_event_loop_once ../../lib/tevent/tevent_standard.c:110
    #33 0x7fb6b4ef3549 in _tevent_loop_once ../../lib/tevent/tevent.c:820

Signed-off-by: Andreas Schneider <asn@samba.org>
Reviewed-by: Martin Schwenke <martin@meltin.net>
2024-10-24 10:54:37 +00:00

144 lines
3.8 KiB
C

/*
Unix SMB/CIFS implementation.
async implementation of WINBINDD_WINS_BYIP
Copyright (C) Volker Lendecke 2011
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "includes.h"
#include "winbindd.h"
#include "libsmb/namequery.h"
#include "librpc/gen_ndr/ndr_winbind_c.h"
#include "libsmb/nmblib.h"
#include "lib/util/string_wrappers.h"
struct winbindd_wins_byip_state {
struct nmb_name star;
struct sockaddr_storage addr;
fstring response;
};
static void winbindd_wins_byip_done(struct tevent_req *subreq);
struct tevent_req *winbindd_wins_byip_send(TALLOC_CTX *mem_ctx,
struct tevent_context *ev,
struct winbindd_cli_state *cli,
struct winbindd_request *request)
{
struct tevent_req *req, *subreq;
struct winbindd_wins_byip_state *state;
req = tevent_req_create(mem_ctx, &state,
struct winbindd_wins_byip_state);
if (req == NULL) {
return NULL;
}
/* Ensure null termination */
request->data.winsreq[sizeof(request->data.winsreq)-1]='\0';
fstr_sprintf(state->response, "%s\t", request->data.winsreq);
D_NOTICE("[%s (%u)] Winbind external command WINS_BYIP start.\n"
"Resolving wins byip for %s.\n",
cli->client_name,
(unsigned int)cli->pid,
request->data.winsreq);
make_nmb_name(&state->star, "*", 0);
if (!interpret_string_addr(&state->addr, request->data.winsreq,
AI_NUMERICHOST)) {
tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER);
return tevent_req_post(req, ev);
}
subreq = node_status_query_send(state, ev, &state->star,
&state->addr);
if (tevent_req_nomem(subreq, req)) {
return tevent_req_post(req, ev);
}
tevent_req_set_callback(subreq, winbindd_wins_byip_done, req);
return req;
}
static void winbindd_wins_byip_done(struct tevent_req *subreq)
{
struct tevent_req *req = tevent_req_callback_data(
subreq, struct tevent_req);
struct winbindd_wins_byip_state *state = tevent_req_data(
req, struct winbindd_wins_byip_state);
struct node_status *names;
size_t i;
size_t num_names = 0;
NTSTATUS status;
status = node_status_query_recv(subreq, talloc_tos(), &names,
&num_names, NULL);
TALLOC_FREE(subreq);
if (tevent_req_nterror(req, status)) {
return;
}
for (i=0; i<num_names; i++) {
size_t size;
/*
* ignore group names
*/
if (names[i].flags & 0x80) {
continue;
}
/*
* Only report 0x20
*/
if (names[i].type != 0x20) {
continue;
}
D_DEBUG("Got name '%s'.\n", names[i].name);
/* len(name) + len(" ") + len(response) */
size = strlen(names[i].name) + 1 + strlen(state->response);
if (size > sizeof(state->response) - 1) {
D_WARNING("Too much data!\n");
tevent_req_nterror(req, STATUS_BUFFER_OVERFLOW);
return;
}
fstrcat(state->response, names[i].name);
fstrcat(state->response, " ");
}
state->response[strlen(state->response)-1] = '\n';
TALLOC_FREE(names);
tevent_req_done(req);
}
NTSTATUS winbindd_wins_byip_recv(struct tevent_req *req,
struct winbindd_response *presp)
{
struct winbindd_wins_byip_state *state = tevent_req_data(
req, struct winbindd_wins_byip_state);
NTSTATUS status;
if (tevent_req_is_nterror(req, &status)) {
return status;
}
D_NOTICE("Winbind external command WINS_BYIP end.\n"
"Response: %s",
state->response);
fstrcpy(presp->data.winsresp, state->response);
return NT_STATUS_OK;
}