NetBSD-Bugs archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
kern/49247: getsockname(2) requires sockaddr structure to cleared
>Number: 49247
>Category: kern
>Synopsis: getsockname(2) requires sockaddr structure to cleared
>Confidential: no
>Severity: serious
>Priority: high
>Responsible: kern-bug-people
>State: open
>Class: sw-bug
>Submitter-Id: net
>Arrival-Date: Tue Sep 30 08:35:00 +0000 2014
>Originator: Takahiro Kambe
>Release: NetBSD 7.0_BETA
>Organization:
Takahiro Kambe
>Environment:
System: NetBSD edge.back-street.net 7.0_BETA NetBSD 7.0_BETA (VMWARE-F6) #2: Sat Sep 13 08:53:11 JST 2014 taca%edge.back-street.net@localhost:/data/amd64/obj/sys/arch/amd64/compile/VMWARE-F6 amd64
Architecture: x86_64
Machine: amd64
>Description:
getsockname(2) requires sockaddr structure to zero cleared when
passing UNIX domain socket. On NetBSD 6.1_STABLE, no such
assumeption was needed.
And it break lmtp support of dovecot2.
>How-To-Repeat:
Here is a simple sample program. Executing without argument,
storange output on NetBSD 7.0_BETA.
% ./a.out
18: /var/tmp/socktest0aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
18: /var/tmp/socktest1aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
With some argument or execute on NetBSD 6.1_STABLE,
% ./a.out foo
18: /var/tmp/socktest0
18: /var/tmp/socktest1
#include <stdio.h>
#include <stdlib.h>
#include <stddef.h>
#include <string.h>
#include <err.h>
#include <errno.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/un.h>
#define UPATH "/var/tmp/socktest"
#define N 2
int
make_sock(char *path)
{
int fd;
struct sockaddr_un un;
fd = socket(PF_LOCAL, SOCK_STREAM, 0);
if (fd < 0)
err(EXIT_FAILURE, "socket");
un.sun_family = AF_UNIX;
strcpy(un.sun_path, path);
un.sun_len = SUN_LEN(&un);
(void)unlink(path);
if (bind(fd, (struct sockaddr *)&un, sizeof un))
err(EXIT_FAILURE, "bind");
return fd;
}
int
main(int argc, char *argv[])
{
int i, n, clear, fd[N];
struct sockaddr_un *run;
struct sockaddr_storage ss;
socklen_t len;
char buf[BUFSIZ];
clear = (argc > 1)? 1: 0;
n = N;
for (i = 0; i < n; i++) {
sprintf(buf, "%s%d", UPATH, i);
fd[i] = make_sock(buf);
}
for (i = 0; i < n; i++) {
if (clear)
memset(&ss, 0, sizeof ss);
else
memset(&ss, 'a', sizeof ss);
run = (struct sockaddr_un *)&ss;
len = sizeof *run;
if (getsockname(fd[i], (struct sockaddr *)run, &len))
err(EXIT_FAILURE, "getsockname");
printf("%d: %s\n", len - 2, run->sun_path);
}
return EXIT_SUCCESS;
}
>Fix:
Unknown. Workaround is make user program to clear sockaddr
structure before calling getsockname(2).
And I don't check in the case of getpeername(2).
>Unformatted:
Home |
Main Index |
Thread Index |
Old Index