cups
cups copied to clipboard
Cupsd cores on SPARC after allocating incorrectly aligned IPP_TAG_STRING.
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?
Any news, please?