]> git.ipfire.org Git - thirdparty/samba.git/commitdiff
ctdb-ib: Replace uses of sprintf()
authorMartin Schwenke <mschwenke@ddn.com>
Thu, 18 Sep 2025 05:24:32 +0000 (15:24 +1000)
committerVolker Lendecke <vl@samba.org>
Thu, 25 Sep 2025 07:57:42 +0000 (07:57 +0000)
An unbounded sprintf() into ibw_lasterr (a 512-byte static data
buffer) can potentially cause overflow into other BSS data.

However, the risk is effectively minimised to zero due to:

* This code not being executed at all in ctdbd.  It is only executed
  in the accompanying test code:

  - The function ibw_process_init_attrs() can cause a buffer overflow
    if its 2nd argument, nattr, is non-zero and one of the structs in
    the array pointed to by its 1st argument, attr, contains a name
    member that is too long.

  - ibw_process_init_attrs() is only called by ibw_init(), which also
    has attr and nattr as its 1st and 2nd args, and it just passes them
    straight through.

  - ibw_init() is called in 2 places:

    1. In ibwrapper_test.c, which is targeted test code.

    2. In ibw_ctdb_init.c:ctdb_ibw_init(), which is the initialisation
       function use to initialise the IB transport in ctdbd.  Here, NULL
       and 0 are passed as the relevant arguments to ibw_init().  Both
       arguments are flagged with TODO comments.  :-)

* This code is not built by default (--enable-infiniband is
  required).

  It appears that Debian and Red Hat family Linux distributions have
  never distributed binaries with this enabled.

* Documentation (ctdb(7) and the wiki) recommends that private
  addresses are configured on a private network that is separate from
  client networks.  So, even if the TODOs were done and the relevant
  arguments could come off the wire, the attack surface should be very
  small.

Only the instance with %s in the format is potentially problematic.
The others can not overflow the current 512 byte buffer.  However, it
makes sense to change them all in case someone foolishly reduces the
size of the buffer and makes other changes so that the buffer can be
overflowed in ctdbd.

Now, will static analysers complain that the result of snprintf() is
not checked even though snprintf() always NUL-terminates?

Signed-off-by: Martin Schwenke <mschwenke@ddn.com>
Reported-by: Marcos “Tr0p” Tolosa <marcos.tolosa@owasp.org>
Reviewed-by: Volker Lendecke <vl@samba.org>
ctdb/ib/ibwrapper.c

