tags 291636 + sid patch security thanks Hi,
I managed to fix the issue. The original one I had on other(non-SMP) machine that some java processes doesn't authenticate correctly, and the problems arised when hammering a port(on a SMP machine; forgot to mention explicitly, sorry). The fix for the actual problem was already in 3.0.16-7 (assumably written by Herbert Xu, basing on the patch made by Paul Szabo. See #208290 for details), but didn't apply cleanly to the new upstream version. I rewrote/merged few parts that had problems applying cleanly. A patch attached. PS. As it seems (eg. according to #291180 ) there are few parts missing from the previous debian diff. You might consider applying them too. So, for convenience, also a cleanly applying patch containing those missing parts not directly related to #291636 or #291180 is also attached. -- Toni Timonen "toni dot timonen at iki dot fi" NP Solutions Ltd Helsinki University of Technology Department of Engineering Physics and Mathematics
diff -rub us/pidentd-3.0.18/debian/changelog try3/pidentd-3.0.18/debian/changelog --- us/pidentd-3.0.18/debian/changelog 2005-01-21 19:41:09.000000000 +0200 +++ try3/pidentd-3.0.18/debian/changelog 2005-01-22 16:56:25.000000000 +0200 @@ -1,3 +1,10 @@ +pidentd (3.0.18-1.1) unstable; urgency=low + + * Non-maintainer upload. + * Reapplied the TCPDIAG support patch. + + -- Toni Timonen <[EMAIL PROTECTED]> Sat, 22 Jan 2005 16:56:08 +0200 + pidentd (3.0.18-1) unstable; urgency=low * New upstream release. diff -rub us/pidentd-3.0.18/src/kernel.c try3/pidentd-3.0.18/src/kernel.c --- us/pidentd-3.0.18/src/kernel.c 2004-06-13 10:47:52.000000000 +0300 +++ try3/pidentd-3.0.18/src/kernel.c 2005-01-22 16:55:36.000000000 +0200 @@ -107,7 +107,7 @@ if (debug) fprintf(stderr, "ka_lookup(), attempt = %d, status = %d\n", attempt, kp->status); - if (kp->status > 0) + if (kp->status >= 0) break; if (attempt > 2 && (attempt & 1) == 1) diff -rub us/pidentd-3.0.18/src/k_linux.c try3/pidentd-3.0.18/src/k_linux.c --- us/pidentd-3.0.18/src/k_linux.c 2003-01-09 01:02:26.000000000 +0200 +++ try3/pidentd-3.0.18/src/k_linux.c 2005-01-22 16:54:45.000000000 +0200 @@ -17,15 +17,28 @@ #include <stdio.h> #include <syslog.h> #include <errno.h> +#include <unistd.h> #include <sys/types.h> #include <sys/param.h> #include <sys/socket.h> #include <netinet/in.h> +#include <netinet/tcp.h> #include <arpa/inet.h> +#include <linux/types.h> +#include <linux/netlink.h> +#include <linux/tcp_diag.h> + #include "pidentd.h" +struct kainfo +{ + int nlfd; + __u32 seq; + FILE *proc_net_tcp; +}; + /* ** Make sure we are running on a supported OS version */ @@ -39,23 +52,85 @@ int ka_open(void **misc) { - FILE *fp; + struct kainfo *kp; + kp = s_malloc(sizeof(*kp)); - while ((fp = fopen("/proc/net/tcp", "r")) == NULL && errno == EINTR) - ; + kp->seq = 0; + kp->nlfd = socket(AF_NETLINK, SOCK_DGRAM, NETLINK_TCPDIAG); + if (kp->nlfd >= 0) + goto out; - if (fp == NULL) + syslog(LOG_INFO, "netlink failed, fallback to /proc/net/tcp: %m"); + kp->proc_net_tcp = fopen("/proc/net/tcp", "r"); + + if (kp->proc_net_tcp == NULL) { syslog(LOG_ERR, "fopen(\"/proc/net/tcp\", \"r\"): %m"); return -1; } - *misc = (void *) fp; +out: + *misc = (void *) kp; return 0; } +static int +netlink_lookup(struct kainfo *kip, struct kernel *kp) +{ + int status; + struct { + struct nlmsghdr nlh; + union { + struct tcpdiagreq req; + struct tcpdiagmsg rsp; + } u; + } buf; + struct sockaddr_nl addr; + + memset(&buf, 0, sizeof(buf)); + buf.nlh.nlmsg_len = NLMSG_ALIGN(NLMSG_LENGTH(sizeof(buf.u.req))); + buf.nlh.nlmsg_type = TCPDIAG_GETSOCK; + buf.nlh.nlmsg_flags = NLM_F_REQUEST; + buf.nlh.nlmsg_seq = ++kip->seq; + buf.u.req.tcpdiag_family = AF_INET; + + buf.u.req.id.tcpdiag_dport = kp->remote.sin_port; + buf.u.req.id.tcpdiag_sport = kp->local.sin_port; + buf.u.req.id.tcpdiag_dst[0] = kp->remote.sin_addr.s_addr; + buf.u.req.id.tcpdiag_src[0] = kp->local.sin_addr.s_addr; + buf.u.req.id.tcpdiag_cookie[0] = TCPDIAG_NOCOOKIE; + buf.u.req.id.tcpdiag_cookie[1] = TCPDIAG_NOCOOKIE; + + status = write(kip->nlfd, &buf, buf.nlh.nlmsg_len); + if (status < 0) { + syslog(LOG_ERR, "netlink_lookup: write failed: %m"); + return 3; + } + + do { + socklen_t alen = sizeof(addr); + status = recvfrom(kip->nlfd, &buf, sizeof(buf), 0, + (void *)&addr, &alen); + if (status < 0) { + if (errno == ENOBUFS) + return -1; + syslog(LOG_ERR, "netlink_lookup: recvfrom failed: %m"); + return 3; + } + } while (addr.nl_pid || buf.nlh.nlmsg_seq != kip->seq); + + if (buf.nlh.nlmsg_type != TCPDIAG_GETSOCK) + return 0; + if (buf.u.rsp.tcpdiag_state != TCP_ESTABLISHED) + return 0; + + kp->euid = buf.u.rsp.tcpdiag_uid; + return 1; +} + + int ka_lookup(void *vp, struct kernel *kp) { @@ -96,21 +171,32 @@ */ unsigned long int ino; + int status; + struct kainfo *kip; + + kip = (struct kainfo *)vp; + kp->ruid = NO_UID; + + if (kip->nlfd >= 0) + return netlink_lookup(kip, kp); + + r_rport = ntohs(kp->remote.sin_port); r_lport = ntohs(kp->local.sin_port); r_raddr = kp->remote.sin_addr.s_addr; r_laddr = kp->local.sin_addr.s_addr; - fp = (FILE *) vp; + fp = kip->proc_net_tcp; + - kp->ruid = NO_UID; rewind(fp); /* eat header */ if (fgets(buf, sizeof(buf)-1,fp) == NULL) return -1; + status =0; while (fgets(buf, sizeof(buf)-1, fp) != NULL) { nra = sscanf(buf, "%d: %lX:%x %lX:%x %x %lX:%lX %x:%lX %lx %d %ld %lu", @@ -122,7 +208,7 @@ if (myladdr == r_laddr && mylport == r_lport && myraddr == r_raddr && myrport == r_rport) { - if (nra >= 14 && euid == 0 && ino == 0) { + if ((nra >= 14 && euid == 0 && ino == 0) || myraddr !=r_raddr || myrport!=r_rport) { /* * Both uid and ino are zero: not even a socket? * Skip (continue), probably fail; or fail (break) @@ -131,11 +217,11 @@ continue; } kp->euid = euid; - return 1; + status=1; } } } - return -1; + return status; }
--- pidentd-3.0.16.orig/src/main.c +++ pidentd-3.0.16/src/main.c @@ -374,7 +377,12 @@ { if (!debug && pidfile_path != NULL) pidfile_create(pidfile_path); - + + if (listen_sock < 0) + { + request_timeout = 0; + } + if (server_init() < 0) { if (debug) --- pidentd-3.0.16.orig/src/server.c +++ pidentd-3.0.16/src/server.c @@ -15,11 +15,14 @@ #include "config.h" #include <syslog.h> +#include <stdio.h> #include <stdlib.h> #include <string.h> #include <sys/time.h> #include <sys/resource.h> #include <errno.h> +#include <unistd.h> +#include <fcntl.h> #include "pidentd.h" @@ -115,10 +118,29 @@ int server_run(void) { + struct pollfd ufds[1]; int fd; - + int timeout = request_timeout <= 0 ? -1 : request_timeout * 1000; + int retval; + + if (fcntl(listen_sock, F_SETFL, O_NONBLOCK) == -1) + { + syslog(LOG_ERR, "fcntl() failed: %m"); + return -1; + } + + ufds[0].fd = listen_sock; + ufds[0].events = POLLIN; while (1) { + if ((retval = s_poll(ufds, 1, timeout)) == -1) + { + syslog(LOG_ERR, "poll() failed: %m"); + return -1; + } + else if (retval == 0) + break; + fd = s_accept(listen_sock, NULL, NULL); if (fd < 0) { @@ -139,4 +161,8 @@ request_run(fd, 0); } + + if (debug) + fprintf(stderr, "accept() timed out\n"); + exit(0); } --- pidentd-3.0.16.orig/src/request.c +++ pidentd-3.0.16/src/request.c @@ -98,6 +98,13 @@ switch (kp->status) { + case 2: + send_error(fd, + local_port, remote_port, + "HIDDEN-USER", + remote_addr); + break; + case 1: send_result(fd, kp); break; @@ -188,8 +195,9 @@ got = s_read(rp->fd, buf+len, sizeof(buf)-len-1); if (got < 0) { - syslog(LOG_ERR, "request_thread: read(%d, ..., %d) failed: %m", - rp->fd, sizeof(buf)-len-1); + if (debug) + fprintf(stderr, "request_thread: read(%d, ..., %d) failed: %s", + rp->fd, sizeof(buf)-len-1, strerror(errno)); goto Exit; } --- pidentd-3.0.16.orig/src/safeio.c +++ pidentd-3.0.16/src/safeio.c @@ -327,3 +327,18 @@ return retcode; } + + + +int +s_poll(struct pollfd *ufds, + unsigned int nfds, + int timeout) +{ + int code; + + while ((code = poll(ufds, nfds, timeout)) == -1 && errno == EINTR) + ; + + return code; +} --- pidentd-3.0.16.orig/src/safeio.h +++ pidentd-3.0.16/src/safeio.h @@ -15,6 +15,8 @@ #ifndef PIDENTD_SAFEIO_H #define PIDENTD_SAFEIO_H +#include <sys/poll.h> + extern void s_abort(void); extern int s_open(const char *path, int oflag, ...); @@ -37,4 +39,5 @@ size_t bufsize, const char *format, ...); +extern int s_poll(struct pollfd *, unsigned int, int); #endif
signature.asc
Description: Digital signature