The branch main has been updated by markj:

URL: 
https://cgit.FreeBSD.org/src/commit/?id=d44c78074d8738db67a2fa6bf07b630c61eee6ab

commit d44c78074d8738db67a2fa6bf07b630c61eee6ab
Author:     Martin Vahlensieck <g...@academicsolutions.ch>
AuthorDate: 2024-04-17 19:01:34 +0000
Commit:     Mark Johnston <ma...@freebsd.org>
CommitDate: 2024-04-24 12:44:50 +0000

    ng_pipe: Do not panic when memory allocations fail
    
    Signed-off-by: Martin Vahlensieck <g...@academicsolutions.ch>
    
    Reviewed by:    markj
    MFC after:      2 weeks
    Pull Request:   https://github.com/freebsd/freebsd-src/pull/1181
---
 sys/netgraph/ng_pipe.c | 45 ++++++++++++++++++++++++++++++---------------
 1 file changed, 30 insertions(+), 15 deletions(-)

diff --git a/sys/netgraph/ng_pipe.c b/sys/netgraph/ng_pipe.c
index d368c142b1ab..42a5991e8dc7 100644
--- a/sys/netgraph/ng_pipe.c
+++ b/sys/netgraph/ng_pipe.c
@@ -641,12 +641,14 @@ ngp_rcvdata(hook_p hook, item_p item)
        }
 
        /* Populate the packet header */
-       ngp_h = uma_zalloc(ngp_zone, M_NOWAIT);
-       KASSERT((ngp_h != NULL), ("ngp_h zalloc failed (1)"));
        NGI_GET_M(item, m);
-       KASSERT(m != NULL, ("NGI_GET_M failed"));
-       ngp_h->m = m;
        NG_FREE_ITEM(item);
+       ngp_h = uma_zalloc(ngp_zone, M_NOWAIT);
+       if (ngp_h == NULL) {
+               NG_FREE_M(m);
+               return (ENOMEM);
+       }
+       ngp_h->m = m;
 
        if (hinfo->cfg.fifo)
                hash = 0;       /* all packets go into a single FIFO queue */
@@ -659,7 +661,11 @@ ngp_rcvdata(hook_p hook, item_p item)
                        break;
        if (ngp_f == NULL) {
                ngp_f = uma_zalloc(ngp_zone, M_NOWAIT);
-               KASSERT(ngp_h != NULL, ("ngp_h zalloc failed (2)"));
+               if (ngp_f == NULL) {
+                       NG_FREE_M(ngp_h->m);
+                       uma_zfree(ngp_zone, ngp_h);
+                       return (ENOMEM);
+               }
                TAILQ_INIT(&ngp_f->packet_head);
                ngp_f->hash = hash;
                ngp_f->packets = 1;
@@ -733,7 +739,7 @@ pipe_dequeue(struct hookinfo *hinfo, struct timeval *now) {
        const priv_p priv = NG_NODE_PRIVATE(node);
        struct hookinfo *dest;
        struct ngp_fifo *ngp_f, *ngp_f1;
-       struct ngp_hdr *ngp_h;
+       struct ngp_hdr *ngp_h, *ngp_dup;
        struct timeval *when;
        struct mbuf *m;
        int plen, error = 0;
@@ -768,16 +774,27 @@ pipe_dequeue(struct hookinfo *hinfo, struct timeval *now) 
{
                }
 
                /*
-                * Either create a duplicate and pass it on, or dequeue
-                * the original packet...
+                * Either create a duplicate and pass it on, or
+                * dequeue the original packet.  When any of the
+                * memory allocations for the duplicate package fail,
+                * simply do not duplicate it at all.
                 */
+               ngp_dup = NULL;
                if (hinfo->cfg.duplicate &&
                    prng32_bounded(100) <= hinfo->cfg.duplicate) {
-                       ngp_h = uma_zalloc(ngp_zone, M_NOWAIT);
-                       KASSERT(ngp_h != NULL, ("ngp_h zalloc failed (3)"));
-                       m = m_dup(m, M_NOWAIT);
-                       KASSERT(m != NULL, ("m_dup failed"));
-                       ngp_h->m = m;
+                       ngp_dup = uma_zalloc(ngp_zone, M_NOWAIT);
+                       if (ngp_dup != NULL) {
+                               ngp_dup->m = m_dup(m, M_NOWAIT);
+                               if (ngp_dup->m == NULL) {
+                                       uma_zfree(ngp_zone, ngp_dup);
+                                       ngp_dup = NULL;
+                               }
+                       }
+               }
+
+               if (ngp_dup != NULL) {
+                       ngp_h = ngp_dup;
+                       m = ngp_h->m;
                } else {
                        TAILQ_REMOVE(&ngp_f->packet_head, ngp_h, ngp_link);
                        hinfo->run.qin_frames--;
@@ -983,8 +1000,6 @@ ngp_modevent(module_t mod, int type, void *unused)
                ngp_zone = uma_zcreate("ng_pipe", max(sizeof(struct ngp_hdr),
                    sizeof (struct ngp_fifo)), NULL, NULL, NULL, NULL,
                    UMA_ALIGN_PTR, 0);
-               if (ngp_zone == NULL)
-                       panic("ng_pipe: couldn't allocate descriptor zone");
                break;
        case MOD_UNLOAD:
                uma_zdestroy(ngp_zone);

Reply via email to