[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: Guile segfault with network calls
From: |
Gary Houston |
Subject: |
Re: Guile segfault with network calls |
Date: |
3 Mar 2001 13:23:36 -0000 |
> From: Martin Grabmueller <address@hidden>
> Date: Thu, 1 Mar 2001 10:28:55 +0100 (MET)
>
> Hello list,
>
> Guile segfaults when a Unix domain address with a very long pathname is
> passed to calls like `connect', `bind' or `sendto'.
>
> Example:
>
> guile> (define s (socket AF_UNIX SOCK_STREAM 0))
> guile> (connect s AF_UNIX (make-string 100000 #\c))
> Segmentation fault
>
> The reason is the following code in `scm_fill_sockaddr' in socket.c:424,
> where a memcpy is made without checking for the length.
Yikes, well spotted.
> #ifdef HAVE_UNIX_DOMAIN_SOCKETS
> case AF_UNIX:
> {
> struct sockaddr_un *soka;
>
> soka = (struct sockaddr_un *)
> scm_must_malloc (sizeof (struct sockaddr_un), proc);
> memset (soka, 0, sizeof (struct sockaddr_un));
> soka->sun_family = AF_UNIX;
> SCM_ASSERT (SCM_STRINGP (address), address, which_arg, proc);
> memcpy (soka->sun_path, SCM_STRING_CHARS (address),
> 1 + SCM_STRING_LENGTH (address));
> *size = sizeof (struct sockaddr_un);
> return (struct sockaddr *) soka;
> }
> #endif
>
> I don't know what the correct fix for this is, because I couldn't find
> out whether there is a standard maximum path length. Maybe POSIX or
> one of the other `Standards' defines one? Does anyone know?
We could use sizeof soka->sun_path. But I noticed this comment in
the glibc manual:
`char sun_path[108]'
This is the file name to use.
*Incomplete:* Why is 108 a magic number? RMS suggests making
this a zero-length array and tweaking the following example
to use `alloca' to allocate an appropriate amount of storage
based on the length of the filename.
If it was implemented like that, sizeof wouldn't work. How about this:
--- socket.c 2001/02/02 04:56:25 1.60
+++ socket.c 2001/03/03 13:19:32
@@ -425,15 +425,21 @@
case AF_UNIX:
{
struct sockaddr_un *soka;
+ size_t addr_size;
+ SCM_ASSERT (SCM_STRINGP (address), address, which_arg, proc);
+ /* the static buffer size in sockaddr_un seems to be arbitrary
+ and not necessarily a hard limit. let's ignore it.
+ sun_path is always the last member of the structure. */
+ addr_size = sizeof (struct sockaddr_un)
+ + max (0, SCM_STRING_LENGTH (address) + 1 - (sizeof soka->sun_path));
soka = (struct sockaddr_un *)
- scm_must_malloc (sizeof (struct sockaddr_un), proc);
- memset (soka, 0, sizeof (struct sockaddr_un));
+ scm_must_malloc (addr_size, proc);
+ memset (soka, 0, addr_size); /* for sun_len: see sin_len above. */
soka->sun_family = AF_UNIX;
- SCM_ASSERT (SCM_STRINGP (address), address, which_arg, proc);
memcpy (soka->sun_path, SCM_STRING_CHARS (address),
- 1 + SCM_STRING_LENGTH (address));
- *size = sizeof (struct sockaddr_un);
+ SCM_STRING_LENGTH (address) + 1);
+ *size = SUN_LEN (soka);
return (struct sockaddr *) soka;
}
#endif