index cf4efa579e2ee93bbc0a28e5e45e04c411a288fc..24fb301824af1b7f9d1c1ae58657fea973d65ca4 100644 (file)
@@ -61,13 +61,17 @@ static void *ibw_alloc_mr(struct ibw_ctx_priv *pctx, struct ibw_conn_priv *pconn
        DEBUG(DEBUG_DEBUG, ("ibw_alloc_mr(cmid=%p, n=%u)\n", pconn->cm_id, n));
        buf = memalign(pctx->pagesize, n);
        if (!buf) {
-               sprintf(ibw_lasterr, "couldn't allocate memory\n");
+               snprintf(ibw_lasterr,
+                        sizeof(ibw_lasterr),
+                        "couldn't allocate memory\n");
                return NULL;
        }
 
        *ppmr = ibv_reg_mr(pconn->pd, buf, n, IBV_ACCESS_LOCAL_WRITE);
        if (!*ppmr) {
-               sprintf(ibw_lasterr, "couldn't allocate mr\n");
+               snprintf(ibw_lasterr,
+                        sizeof(ibw_lasterr),
+                        "couldn't allocate mr\n");
                free(buf);
                return NULL;
        }
@@ -100,14 +104,18 @@ static int ibw_init_memory(struct ibw_conn *conn)
        pconn->buf_send = ibw_alloc_mr(pctx, pconn,
                opts->max_send_wr * opts->recv_bufsize, &pconn->mr_send);
        if (!pconn->buf_send) {
-               sprintf(ibw_lasterr, "couldn't allocate work send buf\n");
+               snprintf(ibw_lasterr,
+                        sizeof(ibw_lasterr),
+                        "couldn't allocate work send buf\n");
                return -1;
        }
 
        pconn->buf_recv = ibw_alloc_mr(pctx, pconn,
                opts->max_recv_wr * opts->recv_bufsize, &pconn->mr_recv);
        if (!pconn->buf_recv) {
-               sprintf(ibw_lasterr, "couldn't allocate work recv buf\n");
+               snprintf(ibw_lasterr,
+                        sizeof(ibw_lasterr),
+                        "couldn't allocate work recv buf\n");
                return -1;
        }
 
@@ -253,7 +261,10 @@ static int ibw_setup_cq_qp(struct ibw_conn *conn)
        /* init verbs */
        pconn->verbs_channel = ibv_create_comp_channel(pconn->cm_id->verbs);
        if (!pconn->verbs_channel) {
-               sprintf(ibw_lasterr, "ibv_create_comp_channel failed %d\n", errno);
+               snprintf(ibw_lasterr,
+                        sizeof(ibw_lasterr),
+                        "ibv_create_comp_channel failed %d\n",
+                        errno);
                return -1;
        }
        DEBUG(DEBUG_DEBUG, ("created channel %p\n", pconn->verbs_channel));
@@ -263,7 +274,10 @@ static int ibw_setup_cq_qp(struct ibw_conn *conn)
 
        pconn->pd = ibv_alloc_pd(pconn->cm_id->verbs);
        if (!pconn->pd) {
-               sprintf(ibw_lasterr, "ibv_alloc_pd failed %d\n", errno);
+               snprintf(ibw_lasterr,
+                        sizeof(ibw_lasterr),
+                        "ibv_alloc_pd failed %d\n",
+                        errno);
                return -1;
        }
        DEBUG(DEBUG_DEBUG, ("created pd %p\n", pconn->pd));
@@ -277,13 +291,18 @@ static int ibw_setup_cq_qp(struct ibw_conn *conn)
                pctx->opts.max_recv_wr + pctx->opts.max_send_wr,
                conn, pconn->verbs_channel, 0);
        if (pconn->cq==NULL) {
-               sprintf(ibw_lasterr, "ibv_create_cq failed\n");
+               snprintf(ibw_lasterr,
+                        sizeof(ibw_lasterr),
+                        "ibv_create_cq failed\n");
                return -1;
        }
 
        rc = ibv_req_notify_cq(pconn->cq, 0);
        if (rc) {
-               sprintf(ibw_lasterr, "ibv_req_notify_cq failed with %d\n", rc);
+               snprintf(ibw_lasterr,
+                        sizeof(ibw_lasterr),
+                        "ibv_req_notify_cq failed with %d\n",
+                        rc);
                return rc;
        }
 
@@ -299,14 +318,20 @@ static int ibw_setup_cq_qp(struct ibw_conn *conn)
 
        rc = rdma_create_qp(pconn->cm_id, pconn->pd, &init_attr);
        if (rc) {
-               sprintf(ibw_lasterr, "rdma_create_qp failed with %d\n", rc);
+               snprintf(ibw_lasterr,
+                        sizeof(ibw_lasterr),
+                        "rdma_create_qp failed with %d\n",
+                        rc);
                return rc;
        }
        /* elase result is in pconn->cm_id->qp */
 
        rc = ibv_query_qp(pconn->cm_id->qp, &attr, IBV_QP_PATH_MTU, &init_attr);
        if (rc) {
-               sprintf(ibw_lasterr, "ibv_query_qp failed with %d\n", rc);
+               snprintf(ibw_lasterr,
+                        sizeof(ibw_lasterr),
+                        "ibv_query_qp failed with %d\n",
+                        rc);
                return rc;
        }
 
