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

Attachment: signature.asc
Description: Digital signature

Reply via email to