~ubuntu-branches/ubuntu/vivid/net-snmp/vivid-updates

« back to all changes in this revision

Viewing changes to agent/snmp_agent.c

  • Committer: Package Import Robot
  • Author(s): Marc Deslauriers
  • Date: 2014-04-08 08:17:14 UTC
  • Revision ID: package-import@ubuntu.com-20140408081714-31du0g3p3ggkwe9o
Tags: 5.7.2~dfsg-8.1ubuntu3
* SECURITY UPDATE: denial of service via AgentX subagent timeout
  - debian/patches/CVE-2012-6151.patch: track cancelled sessions in
    agent/mibgroup/agentx/{master.c,master_admin.c}, agent/snmp_agent.c,
    include/net-snmp/agent/snmp_agent.h.
  - CVE-2012-6151
* SECURITY UPDATE: denial of service when ICMP-MIB is in use
  - debian/patches/CVE-2014-2284.patch: fix ICMP mib table handling in
    agent/mibgroup/mibII/icmp.c, agent/mibgroup/mibII/kernel_linux.*.
  - CVE-2014-2284
* SECURITY UPDATE: denial of service in perl trap handler
  - debian/patches/CVE-2014-2285.patch: handle empty community string in
    perl/TrapReceiver/TrapReceiver.xs.
  - CVE-2014-2285

Show diffs side-by-side

added added

removed removed

Lines of Context:
1446
1446
        netsnmp_free_cachemap(asp->cache_store);
1447
1447
        asp->cache_store = NULL;
1448
1448
    }
 
1449
    agent_snmp_session_release_cancelled(asp);
1449
1450
    SNMP_FREE(asp);
1450
1451
}
1451
1452
 
1457
1458
 
1458
1459
    if (NULL == asp->treecache)
1459
1460
        return 0;
 
1461
 
 
1462
    if (agent_snmp_session_is_cancelled(asp)) {
 
1463
        return 0;
 
1464
    }
1460
1465
    