@@ -338,7 +363,10 @@ static int ibw_refill_cq_recv(struct ibw_conn *conn)
 
        rc = ibv_post_recv(pconn->cm_id->qp, &wr, &bad_wr);
        if (rc) {
-               sprintf(ibw_lasterr, "refill/ibv_post_recv failed with %d\n", rc);
+               snprintf(ibw_lasterr,
+                        sizeof(ibw_lasterr),
+                        "refill/ibv_post_recv failed with %d\n",
+                        rc);
                DEBUG(DEBUG_ERR, ("%s", ibw_lasterr));
                return -2;
        }
@@ -372,7 +400,10 @@ static int ibw_fill_cq(struct ibw_conn *conn)
 
                rc = ibv_post_recv(pconn->cm_id->qp, &wr, &bad_wr);
                if (rc) {
-                       sprintf(ibw_lasterr, "fill/ibv_post_recv failed with %d\n", rc);
+                       snprintf(ibw_lasterr,
+                                sizeof(ibw_lasterr),
+                                "fill/ibv_post_recv failed with %d\n",
+                                rc);
                        DEBUG(DEBUG_ERR, ("%s", ibw_lasterr));
                        return -2;
                }
@@ -400,7 +431,10 @@ static int ibw_manage_connect(struct ibw_conn *conn)
 
        rc = rdma_connect(pconn->cm_id, &conn_param);
        if (rc)
-               sprintf(ibw_lasterr, "rdma_connect error %d\n", rc);
+               snprintf(ibw_lasterr,
+                        sizeof(ibw_lasterr),
+                        "rdma_connect error %d\n",
+                        rc);
 
        return rc;
 }
