>>>>> On Tue, 30 Nov 2004 21:40:25 -0800, >>>>> "David Schwartz" <davids_at_webmaster.com> said: >> % ./a.out >> address of p is 0x800 >> zsh: 794 segmentation fault (core dumped) ./a.out >> >> Is this a malloc bug? Or is this the intended behavior and the man >> page description is old? > This is the intended behavior but the man page description is correct. The > problem is not that the pointer is invalid but that you assumed that it was > large enough to hold a 'char' and it is not. I know the line of XXX is not correct; I simply tried to highlight the problem, but I seem to convey the real point. How about this example? main() { char *p = malloc(0), *q; printf("address of p is %p\n", p); printf("the value of p is %c\n", *p); } the execution of this code would be like this: % ./a.out address of p is 0x800 zsh: 645 segmentation fault (core dumped) ./a.out And, more specifically, my real-world problem is that 'ndp -r' fails when it calls sysctl without any IPv6 default routers. The related code of ndp is as follows: int mib[] = { CTL_NET, PF_INET6, IPPROTO_ICMPV6, ICMPV6CTL_ND6_DRLIST }; (...) if (sysctl(mib, sizeof(mib) / sizeof(mib[0]), NULL, &l, NULL, 0) < 0) { err(1, "sysctl(ICMPV6CTL_ND6_DRLIST)"); /*NOTREACHED*/ } buf = malloc(l); if (!buf) { err(1, "malloc"); /*NOTREACHED*/ } if (sysctl(mib, sizeof(mib) / sizeof(mib[0]), buf, &l, NULL, 0) < 0) { err(1, "sysctl(ICMPV6CTL_ND6_DRLIST)"); /*NOTREACHED*/ } The first call to sysctl sets 'l' to 0, since the list is empty. Then the malloc returns '0x800' as a *valid pointer*. But in the second call to sysctl, kernel rejects this pointer at line 1299 of sys/kern/kern_sysctl.c: userland_sysctl(struct thread *td, int *name, u_int namelen, void *old, size_t *oldlenp, int inkernel, void *new, size_t newlen, size_t *retval) { (...) if (old) { --> if (!useracc(old, req.oldlen, VM_PROT_WRITE)) --> return (EFAULT); and so we'll see % ndp -r ndp: sysctl(ICMPV6CTL_ND6_DRLIST): Bad address Note that the same code worked with, e.g., FreeBSD 4.10. So, if we wanted to call 0x800 "a valid pointer just with not-enough-size", it would be fine. But then we need to implement the same logic in the kernel to provide consistent behavior. (I would "fix" the malloc behavior though). JINMEI, Tatuya Communication Platform Lab. Corporate R&D Center, Toshiba Corp. jinmei_at_isl.rdc.toshiba.co.jpReceived on Wed Dec 01 2004 - 05:35:30 UTC
This archive was generated by hypermail 2.4.0 : Wed May 19 2021 - 11:38:23 UTC