1461
1466
    for (i = 0; i <= asp->treecache_num; i++) {
1462
1467
        for (request = asp->treecache[i].requests_begin; request;
1535
1540
netsnmp_remove_delegated_requests_for_session(netsnmp_session *sess)
1536
1541
{
1537
1542
    netsnmp_agent_session *asp;
1538
 
    int count = 0;
 
1543
    int total_count = 0;
1539
1544
    
1540
1545
    for (asp = agent_delegated_list; asp; asp = asp->next) {
1541
1546
        /*
1542
1547
         * check each request
1543
1548
         */
 
1549
        int i;
 
1550
        int count = 0;
1544
1551
        netsnmp_request_info *request;
1545
 
        for(request = asp->requests; request; request = request->next) {
1546
 
            /*
1547
 
             * check session
1548
 
             */
1549
 
            netsnmp_assert(NULL!=request->subtree);
1550
 
            if(request->subtree->session != sess)
1551
 
                continue;
 
1552
        for (i = 0; i <= asp->treecache_num; i++) {
 
1553
            for (request = asp->treecache[i].requests_begin; request;
 
1554
                 request = request->next) {
 
1555
                /*
 
1556
                 * check session
 
1557
                 */
 
1558
                netsnmp_assert(NULL!=request->subtree);
 
1559
                if(request->subtree->session != sess)
 
1560
                    continue;
1552
1561
 
1553
 
            /*
1554
 
             * matched! mark request as done
1555
 
             */
1556
 
            netsnmp_request_set_error(request, SNMP_ERR_GENERR);
1557
 
            ++count;
 
1562
                /*
 
1563
                 * matched! mark request as done
 
1564
                 */
 
1565
                netsnmp_request_set_error(request, SNMP_ERR_GENERR);
 
1566
                ++count;
 
1567
            }
 
1568
        }
 
1569
        if (count) {
 
1570
            agent_snmp_session_mark_cancelled(asp);
 
1571
            total_count += count;
1558
1572
        }
1559
1573
    }
1560
1574
 
1561
1575
    /*
1562
1576
     * if we found any, that request may be finished now
1563
1577
     */
1564
 
    if(count) {
 
1578
    if(total_count) {
1565
1579
        DEBUGMSGTL(("snmp_agent", "removed %d delegated request(s) for session "
1566
 
                    "%8p\n", count, sess));
1567
 
        netsnmp_check_outstanding_agent_requests();
 
1580
                    "%8p\n", total_count, sess));
 
1581
        netsnmp_check_delegated_requests();
1568
1582
    }
1569
1583
    
1570
 
    return count;
 
1584
    return total_count;
1571
1585
}
1572
1586
 
1573
1587
int
2739
2753
    return final_status;
2740
2754
}
2741
2755
 
2742
 
/*
2743
 
 * loop through our sessions known delegated sessions and check to see
2744
 
 * if they've completed yet. If there are no more delegated sessions,
2745
 
 * check for and process any queued requests
2746
 
 */
2747
2756
void
2748
 
netsnmp_check_outstanding_agent_requests(void)
 
2757
netsnmp_check_delegated_requests(void)
2749
2758
{
2750
2759
    netsnmp_agent_session *asp, *prev_asp = NULL, *next_asp = NULL;
2751
2760
 
2752
 
    /*
2753
 
     * deal with delegated requests
2754
 
     */
2755
2761
    for (asp = agent_delegated_list; asp; asp = next_asp) {
2756
2762
        next_asp = asp->next;   /* save in case we clean up asp */
2757
2763
        if (!netsnmp_check_for_delegated(asp)) {
2790
2796
            prev_asp = asp;
2791
2797
        }
2792
2798
    }
 
2799
}
 
2800
 
 
2801
/*
 
2802
 * loop through our sessions known delegated sessions and check to see
 
2803
 * if they've completed yet. If there are no more delegated sessions,
 
2804
 * check for and process any queued requests
 
2805
 */
 
2806
void
 
2807
netsnmp_check_outstanding_agent_requests(void)
 
2808
{
 
2809
    netsnmp_agent_session *asp;
 
2810
 
 
2811
    /*
 
2812
     * deal with delegated requests
 
2813
     */
 
2814
    netsnmp_check_delegated_requests();
2793
2815
 
2794
2816
    /*
2795
2817
     * if we are processing a set and there are more delegated
2819
2841
 
2820
2842
            netsnmp_processing_set = netsnmp_agent_queued_list;
2821
2843
            DEBUGMSGTL(("snmp_agent", "SET request remains queued while "
2822
 
                        "delegated requests finish, asp = %8p\n", asp));
 
2844
                        "delegated requests finish, asp = %8p\n",
 
2845
                        agent_delegated_list));
2823
2846
            break;
2824
2847
        }
2825
2848
#endif /* NETSNMP_NO_WRITE_SUPPORT */
2880
2903
    case SNMP_MSG_GETBULK:
2881
2904
    case SNMP_MSG_GETNEXT:
2882
2905
        netsnmp_check_all_requests_status(asp, 0);
 
2906
        if (agent_snmp_session_is_cancelled(asp)) {
 
2907
            DEBUGMSGTL(("snmp_agent","canceling next walk for asp %p\n", asp));
 
2908
            break;
 
2909
        }
2883
2910
        handle_getnext_loop(asp);
2884
2911
        if (netsnmp_check_for_delegated(asp) &&
2885
2912
            netsnmp_check_transaction_id(asp->pdu->transid) !=
3836
3863
}
3837
3864
#endif /* NETSNMP_FEATURE_REMOVE_SET_ALL_REQUESTS_ERROR */
3838
3865
/** @} */
 
3866
 
 
3867
 
 
3868
/*
 
3869
 * Ugly hack to fix bug #950602 and preserve ABI
 
3870
 * (the official patch adds netsnmp_agent_session->flags).
 
3871
 * We must create parallel database of netsnmp_agent_sessions
 
3872
 * and put cancelled requests there instead of marking
 
3873
 * netsnmp_agent_session->flags.
 
3874
 */
 
3875
static netsnmp_agent_session **cancelled_agent_snmp_sessions;
 
3876
static int cancelled_agent_snmp_sessions_count;
 
3877
static int cancelled_agent_snmp_sessions_max;
 
3878
 
 
3879
int
 
3880
agent_snmp_session_mark_cancelled(netsnmp_agent_session *session)
 
3881
{
 
3882
    DEBUGMSGTL(("agent:cancelled", "Cancelling session %p\n", session));
 
3883
    if (!session)
 
3884
        return 0;
 
3885
    if (cancelled_agent_snmp_sessions_count + 1 > cancelled_agent_snmp_sessions_max) {
 
3886
        netsnmp_agent_session **aux;
 
3887
        int max = cancelled_agent_snmp_sessions_max + 10;
 
3888
        aux = realloc(cancelled_agent_snmp_sessions, sizeof(netsnmp_agent_session*) * max);
 
3889
        if (!aux)
 
3890
            return SNMP_ERR_GENERR;
 
3891
        cancelled_agent_snmp_sessions = aux;
 
3892
        cancelled_agent_snmp_sessions_max = max;
 
3893
    }
 
3894
    cancelled_agent_snmp_sessions[cancelled_agent_snmp_sessions_count] = session;
 
3895
    cancelled_agent_snmp_sessions_count++;
 
3896
    return 0;
 
3897
}
 
3898
 
 
3899
int
 
3900
agent_snmp_session_is_cancelled(netsnmp_agent_session *session)
 
3901
{
 
3902
    int i;
 
3903
    for (i=0; i<cancelled_agent_snmp_sessions_count; i++)
 
3904
        if (cancelled_agent_snmp_sessions[i] == session) {
 
3905
            DEBUGMSGTL(("agent:cancelled", "session %p is cancelled\n", session));
 
3906
            return TRUE;
 
3907
    }
 
3908
    return FALSE;
 
3909
}
 
3910
 
 
3911
int
 
3912
agent_snmp_session_release_cancelled(netsnmp_agent_session *session)
 
3913
{
 
3914
    int i, j;
 
3915
 
 
3916
    if (!session)
 
3917
        return 0;
 
3918
 
 
3919
    DEBUGMSGTL(("agent:cancelled", "Removing session %p\n", session));
 
3920
 
 
3921
    /* delete the session from cancelled_agent_snmp_sessions */
 
3922
    for (i=0, j=0; j<cancelled_agent_snmp_sessions_count; i++, j++)
 
3923
        if (cancelled_agent_snmp_sessions[j] == session)
 
3924
            i--; /* don't increase i in this loop iteration */
 
3925
        else
 
3926
            cancelled_agent_snmp_sessions[i] = cancelled_agent_snmp_sessions[j];
 
3927
 
 
3928
    cancelled_agent_snmp_sessions_count = i;
 
3929
 
 
3930
    for (; i< cancelled_agent_snmp_sessions_max; i++)
 
3931
        cancelled_agent_snmp_sessions[i] = NULL;
 
3932
    return 0;
 
3933
}