This is the mail archive of the cygwin mailing list for the Cygwin project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

bind(sock, addr, addrlen) doesn't respect addrelen


Hi.

I found bind(sock, addr, addrlen) function doesn't respect addrlen.

If addr is AF_UNIX socket address and sun_path field is not
NUL-terminated until the length specified as addrlen,
bind() refer bytes after addrlen.
This can be observed by created socket file name is longer
than expected.

The test program attached below specifies addrlen as
offsetof(struct sockaddr_un, sun_path) + 2.
So I expect bind() uses sun_path[0] and sun_path[1] and
doen't use sun_path[2] and later.
But actually created socket is "abcd".
This means bind() uses sun_path[0] to sun_path[3]
(and the terminating NUL in sun_path[4]).

I know POSIX defines sun_path as pathname and
pathname is NUL-terminated by definition.
So strictly speaking, this test is not POSIX conforming.

But I feel the given length should be respected and
other platforms such as GNU/Linux, FreeBSD, NetBSD,
OpenBSD and SunOS respects addrlen.

I found this problem when I made a more generic test program:
https://github.com/akr/socket-test
result: http://htmlpreview.github.com/?https://github.com/akr/socket-test/blob/master/results.html

% uname -mrsv
CYGWIN_NT-5.1 1.7.17(0.262/5/3) 2012-10-19 14:39 i686
% ls
tst.c
% gcc -Wall tst.c -o tst
% ls
tst.c  tst.exe
% ./tst
% ls
abcd  tst.c  tst.exe
% file abcd
abcd: socket
% cat tst.c
#include <stddef.h>
#include <stdlib.h>
#include <stdio.h>
#include <sys/socket.h>
#include <sys/un.h>

int main(int argc, char *argv[])
{
  int s, ret;
  struct sockaddr_un addr;
  socklen_t addrlen;

  s = socket(AF_UNIX, SOCK_STREAM, 0);
  if (s == -1) { perror("socket"); exit(EXIT_FAILURE); }

  addrlen = offsetof(struct sockaddr_un, sun_path) + 2;
  addr.sun_family = AF_UNIX;
  addr.sun_path[0] = 'a';
  addr.sun_path[1] = 'b';
  addr.sun_path[2] = 'c';
  addr.sun_path[3] = 'd';
  addr.sun_path[4] = '\0';

  ret = bind(s, (struct sockaddr *)&addr, addrlen);
  if (s == -1) { perror("bind"); exit(EXIT_FAILURE); }

  return EXIT_SUCCESS;
}
-- 
Tanaka Akira

--
Problem reports:       http://cygwin.com/problems.html
FAQ:                   http://cygwin.com/faq/
Documentation:         http://cygwin.com/docs.html
Unsubscribe info:      http://cygwin.com/ml/#unsubscribe-simple


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]