cups icon indicating copy to clipboard operation
cups copied to clipboard

Cupsd cores on SPARC after allocating incorrectly aligned IPP_TAG_STRING.

Open l1gi opened this issue 2 years ago • 1 comments

I got a core from cupsd on Solaris 11.4. I still don't have any debug logs, but I plan to attach it. Could you look into it and help me find the place where the attribute was constructed so we can find the place with invalid alignment, please?

Thank you.

My analysis follows.

cupsd:core> ::status
debugging core file of cupsd (64-bit) from bdkzone3
file: /usr/sbin/cupsd
initial argv: /usr/sbin/cupsd -C /etc/cups/cupsd.conf -s /etc/cups/cups-files.conf
status: process terminated by SIGBUS (Bus Error) code=1 (BUS_ADRALN), addr=17ab0cdf64

cupsd:core> $C
fffffcfd1d189951 libc.so.1`_free_unlocked+0xbc(17ab0cdf74, 17ab0cdf74, 0, 1ffec62fe24000, 1ffec62fe36e98, 17ab0cdf74)
fffffcfd1d189a01 libc.so.1`free+0x50(1ffec62fe25980, b3f8, b000, 1ffec62fe24000, 1ffec62fe36e98, 0)
fffffcfd1d189ab1 libcups.so.2`ipp_free_values+0x118(17ab0caa80, 0, 1, 1ffec630432a40, 17ab0caab0, 17ab0caaa0)
fffffcfd1d189b61 libcups.so.2`ippDelete+0x70(17ab0ca870, 1, 1ffec62fe2c940, 1ffec630432a40, 17ab0caac0, 17ab0caa80)
fffffcfd1d189c11 cupsdWriteClient+0x3a0(17ab0cb290, 1ffec62f52de80, 0, 0, 0, 0)
fffffcfd1d189d01 cupsd`cupsdDoSelect+0x1e0(1, fffffcfd1d18a5b0, 17ab0cafe0, 1ffec630400c38, 17ab091ad0, 17ab0cafd8)
fffffcfd1d189dd1 main+0xaf0(1ffec630400700, fffffcfd1d18ab38, 1, 1ffec630400790, 618258cf, 1)
fffffcfd1d18a741 _start+0x64(0, 0, 0, 0, 0, 0)

cupsd:core> libc.so.1`_free_unlocked+0xbc::dis
...
libc.so.1`_free_unlocked+0xb8:  nop
libc.so.1`_free_unlocked+0xbc:  ldx       [%i0 - 0x10], %o4
libc.so.1`_free_unlocked+0xc0:  btst      0x1, %o4
libc.so.1`_free_unlocked+0xc4:  be,pn     %xcc, +0x80   <libc.so.1`_free_unlocked+0x144>

cupsd:core> <i0=J
                17ab0cdf74

We are reading from address 17ab0cdf64 which is not 64bit aligned, thus BUS_ADRALN.

It seems the instructions we are executing maps to

1132  	if (!ISBIT0(SIZE(BLOCK(old))))
1133  		return;

test in on-default/usr/src/lib/libc/port/gen/malloc.c and

60  typedef struct _t_ {
61  	size_t		t_s;
62  	struct _t_	*t_p;
63  	struct _t_	*t_l;
64  	struct _t_	*t_r;
65  	struct _t_	*t_n;
66  	struct _t_	*t_d;
67  } TREE;
68  #define	SIZE(b)		((b)->t_s)
136  #define	BLOCK(d)	((TREE *)(((uintptr_t)(d)) - WORDSIZE))

in on-default/usr/src/lib/libc/inc/mallint.h.

Argument to _free_unlocked is 17ab0cdf74.

Address sent to free() is not 8 bytes aligned, thus address-0x10 is not aligned also.

free() calls _free_unlocked() with the same argument.

ippDelete() was called from cupsdWriteClient() to free the attr collection. For each attr it calls ipp_free_values() which in turn calls free() on strings and maybe other tags:

6316        case IPP_TAG_STRING :
6317        default :
6318  	  for (i = count, value = attr->values + element;
6319  	       i > 0;
6320  	       i --, value ++)
6321  	  {
6322  	    if (value->unknown.data)
6323  	    {
6324  	      free(value->unknown.data);
6325  	      value->unknown.data = NULL;
6326  	    }
6327  	  }

The value we are looking at has definition:

111  struct _ipp_attribute_s			/**** IPP attribute ****/
112  {
113    ipp_attribute_t *next;		/* Next attribute in list */
114    ipp_tag_t	group_tag,		/* Job/Printer/Operation group tag */
115  		value_tag;		/* What type of value is it? */
116    char		*name;			/* Name of attribute */
117    int		num_values;		/* Number of values */
118    _ipp_value_t	values[1];		/* Values */
119  };
cupsd:core> 17ab0caa80,10/J
0x17ab0caa80:   17ab0caac0      400000030       17ab0cde54      100000000       0               17ab0cdf74      
                31              1ffec62f52f630  17ab0cab40      400000031       17ab0cab04      100000000       
                7e50b020e0f0e00 2b00000000000000 31              1ffec62f52f6f0  

cupsd:core> 17ab0caa80+8/X
0x17ab0caa88:   4

So group_tag should be 4, which is

686    IPP_TAG_PRINTER,			/* Printer group */
cupsd:core> 17ab0caa80+8+4/X
0x17ab0caa8c:   30

And value_tag should be 0x30, which is

703    IPP_TAG_STRING = 0x30,		/* Octet string value */
cupsd:core> 17ab0cde54/S
0x17ab0cde54:   printer-alert

name is "printer-alert".

num_values is 1.

And our value[0], argument to free() is 17ab0cdf74.

cupsd:core> 17ab0cdf74/S
0x17ab0cdf74:   \"printer-alert\"

The address should be 8 bytes aligned, but it is not. Why?

l1gi avatar Nov 10 '21 17:11 l1gi

Any news, please?

l1gi avatar Feb 10 '22 11:02 l1gi