bug-gnulib
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: non-null declarations, recvfrom, sendto


From: Bruno Haible
Subject: Re: non-null declarations, recvfrom, sendto
Date: Fri, 11 Dec 2009 00:44:02 +0100
User-agent: KMail/1.9.9

Hi Eric, Paolo, Simon,

About sendto, I wrote:
> > > -extern int rpl_sendto (int, const void *, int, int, struct sockaddr *, 
> > > int);
> > > +extern int rpl_sendto (int, const void *, int, int, struct sockaddr *, 
> > > int)
> > > +     _GL_ARG_NONNULL ((2, 5));
> > 
> > Bug: Arg 5 can be NULL, since POSIX states that "The send( ) function is 
> > equivalent to sendto( ) with a null pointer dest_len argument" (well, 
> > that's 
> > also a bug in POSIX, since dest_len is socklen_t; it obviously meant a null 
> > dest_addr argument).
> 
> The only indication in the sendto specification that I can see is the
> sentence "If the socket is connection-mode, dest_addr shall be ignored."
> So, if a user knows that the socket is connection-mode, he may pass NULL.
> But I would qualify this as dangerous practice, therefore I leave the warning
> in.

Now I see in the Linux manpage
  <http://www.kernel.org/doc/man-pages/online/pages/man2/sendto.2.html>
that it is recommended practice to pass a 5th argument NULL in some cases:
  "If sendto() is used on a connection-mode (SOCK_STREAM, SOCK_SEQPACKET) 
socket,
   the arguments dest_addr and addrlen are ignored (and the error EISCONN may be
   returned when they are not NULL and 0)"

So I remove the warning for arg 5.

> > > -extern int rpl_recvfrom (int, void *, int, int, struct sockaddr *, int 
> > > *);
> > > +extern int rpl_recvfrom (int, void *, int, int, struct sockaddr *, int *)
> > > +     _GL_ARG_NONNULL ((2, 6));
> > 
> > Bug: Arg 6 can be NULL, since POSIX states that "The recv( ) function is 
> > equivalent to recvfrom( ) with a zero address_len argument" (well, 
> > technically, 
> > a null address_len argument only makes sense when address [arg 5] is also 
> > NULL).
> 
> Indeed, when the 5th argument is NULL, the 6th argument can be NULL as well.
> Corrected.

The Linux manpage
  <http://www.kernel.org/doc/man-pages/online/pages/man2/recvfrom.2.html>
also mentions this possibility:
  "When src_addr is NULL, nothing is
   filled in; in this case, addrlen is not used, and should also be NULL."

But this also means that our recvfrom wrapper makes invalid memory accesses.
Here is a proposed patch:


2009-12-10  Bruno Haible  <address@hidden>

        * lib/recvfrom.c (rpl_recvfrom): Allow the from argument to be NULL.

--- lib/recvfrom.c.orig 2009-12-11 00:33:28.000000000 +0100
+++ lib/recvfrom.c      2009-12-11 00:14:22.000000000 +0100
@@ -1,6 +1,6 @@
 /* recvfrom.c --- wrappers for Windows recvfrom function
 
-   Copyright (C) 2008 Free Software Foundation, Inc.
+   Copyright (C) 2008-2009 Free Software Foundation, Inc.
 
    This program is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
@@ -32,7 +32,7 @@
 rpl_recvfrom (int fd, void *buf, int len, int flags, struct sockaddr *from,
               int *fromlen)
 {
-  int frombufsize = *fromlen;
+  int frombufsize = (from != NULL ? *fromlen : 0);
   SOCKET sock = FD_TO_SOCKET (fd);
   int r = recvfrom (sock, buf, len, flags, from, fromlen);
 
@@ -41,7 +41,7 @@
 
   /* Winsock recvfrom() only returns a valid 'from' when the socket is
      connectionless.  POSIX gives a valid 'from' for all types of sockets.  */
-  else if (*fromlen == frombufsize)
+  else if (from != NULL && *fromlen == frombufsize)
     rpl_getpeername (fd, from, fromlen);
 
   return r;




reply via email to

[Prev in Thread] Current Thread [Next in Thread]