Icinga / icinga-core

Icinga 1.x, the old core (EOL 31.12.2018)
GNU General Public License v2.0
45 stars 27 forks source link

[dev.icinga.com #11048] cgi/cgiutils.c NULL value with segfault in #1571

Closed icinga-migration closed 8 years ago

icinga-migration commented 8 years ago

This issue has been migrated from Redmine: https://dev.icinga.com/issues/11048

Created by fcolle on 2016-01-28 10:33:15 +00:00

Assignee: ricardo Status: Resolved (closed on 2016-07-18 21:05:48 +00:00) Target Version: 1.14 Last Update: 2016-07-18 21:05:48 +00:00 (in Redmine)

Icinga Version: 1.13.3
OS Version: CentOS 6.6

In cgiutils.c, rev #31dd493a and previous versions, the function void

get_time_string(time_t *raw_time, char *buffer, int buffer_length, int type)

contains this code:

    time_t t;
    struct tm *tm_ptr = NULL;
    int hour = 0;
    int minute = 0;
    int second = 0;
    int month = 0;
    int day = 0;
    int year = 0;
    char *weekdays[7] = {"Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"};
    char *months[12] = {"Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"};
    char *tzone = "";

    if (raw_time == NULL)
        time(&t);
    else
        t = *raw_time;

    if (type == HTTP_DATE_TIME)
        tm_ptr = gmtime(&t);
    else
        tm_ptr = localtime(&t);

    hour = tm_ptr->tm_hour;
    minute = tm_ptr->tm_min;
    second = tm_ptr->tm_sec;
    month = tm_ptr->tm_mon + 1;
    day = tm_ptr->tm_mday;
    year = tm_ptr->tm_year + 1900;

 ...

According to man pages, both gmtime() and localtime() functions can return NULL values on error. In that case, the following lines cause a segfault of the caller cgi.

A possible solution is to read again the current time from the OS (less likely to return NULL):

    time_t t;
    struct tm *tm_ptr = NULL;
    int hour = 0;
    int minute = 0;
    int second = 0;
    int month = 0;
    int day = 0;
    int year = 0;
    char *weekdays[7] = {"Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"};
    char *months[12] = {"Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"};
    char *tzone = "";

    if (raw_time == NULL)
        time(&t);
    else
        t = *raw_time;

    if (type == HTTP_DATE_TIME)
        tm_ptr = gmtime(&t);
    else
        tm_ptr = localtime(&t);

    if(!tmp_ptr)
    {
        //we read at least the local time
        t=time(NULL);
        tm_ptr=gmtime(&t));
        //todo: add some logging for warning about the invalid time value
    }
   if(tmp_ptr)
  {

    hour = tm_ptr->tm_hour;
    minute = tm_ptr->tm_min;
    second = tm_ptr->tm_sec;
    month = tm_ptr->tm_mon + 1;
    day = tm_ptr->tm_mday;
    year = tm_ptr->tm_year + 1900;
   }
..

This solution worked on my installation with Icinga2, classic UI and 2000 monitored hosts.

Changesets

2016-02-02 20:48:36 +00:00 by ricardo a3f736edf2da803ca422b26d436da5389a51665a

Fixed cgi/cgiutils.c NULL value with segfault in get_time_string #11048

Refs: #11048
whatthecommit: Well, it's doing something.
icinga-migration commented 8 years ago

Updated by ricardo on 2016-06-23 22:01:09 +00:00

Thank you for reporting.

Added changes to CGIs.

Cheers Ricardo

icinga-migration commented 8 years ago

Updated by ricardo on 2016-06-23 22:30:50 +00:00

fixed in https://dev.icinga.org/projects/icinga-core/repository/revisions/a3f736edf2da803ca422b26d436da5389a51665a

Cheers Ricardo

icinga-migration commented 8 years ago

Updated by ricardo on 2016-07-18 21:05:48 +00:00