I was confused, it really is an off by one (bug buster song, it's an off
by one and it ain't no fun).
Program received signal SIGSEGV, Segmentation fault.
0x00000c4edab20b14 in main () at buffer.c:30
30 printf("len = %d\n", att->somelen);
Current language: auto; currently minimal
(gdb) list
Here is the test code, I do believe this is what it does also in radius.c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
struct attribute {
uint8_t somevar;
uint8_t somelen;
uint32_t someothervar;
};
int
main(void)
{
char *p, *end;
int len = 4096;
struct attribute *att;
p = malloc(len);
if (p == NULL) {
perror("malloc");
exit(1);
}
end = p + len;
att = (struct attribute *)(end - 1);
printf("len = %d\n", att->somelen);
sleep(10);
return 0;
}
OK please excuse the formatting of this mail, it's written with
thunderbird and I'm not at home either.
BTW I just did an if statement instead of the printf() and it cored again:
spica$ ./buffer
Segmentation fault (core dumped)
Best regards,
-peter
On 2/10/24 10:40, Peter J. Philipp wrote:
On 2/10/24 08:38, Peter J. Philipp wrote:
Hi,
I'd like you to just quickly look at the following to files:
/usr/src/lib/libradius/radius.c
61 for (; attr < end; ATTRS_ADVANCE(attr)) {
62 if (attr->length < 2)
63 return (-1);
and it's header file
/usr/lib/lib/libradius/radius_local.h
68 #define ATTRS_NEXT(x) ((RADIUS_ATTRIBUTE*)(((char*)x) +
x->length))
69
70 /*
71 * must be expression rather than statement
72 * to be used in third expression of for statement.
73 */
74 #define ATTRS_ADVANCE(x) (x = ATTRS_NEXT(x))
If a packet manages to point beyond "end" pointer, attr->length is
accessed
right? This could result in some signal being delivered to the process?
Hi, I think I made a mistake. if attr is on (end - 1) then length is
at (end) which is still malloc'ed.
Best Regards,
-peter
--
Over thirty years experience on UNIX-like Operating Systems starting with QNX.