Security: Apache mod code review

Bug #457442 reported by root
8
This bug affects 1 person
Affects Status Importance Assigned to Milestone
psiphon
Confirmed
Unknown
Unassigned

Bug Description

* Run Static analysis tools to identify buffer overflows, memory leaks, thread deadlocks, etc.
            * E.g, Coverity

Tags: category3
Revision history for this message
root (n-root-psiphon-ca) wrote :
Download full text (5.7 KiB)

Here's a quick, first cut using a basic tool, cppcheck. Also see the item at the bottom which is from compiler warnings.

                cppcheck output:

                [./mod_psiphon_db_to_cookie.c:100]: Memory leak: tm
                [./mod_test.c:245]: Resource leak: f
                [./proxy/proxy_util.c:2885]: Memory leak: tm

                Here are the files. Review my fixes in rev 967.

                =======================================================

                ./mod_psiphon_db_to_cookie.c

                No frees on return, so this does look like a memory leak. What's sizeof(*tm), shouldn't it be sizeof(struct tm)? Wait, why is there am allocation here at all? It looks like the pointer to the allocated memory is overwritten ("tm = gmtime(&t)") and the allocated memory is never referenced.. Also, should use thread-safe gtime_r (http://www.opengroup.org/onlinepubs/009695399/functions/gmtime.html).

                =======================================================

                struct tm *tm = malloc(sizeof(*tm));
                time_t t = time(NULL);
                char *tstr;

                dbtc_log("dbtc()");

                dconf = (struct_dbtc_dir_config *) ap_get_module_config(r->per_dir_config,
                &psiphon_db_to_cookie_module);

                if (!dconf->need_dbtc) {
                dbtc_log("dbtc(): no need dbtc");
                return DECLINED;
                };

                if (r->main != NULL) /*no subrequests*/
                {
                dbtc_log("dbtc(): not a main request");
                return DECLINED;
                }
                tm = gmtime(&t);
                t = mktime(tm);
                tstr = apr_psprintf(r->pool, "%d", t);

                =======================================================

                ./mod_test.c

                File f isn't closed. Is this just a test routine? Should fix anyways. Should this file be removed before open source?

                =======================================================

                int test_hook(request_rec *r) {
                struct_test_dir_config *dconf;
                char body[MAX_BODY];
                // const char *body = "here is line\r\nhere IS digits: 12345\r\nqqqq\n";
                const char *result;

                regs_v_t **regs_v;
                FILE *f;

                jsf_log("test_hook()");

                dconf = (struct_test_dir_config *) ap_get_module_config(r->per_dir_config,
                &test_module);

                if (!dconf->enable) {
                jsf_log("test_hook(): don't need test");
                return DECLINED;
                };

                jsf_log("test_hook(): running");

                ap_set_content_type(r, "text/plain");

 ...

Read more...

Revision history for this message
root (n-root-psiphon-ca) wrote :

printf in mod_map_to_proxy.c fixed in r968

Revision history for this message
root (n-root-psiphon-ca) wrote :
Download full text (113.1 KiB)

Splint 3.1.1 --- 28 Apr 2003

                mod_bluebar.c: (in function bluebar_filter)
                mod_bluebar.c:118:5: Return value (type ap_filter_t *) ignored:
                ap_add_output_fi...
                Result returned by function call is not used. If this is intended, can cast
                result to (void) to eliminate message. (Use -retvalother to inhibit warning)
                mod_bluebar.c:132:17: Return value (type apr_status_t) ignored:
                ap_pass_brigade(...
                mod_bluebar.c:134:13: Return value (type apr_status_t) ignored:
                apr_brigade_clea...
                mod_bluebar.c:147:5: Return value (type apr_status_t) ignored:
                apr_brigade_clea...
                mod_bluebar.c:72:25: Variable end declared but not used
                A variable is declared but never used. Use /*@unused@*/ in front of
                declaration to suppress message. (Use -varuse to inhibit warning)
                mod_bluebar.c:74:17: Variable subpool declared but not used
                mod_bluebar.c: (in function bluebar_store_filter)
                mod_bluebar.c:160:9: Return value (type apr_status_t) ignored:
                apr_brigade_clea...
                mod_bluebar.c:174:5: Return value (type apr_status_t) ignored:
                apr_brigade_clea...
                mod_bluebar.c:157:9: Variable seen_eos declared but not used
                mod_bluebar.c:183:5: Initializer block for bluebar_cmds[1] has 1 field, but
                command_rec has 6 fields: NULL
                Initializer does not set every field in the structure. (Use -fullinitblock to
                inhibit warning)
                mod_bluebar.c: (in function bluebar_register_hook)
                mod_bluebar.c:190:9: Function ap_register_output_filter_protocol expects arg 5
                to be unsigned int gets int: 0x1 | 0x2
                To ignore signs in type comparisons use +ignoresigns
                mod_bluebar.c:188:5: Return value (type ap_filter_rec_t *) ignored:
                ap_register_outp...
                mod_bluebar.c:193:9: Function ap_register_output_filter_protocol expects arg 5
                to be unsigned int gets int: 0x1 | 0x2
                mod_bluebar.c:191:5: Return value (type ap_filter_rec_t *) ignored:
                ap_register_outp...
                mod_bluebar.c:198:10: Variable bluebar_module redefined
                A function or variable is redefined. One of the declarations should use
                extern. (Use -redef to inhibit warning)
                mod_bluebar.c:35:10: Previous definition of bluebar_module
                mod_deflate.c: (in function flush_libz_buffer)
                mod_deflate.c:334:14: Assignment of apr_size_t to uInt:
                ctx->stream.avail_out = c->bufferSize
                Types are incompatible. (Use -type to inhibit warning)
                mod_deflate.c: (in function deflate_out_filter)
                mod_deflate.c:593:9: Assignment of apr_size_t to uInt:
                ctx->stream.avail_out = c->bufferSize
                mod_deflate.c:628:49: Function apr_off_t_toa expects arg 2 to...

Revision history for this message
root (n-root-psiphon-ca) wrote :

[] has contacted Coverity to request access to their Prevent scanning application.

                Here's another possibility: http://www.ibm.com/developerworks/downloads/r/rsar/?S_TACT=105AGX15&S_CMP=LP

                We should also run Splint 3.1.2. But it's complaining about parsing errors:

                ~/splint-3.1.2/bin/splint *.c -I./utils -I/usr/local/include/libxml2 -I/usr/local/apache2/include -larchpath ~/splint-3.1.2/lib -lclimportdir ~/splint-3.1.2/import -D"off64_t=long long" +posixlib -weak -gnuextensions
                Splint 3.1.2 --- 15 Jun 2009

                /usr/include/sys/syslog.h:200:66: Parse Error:
                Inconsistent function parameter syntax: __gnuc_va_list :
                <any>. (For help on parse errors, see splint -help parseerrors.)
                *** Cannot continue.

                To suppress the low risk errors we reviewed in 3.1.1, try a scan with these switches: +matchanyintegral, +ignoresigns, +varuse (these aren't necessarily harmless though)

Revision history for this message
root (n-root-psiphon-ca) wrote :
Download full text (57.2 KiB)

Splint 3.1.2 --- 15 Jun 2009

                mod_bluebar.c: (in function bluebar_filter)
                mod_bluebar.c:89:10: Unrecognized identifier: strncasecmp
                Identifier used in code has not been declared. (Use -unrecog to inhibit
                warning)
                mod_bluebar.c:118:5: Return value (type ap_filter_t *) ignored:
                ap_add_output_fi...
                Result returned by function call is not used. If this is intended, can cast
                result to (void) to eliminate message. (Use -retvalother to inhibit warning)
                mod_bluebar.c:132:17: Return value (type apr_status_t) ignored:
                ap_pass_brigade(...
                mod_bluebar.c:134:13: Return value (type apr_status_t) ignored:
                apr_brigade_clea...
                mod_bluebar.c:147:5: Return value (type apr_status_t) ignored:
                apr_brigade_clea...
                mod_bluebar.c: (in function bluebar_store_filter)
                mod_bluebar.c:160:9: Return value (type apr_status_t) ignored:
                apr_brigade_clea...
                mod_bluebar.c:174:5: Return value (type apr_status_t) ignored:
                apr_brigade_clea...
                mod_bluebar.c:183:5: Initializer block for bluebar_cmds[1] has 1 field, but
                command_rec has 6 fields: NULL
                Initializer does not set every field in the structure. (Use -fullinitblock to
                inhibit warning)
                mod_bluebar.c: (in function bluebar_register_hook)
                mod_bluebar.c:188:5: Return value (type ap_filter_rec_t *) ignored:
                ap_register_outp...
                mod_bluebar.c:191:5: Return value (type ap_filter_rec_t *) ignored:
                ap_register_outp...
                mod_deflate.c: (in function check_gzip)
                mod_deflate.c:109:14: Unrecognized identifier: strcasecmp
                mod_deflate.c: (in function deflate_out_filter)
                mod_deflate.c:695:9: Return value (type apr_status_t) ignored:
                (e)->type->read(...
                mod_deflate.c:734:5: Return value (type apr_status_t) ignored:
                apr_brigade_clea...
                mod_deflate.c: (in function deflate_in_filter)
                mod_deflate.c:835:9: Return value (type apr_status_t) ignored:
                apr_brigade_clea...
                mod_deflate.c:884:13: Return value (type apr_status_t) ignored:
                (bkt)->type->rea...
                mod_deflate.c:962:9: Return value (type apr_status_t) ignored:
                apr_brigade_clea...
                mod_deflate.c:987:9: Return value (type apr_status_t) ignored:
                apr_brigade_part...
                mod_deflate.c: (in function inflate_out_filter)
                mod_deflate.c:1190:9: Return value (type apr_status_t) ignored:
                (e)->type->read(...
                mod_deflate.c:1328:5: Return value (type apr_status_t) ignored:
                apr_brigade_clea...
                mod_deflate.c: (in function register_hooks)
                mod_deflate.c:1335:5: Return value (type ap_filter_rec_t *) ignored:
 ...

Revision history for this message
root (n-root-psiphon-ca) wrote :

Here are comments from manual code review of mod_headers:

                ---------- Forwarded message ----------
                Date: Fri, Jun 19, 2009 at 4:09 PM
                Subject: mod_header review

                Here are my comments:

                psiphon_headers_utils.c

                * What's the source of the util functions? If from well-regarded open
                source project, then maybe I don't need to dig into all the time calc
                and parsing stuff and can assume it's ok (which I did). But then we
                need to put proper attribution and copyright notices, etc.

                mod_psiphon_headers.c

                * Query logic around line 579 and on is weird. In the query =
                query_delete case, it looks like SQL DELETE will be attempted 3 times
                in the case of a low-level database error. Should check for "rows
                affected" separately from database error checks. Also, may be better
                to do UPDATE instead of DELETE/INSERT.

                * There's a lot of low level string manipulation in this code. I
                can't be certain it's all free from buffer overflow type issues. More
                use of string library routines (can we use C++ here?) would be nice in
                the future.

                * apr_dbd_escape may not be as secure as parameterized queries (as is
                the case in PHP)

                * Add limit for domain depth (a.b.c.d.....com) to 10 or so? Line 256.

                * Comment explaining magic limit of 20 cookies. Comments explaining
                domain logic in line 256, path logic in line 299. More comments would
                be good in general. Link to any relevant specs or discussions (e.g.,
                http://en.wikipedia.org/wiki/HTTP_cookie). Showing how an example is
                processed (e.g., a.b.c.org/x/y/z) would be helpful.

                * As we just discussed, line 269 "query = apr_pstrcat(r->pool, query,
                " order by id desc", NULL);" should actually order by len(domain) or
                something to ensure that the hash table logic around line 279 respects
                the correct precedence rules for cookies with same key, different
                domain level.

Revision history for this message
root (n-root-psiphon-ca) wrote :

Moving out of Open Source, as we've done what we intend to do for review in advance of that release. Still waiting to hear from Coverity about running their tool... should contact them again after open source release, as we'd then qualify directly under the terms of their Scan project: http://scan.coverity.com/devfaq.html

Adam P (adam+)
Changed in psiphon:
status: In Progress → New
Adam P (adam+)
Changed in psiphon:
status: New → Confirmed
Rod (rod-psiphon)
visibility: private → public
Rod (rod-psiphon)
tags: added: category3
To post a comment you must log in.
This report contains Public information  
Everyone can see this information.

Other bug subscribers

Remote bug watches

Bug watches keep track of this bug in other bug trackers.