@@ -422,7 +456,10 @@ static void ibw_event_handler_cm(struct tevent_context *ev,
        if (rc) {
                ctx->state = IBWS_ERROR;
                event = NULL;
-               sprintf(ibw_lasterr, "rdma_get_cm_event error %d\n", rc);
+               snprintf(ibw_lasterr,
+                        sizeof(ibw_lasterr),
+                        "rdma_get_cm_event error %d\n",
+                        rc);
                goto error;
        }
        cma_id = event->id;
@@ -436,7 +473,10 @@ static void ibw_event_handler_cm(struct tevent_context *ev,
                /* continuing from ibw_connect ... */
                rc = rdma_resolve_route(cma_id, 2000);
                if (rc) {
-                       sprintf(ibw_lasterr, "rdma_resolve_route error %d\n", rc);
+                       snprintf(ibw_lasterr,
+                                sizeof(ibw_lasterr),
+                                "rdma_resolve_route error %d\n",
+                                rc);
                        goto error;
                }
                /* continued at RDMA_CM_EVENT_ROUTE_RESOLVED */
@@ -501,19 +541,34 @@ static void ibw_event_handler_cm(struct tevent_context *ev,
                break;
 
        case RDMA_CM_EVENT_ADDR_ERROR:
-               sprintf(ibw_lasterr, "RDMA_CM_EVENT_ADDR_ERROR, error %d\n", event->status);
+               snprintf(ibw_lasterr,
+                        sizeof(ibw_lasterr),
+                        "RDMA_CM_EVENT_ADDR_ERROR, error %d\n",
+                        event->status);
                goto error;
        case RDMA_CM_EVENT_ROUTE_ERROR:
-               sprintf(ibw_lasterr, "RDMA_CM_EVENT_ROUTE_ERROR, error %d\n", event->status);
+               snprintf(ibw_lasterr,
+                        sizeof(ibw_lasterr),
+                        "RDMA_CM_EVENT_ROUTE_ERROR, error %d\n",
+                        event->status);
                goto error;
        case RDMA_CM_EVENT_CONNECT_ERROR:
-               sprintf(ibw_lasterr, "RDMA_CM_EVENT_CONNECT_ERROR, error %d\n", event->status);
+               snprintf(ibw_lasterr,
+                        sizeof(ibw_lasterr),
+                        "RDMA_CM_EVENT_CONNECT_ERROR, error %d\n",
+                        event->status);
                goto error;
        case RDMA_CM_EVENT_UNREACHABLE:
-               sprintf(ibw_lasterr, "RDMA_CM_EVENT_UNREACHABLE, error %d\n", event->status);
+               snprintf(ibw_lasterr,
+                        sizeof(ibw_lasterr),
+                        "RDMA_CM_EVENT_UNREACHABLE, error %d\n",
+                        event->status);
                goto error;
        case RDMA_CM_EVENT_REJECTED:
-               sprintf(ibw_lasterr, "RDMA_CM_EVENT_REJECTED, error %d\n", event->status);
+               snprintf(ibw_lasterr,
+                        sizeof(ibw_lasterr),
+                        "RDMA_CM_EVENT_REJECTED, error %d\n",
+                        event->status);
                DEBUG(DEBUG_INFO, ("cm event handler: %s", ibw_lasterr));
                conn = talloc_get_type(cma_id->context, struct ibw_conn);
                if (conn) {
@@ -542,16 +597,24 @@ static void ibw_event_handler_cm(struct tevent_context *ev,
                break;
 
        case RDMA_CM_EVENT_DEVICE_REMOVAL:
-               sprintf(ibw_lasterr, "cma detected device removal!\n");
+               snprintf(ibw_lasterr,
+                        sizeof(ibw_lasterr),
+                        "cma detected device removal!\n");
                goto error;
 
        default:
-               sprintf(ibw_lasterr, "unknown event %d\n", event->event);
+               snprintf(ibw_lasterr,
+                        sizeof(ibw_lasterr),
+                        "unknown event %d\n",
+                        event->event);
                goto error;
        }
 
        if (event!=NULL && (rc=rdma_ack_cm_event(event))) {
-               sprintf(ibw_lasterr, "rdma_ack_cm_event failed with %d\n", rc);
+               snprintf(ibw_lasterr,
+                        sizeof(ibw_lasterr),
+                        "rdma_ack_cm_event failed with %d\n",
+                        rc);
                goto error;
        }
 
@@ -596,23 +659,36 @@ static void ibw_event_handler_verbs(struct tevent_context *ev,
        /* TODO: check whether if it's good to have more channels here... */
        rc = ibv_get_cq_event(pconn->verbs_channel, &ev_cq, &ev_ctx);
        if (rc) {
-               sprintf(ibw_lasterr, "Failed to get cq_event with %d\n", rc);
+               snprintf(ibw_lasterr,
+                        sizeof(ibw_lasterr),
+                        "Failed to get cq_event with %d\n",
+                        rc);
                goto error;
        }
        if (ev_cq != pconn->cq) {
-               sprintf(ibw_lasterr, "ev_cq(%p) != pconn->cq(%p)\n", ev_cq, pconn->cq);
+               snprintf(ibw_lasterr,
+                        sizeof(ibw_lasterr),
+                        "ev_cq(%p) != pconn->cq(%p)\n",
+                        ev_cq,
+                        pconn->cq);
                goto error;
        }
        rc = ibv_req_notify_cq(pconn->cq, 0);
        if (rc) {
-               sprintf(ibw_lasterr, "Couldn't request CQ notification (%d)\n", rc);
+               snprintf(ibw_lasterr,
+                        sizeof(ibw_lasterr),
+                        "Couldn't request CQ notification (%d)\n",
+                        rc);
                goto error;
        }
 
        while((rc=ibv_poll_cq(pconn->cq, 1, &wc))==1) {
                if (wc.status) {
-                       sprintf(ibw_lasterr, "cq completion failed status=%d, opcode=%d, rc=%d\n",
-                               wc.status, wc.opcode, rc);
+                       snprintf(ibw_lasterr,
+                                sizeof(ibw_lasterr),
+                                "cq completion failed status=%d, opcode=%d, rc=%d\n",
+                                wc.status, wc.opcode,
+                                rc);
                        goto error;
                }
 
@@ -638,12 +714,18 @@ static void ibw_event_handler_verbs(struct tevent_context *ev,
                        break;
 
                default:
-                       sprintf(ibw_lasterr, "unknown completion %d\n", wc.opcode);
+                       snprintf(ibw_lasterr,
+                                sizeof(ibw_lasterr),
+                                "unknown completion %d\n",
+                                wc.opcode);
                        goto error;
                }
        }
        if (rc!=0) {
-               sprintf(ibw_lasterr, "ibv_poll_cq error %d\n", rc);
+               snprintf(ibw_lasterr,
+                        sizeof(ibw_lasterr),
+                        "ibv_poll_cq error %d\n",
+                        rc);
                goto error;
        }
 
@@ -737,8 +819,11 @@ static int ibw_wc_send(struct ibw_conn *conn, struct ibv_wc *wc)
                        if ((p->wr_id + pctx->opts.max_recv_wr)==(int)wc->wr_id)
                                break;
                if (p==NULL) {
-                       sprintf(ibw_lasterr, "failed to find wr_id %d\n", (int)wc->wr_id);
-                               return -1;
+                       snprintf(ibw_lasterr,
+                                sizeof(ibw_lasterr),
+                                "failed to find wr_id %d\n",
+                                (int)wc->wr_id);
+                       return -1;
                }
                if (p->ref_cnt) {
                        p->ref_cnt--;
@@ -764,8 +849,11 @@ static int ibw_append_to_part(struct ibw_conn_priv *pconn,
                        assert(part->len==0);
                        part->buf = talloc_size(pconn, add_len);
                        if (part->buf==NULL) {
-                               sprintf(ibw_lasterr, "recv talloc_size error (%u) #%d\n",
-                                       add_len, info);
+                               snprintf(ibw_lasterr,
+                                        sizeof(ibw_lasterr),
+                                        "recv talloc_size error (%u) #%d\n",
+                                        add_len,
+                                        info);
                                return -1;
                        }
                        part->bufsize = add_len;
@@ -773,8 +861,12 @@ static int ibw_append_to_part(struct ibw_conn_priv *pconn,
                        part->buf = talloc_realloc_size(pconn,
                                part->buf, part->len + add_len);
                        if (part->buf==NULL) {
-                               sprintf(ibw_lasterr, "recv realloc error (%u + %u) #%d\n",
-                                       part->len, add_len, info);
+                               snprintf(ibw_lasterr,
+                                        sizeof(ibw_lasterr),
+                                        "recv realloc error (%u + %u) #%d\n",
+                                        part->len,
+                                        add_len,
+                                        info);
                                return -1;
                        }
                }
@@ -802,7 +894,9 @@ static int ibw_wc_mem_threshold(struct ibw_conn_priv *pconn,
                talloc_free(part->buf);
                part->buf = talloc_size(pconn, threshold);
                if (part->buf==NULL) {
-                       sprintf(ibw_lasterr, "talloc_size failed\n");
+                       snprintf(ibw_lasterr,
+                                sizeof(ibw_lasterr),
+                                "talloc_size failed\n");
                        return -1;
                }
                part->bufsize = threshold;
@@ -841,7 +935,10 @@ static int ibw_wc_recv(struct ibw_conn *conn, struct ibv_wc *wc)
                                /* set it again now... */
                                part->to_read = *((uint32_t *)(part->buf)); /* TODO: ntohl */
                                if (part->to_read<sizeof(uint32_t)) {
-                                       sprintf(ibw_lasterr, "got msglen=%u #2\n", part->to_read);
+                                       snprintf(ibw_lasterr,
+                                                sizeof(ibw_lasterr),
+                                                "got msglen=%u #2\n",
+                                                part->to_read);
                                        goto error;
                                }
                                part->to_read -= sizeof(uint32_t); /* it's already read */
@@ -859,7 +956,10 @@ static int ibw_wc_recv(struct ibw_conn *conn, struct ibv_wc *wc)
                        if (remain>=sizeof(uint32_t)) {
                                uint32_t msglen = *(uint32_t *)p; /* TODO: ntohl */
                                if (msglen<sizeof(uint32_t)) {
-                                       sprintf(ibw_lasterr, "got msglen=%u\n", msglen);
+                                       snprintf(ibw_lasterr,
+                                                sizeof(ibw_lasterr),
+                                                "got msglen=%u\n",
+                                                msglen);
                                        goto error;
                                }
 
@@ -925,7 +1025,10 @@ static int ibw_process_init_attrs(struct ibw_initattr *attr, int nattr, struct i
                else if (strcmp(name, "recv_threshold")==0)
                        opts->recv_threshold = atoi(value);
                else {
-                       sprintf(ibw_lasterr, "ibw_init: unknown name %s\n", name);
+                       snprintf(ibw_lasterr,
+                                sizeof(ibw_lasterr),
+                                "ibw_init: unknown name %s\n",
+                                name);
                        return -1;
                }
        }
@@ -969,7 +1072,10 @@ struct ibw_ctx *ibw_init(struct ibw_initattr *attr, int nattr,
        /* init cm */
        pctx->cm_channel = rdma_create_event_channel();
        if (!pctx->cm_channel) {
-               sprintf(ibw_lasterr, "rdma_create_event_channel error %d\n", errno);
+               snprintf(ibw_lasterr,
+                        sizeof(ibw_lasterr),
+                        "rdma_create_event_channel error %d\n",
+                        errno);
                goto cleanup;
        }
 
@@ -983,7 +1089,10 @@ struct ibw_ctx *ibw_init(struct ibw_initattr *attr, int nattr,
 #endif
        if (rc) {
                rc = errno;
-               sprintf(ibw_lasterr, "rdma_create_id error %d\n", rc);
+               snprintf(ibw_lasterr,
+                        sizeof(ibw_lasterr),
+                        "rdma_create_id error %d\n",
+                        rc);
                goto cleanup;
        }
        DEBUG(DEBUG_DEBUG, ("created cm_id %p\n", pctx->cm_id));
@@ -1030,7 +1139,10 @@ int ibw_bind(struct ibw_ctx *ctx, struct sockaddr_in *my_addr)
                inet_ntoa(my_addr->sin_addr), ntohs(my_addr->sin_port)));
        rc = rdma_bind_addr(pctx->cm_id, (struct sockaddr *) my_addr);
        if (rc) {
-               sprintf(ibw_lasterr, "rdma_bind_addr error %d\n", rc);
+               snprintf(ibw_lasterr,
+                        sizeof(ibw_lasterr),
+                        "rdma_bind_addr error %d\n",
+                        rc);
                DEBUG(DEBUG_ERR, ("%s", ibw_lasterr));
                return rc;
        }
@@ -1047,7 +1159,10 @@ int ibw_listen(struct ibw_ctx *ctx, int backlog)
        DEBUG(DEBUG_DEBUG, ("ibw_listen\n"));
        rc = rdma_listen(pctx->cm_id, backlog);
        if (rc) {
-               sprintf(ibw_lasterr, "rdma_listen failed: %d\n", rc);
+               snprintf(ibw_lasterr,
+                        sizeof(ibw_lasterr),
+                        "rdma_listen failed: %d\n",
+                        rc);
                DEBUG(DEBUG_ERR, ("%s", ibw_lasterr));
                return rc;
        }
@@ -1069,7 +1184,10 @@ int ibw_accept(struct ibw_ctx *ctx, struct ibw_conn *conn, void *conn_userdata)
        conn_param.initiator_depth = 1;
        rc = rdma_accept(pconn->cm_id, &conn_param);
        if (rc) {
-               sprintf(ibw_lasterr, "rdma_accept failed %d\n", rc);
+               snprintf(ibw_lasterr,
+                        sizeof(ibw_lasterr),
+                        "rdma_accept failed %d\n",
+                        rc);
                DEBUG(DEBUG_ERR, ("%s", ibw_lasterr));
                return -1;;
        }
@@ -1108,7 +1226,10 @@ int ibw_connect(struct ibw_conn *conn, struct sockaddr_in *serv_addr, void *conn
 #endif
        if (rc) {
                rc = errno;
-               sprintf(ibw_lasterr, "ibw_connect/rdma_create_id error %d\n", rc);
+               snprintf(ibw_lasterr,
+                        sizeof(ibw_lasterr),
+                        "ibw_connect/rdma_create_id error %d\n",
+                        rc);
                talloc_free(conn);
                return -1;
        }
@@ -1116,7 +1237,10 @@ int ibw_connect(struct ibw_conn *conn, struct sockaddr_in *serv_addr, void *conn
 
        rc = rdma_resolve_addr(pconn->cm_id, NULL, (struct sockaddr *) serv_addr, 2000);
        if (rc) {
-               sprintf(ibw_lasterr, "rdma_resolve_addr error %d\n", rc);
+               snprintf(ibw_lasterr,
+                        sizeof(ibw_lasterr),
+                        "rdma_resolve_addr error %d\n",
+                        rc);
                DEBUG(DEBUG_ERR, ("%s", ibw_lasterr));
                talloc_free(conn);
                return -1;
@@ -1143,7 +1267,10 @@ int ibw_disconnect(struct ibw_conn *conn)
        case IBWC_CONNECTED:
                rc = rdma_disconnect(pconn->cm_id);
                if (rc) {
-                       sprintf(ibw_lasterr, "ibw_disconnect failed with %d\n", rc);
+                       snprintf(ibw_lasterr,
+                                sizeof(ibw_lasterr),
+                                "ibw_disconnect failed with %d\n",
+                                rc);
                        DEBUG(DEBUG_ERR, ("%s", ibw_lasterr));
                        return rc;
                }
@@ -1173,7 +1300,9 @@ int ibw_alloc_send_buf(struct ibw_conn *conn, void **buf, void **key, uint32_t l
                } else {
                        p->buf_large = ibw_alloc_mr(pctx, pconn, len, &p->mr_large);
                        if (p->buf_large==NULL) {
-                               sprintf(ibw_lasterr, "ibw_alloc_mr#1 failed\n");
+                               snprintf(ibw_lasterr,
+                                        sizeof(ibw_lasterr),
+                                        "ibw_alloc_mr#1 failed\n");
                                goto error;
                        }
                        *buf = (void *)p->buf_large;
@@ -1187,7 +1316,10 @@ int ibw_alloc_send_buf(struct ibw_conn *conn, void **buf, void **key, uint32_t l
                        p = pconn->extra_avail = talloc_zero(pconn, struct ibw_wr);
                        talloc_set_destructor(p, ibw_wr_destruct);
                        if (p==NULL) {
-                               sprintf(ibw_lasterr, "talloc_zero failed (emax: %u)\n", pconn->extra_max);
+                               snprintf(ibw_lasterr,
+                                        sizeof(ibw_lasterr),
+                                        "talloc_zero failed (emax: %u)\n",
+                                        pconn->extra_max);
                                goto error;
                        }
                        p->wr_id = pctx->opts.max_send_wr + pconn->extra_max;
@@ -1203,7 +1335,9 @@ int ibw_alloc_send_buf(struct ibw_conn *conn, void **buf, void **key, uint32_t l
 
                p->buf_large = ibw_alloc_mr(pctx, pconn, len, &p->mr_large);
                if (p->buf_large==NULL) {
-                       sprintf(ibw_lasterr, "ibw_alloc_mr#2 failed\n");
+                       snprintf(ibw_lasterr,
+                                sizeof(ibw_lasterr),
+                                "ibw_alloc_mr#2 failed\n");
                        goto error;
                }
                *buf = (void *)p->buf_large;
@@ -1256,8 +1390,11 @@ static int ibw_send_packet(struct ibw_conn *conn, void *buf, struct ibw_wr *p, u
 
                rc = ibv_post_send(pconn->cm_id->qp, &wr, &bad_wr);
                if (rc) {
-                       sprintf(ibw_lasterr, "ibv_post_send error %d (%d)\n",
-                               rc, pconn->wr_sent);
+                       snprintf(ibw_lasterr,
+                                sizeof(ibw_lasterr),
+                                "ibv_post_send error %d (%d)\n",
+                                rc,
+                                pconn->wr_sent);
                        goto error;
                }