Bug #627

casts corrupt int values (on PPC)

Added by Anonymous 955 days ago. Updated 55 days ago.

Status:Invalid Start:
Priority:Normal Due date:
Assigned to:- % Done:

0%

Category:core
Target version:1.4.20
Pending:

No

Resolution:

invalid

Patch available:


Description

Debugging a module of my own, I encountered a problem that several config parameters of type int were being corrupted in a reproducible way. The problem, as it seems, lies with passing numeric values in and out of arrays. When, in a SETDEFAULTS_FUNC, values are inserted from a config context in a plugin config, this eventually results in the following statement (config-glue.c, rev. 510 line 78, or rev. 1102 line 90, in function config_insert_values_internal):


*((unsigned short *)(cv[i].destination)) = di->value;

The minimal test case is as follows:


#include <stdio.h>
#include <stdlib.h>
#include "array.h" /* From lighttpd */

void set(void *dest, data_unset *du) {
  *((unsigned short *)dest) = ((data_integer*)du)->value;
}

int main(int argc, char *argv[]) {
  int flags = 3000;
  int rcp;
  data_integer *di;

  di = data_integer_init();
  di->value = flags;
  set(&rcp, (data_unset*) di);
  printf("%d = %x\n%d = %x\n", flags, flags, rcp, rcp);
}

When compiled and run on my primary machine, which is a PowerPC, this prints:


3000 = bb8
196608000 = bb80000

I assume that this is due to PPC's being a big-endian architecture, but altogether, casting pointer types for variebyte data is somewhat careless. I have solved the problem locally by adding a new config_values_type_t value T_CONFIG_INT and a corresponding case in config_insert_values_internal. I worked with the version of lighttpd from DarwinPorts, which is no longer current, and the modification is trivial, but if you are interested in my patches anyway, please tell where to send them.

Thank you.

-- boris.smilga

src.ticket627.diff - patches for ticket #627 in src/base.h, src/configfile-glue.h (1013 Bytes) agrostis, 11/19/2006 10:35 PM

History

04/26/2006 06:27 AM - moo

simply attach file here, thanks.

11/19/2006 10:37 PM - agrostis

Sorry for the delay.

11/20/2006 01:05 AM - moo

i don't think we need short+int at the same time. any way to analyze the code automatically?

11/20/2006 01:06 PM - agrostis

Up to you. It might at least be reasonable to change the type of value in struct data_integer (array.h rev. 1349, line 132) to unsigned short as well.

I'm afraid I don't quite get your second remark.

11/21/2006 01:15 AM - moo

there're lots of lines to fix. either change CONFIG_SHORT to CONFIG_INTEGER and fix configure-glue.c, or change int to short. "any way to analyze the code automatically?" -> but do u think there's a way to analyze the code or anything so we can find out all the type mismatches? although i doubt it

11/21/2006 01:58 PM - agrostis

Replying to moo:

but do u think there's a way to analyze the code or anything so we can find out all the type mismatches? although i doubt it

There are, of course, lint and similar tools, such as SpLint, SMatch, and some commercial software. I only rarely program in C, and cannot really recommend anything.

04/24/2008 07:52 PM - stbuehler

  • Status changed from New to Fixed
  • Resolution set to invalid

It looks like no module in upstream needs CONFIG_INTEGER, they alway use unsigned short for integer config options (if not, that would be a bug).

Perhaps it would be a good idea to convert all CONFIG_SHORT to CONFIG_INTEGER, but i see no bug here.

10/10/2008 06:53 PM - stbuehler

  • Status changed from Fixed to Invalid

Also available in: Atom PDF