getifaddrs/netlink problem

classic Classic list List threaded Threaded
2 messages Options
Reply | Threaded
Open this post in threaded view
|

getifaddrs/netlink problem

Miroslav Ruda
Hi,

  when testing heimdal-0.7pre3, we have found problem with getifaddrs()
implementation from lib/roken (on linux. debian stable, but it should be general
linux problem). Program, which was doing krb5_get_in_tkt_with_keytab()
repeatedly, sometimes froze in netlink functions (when reading list of
interfaces). From man 7 netlink I have found that at least on my linux:

  Netlink is not a reliable protocol.  It tries its  best  to  deliver  a
message  to  its  destination(s),  but may drop messages when an out of memory
condition or other error  occurs.

See attached trace from gdb - it looks like some netlink message was really
lost. Suggested solution would be not use blocking recvmsg() but select()
with timeout and repeat nl_sendreq() in case of problems...


My second question is about krb5_get_in_tkt_with_keytab() function. We have
no-addresses = yes in krb5.conf, so I would expect that getifaddrs() is not
needed to call. However, it's not clear to me how I should set parameter "addrs"
to avoid detection of IP addresses etc. Or is it really needed when doing
as_req?

--
                   Mirek Ruda

#0  0x40224892 in recvmsg () from /lib/libc.so.6
#1  0x080ad163 in nl_recvmsg (sd=5, request=18, seq=1117986903, buf=0x8111e8
     buflen=65536, flags=0xbfffb3f8) at ../../../lib/roken/getifaddrs.c:304
#2  0x080ad1d7 in nl_getmsg (sd=5, request=18, seq=1117986903,
     nlhp=0xbfffb444, done=0xbfffb448) at ../../../lib/roken/getifaddrs.c:331
#3  0x080ad351 in nl_getlist (sd=5, seq=1117986903, request=18,
     nlm_list=0xbfffb4f4, nlm_end=0xbfffb4f8)
     at ../../../lib/roken/getifaddrs.c:387
#4  0x080ad57e in getifaddrs (ifap=0xbfffb568)
     at ../../../lib/roken/getifaddrs.c:500
#5  0x08095446 in find_all_addresses (context=0x80ef118, res=0x80f1b60,
     flags=14) at ../../../lib/krb5/get_addrs.c:109
#6  0x08095796 in get_addrs_int (context=0x80ef118, res=0x80f1b60, flags=14)
     at ../../../lib/krb5/get_addrs.c:233
#7  0x08095866 in krb5_get_all_client_addrs (context=0x80ef118, res=0x80f1b6
     at ../../../lib/krb5/get_addrs.c:279
#8  0x08085723 in init_as_req (context=0x80ef118, opts=
       {b = {reserved = 0, forwardable = 1, forwarded = 0, proxiable = 0, pro
  0, allow_postdate = 0, postdated = 0, unused7 = 0, renewable = 0, unused9 =
unused10 = 0, unused11 = 0, request_anonymous = 0, canonicalize = 0, disable
nsited_check = 0, renewable_ok = 0, enc_tkt_in_skey = 0, renew = 0, validate
}, i = 3220701186}, creds=0xbfffb964, addrs=0x0, etypes=0x0,
     ptypes=0xbfffb948, preauth=0x0, key_proc=0x8086070 <krb5_keytab_key_proc
     keyseed=0xbfffb8d4, nonce=683628812, a=0xbfffb7dc)
     at ../../../lib/krb5/get_in_tkt.c:500
#9  0x08085b52 in krb5_get_in_cred (context=0x80ef118, options=3220701186,
     addrs=0x0, etypes=0x0, ptypes=0xbfffb948, preauth=0x0,
     key_proc=0x8086070 <krb5_keytab_key_proc>, keyseed=0xbfffb8d4,
     decrypt_proc=0, decryptarg=0x0, creds=0xbfffb964, ret_as_reply=0x0)
     at ../../../lib/krb5/get_in_tkt.c:664
#10 0x08086041 in krb5_get_in_tkt (context=0x80ef118, options=2, addrs=0x0,
     etypes=0x0, ptypes=0xbfffb948, key_proc=0x8086070 <krb5_keytab_key_proc>
     keyseed=0xbfffb8d4, decrypt_proc=0, decryptarg=0x0, creds=0xbfffb964,
     ccache=0x80f1b08, ret_as_reply=0x0) at ../../../lib/krb5/get_in_tkt.c:80
#11 0x0808614a in krb5_get_in_tkt_with_keytab (context=0x80ef118, options=2,
     addrs=0x0, etypes=0x0, pre_auth_types=0xbfffb948, keytab=0x0,
     ccache=0x80f1b08, creds=0xbfffb964, ret_as_reply=0x0)
     at ../../../lib/krb5/get_in_tkt_with_keytab.c:87
Reply | Threaded
Open this post in threaded view
|

Re: getifaddrs/netlink problem

Love Hörnquist Åstrand

Miroslav Ruda <[hidden email]> writes:

> Hi,
>
>   when testing heimdal-0.7pre3, we have found problem with
> getifaddrs() implementation from lib/roken (on linux. debian stable,
> but it should be general linux problem). Program, which was doing
> krb5_get_in_tkt_with_keytab() repeatedly, sometimes froze in netlink
> functions (when reading list of interfaces). From man 7 netlink I have
> found that at least on my linux:
>
>   Netlink is not a reliable protocol.  It tries its  best  to  deliver
> a message  to  its  destination(s),  but may drop messages when an out
> of memory condition or other error  occurs.
>
> See attached trace from gdb - it looks like some netlink message was
> really lost. Suggested solution would be not use blocking recvmsg()
> but select()
> with timeout and repeat nl_sendreq() in case of problems...
I couldn't reproduce the problem so can you test the patch below ?

> My second question is about krb5_get_in_tkt_with_keytab() function. We have
> no-addresses = yes in krb5.conf, so I would expect that getifaddrs()
> is not needed to call. However, it's not clear to me how I should set
> parameter "addrs"
> to avoid detection of IP addresses etc. Or is it really needed when doing
> as_req?

Its a bug in krb5_get_in_tkt_with_keytab. First krb5_get_in_tkt is
deprecated, you should use krb5_get_init_creds. If we are going to keep
get_in_tkt they should be rewritten in terms of krb5_get_init_creds.

Love

diff -u -u -w -r1.11 lib/roken/getifaddrs.c
--- lib/roken/getifaddrs.c 30 Apr 2005 15:45:47 -0000 1.11
+++ lib/roken/getifaddrs.c 11 Jun 2005 18:03:55 -0000
@@ -108,6 +108,7 @@
 #include <linux/rtnetlink.h>
 #include <sys/types.h>
 #include <sys/socket.h>
+#include <sys/poll.h>
 #include <netpacket/packet.h>
 #include <net/ethernet.h>     /* the L2 protocols */
 #include <sys/uio.h>
@@ -378,13 +379,30 @@
   struct nlmsghdr *nlh = NULL;
   int status;
   int done = 0;
+  int tries = 3;
 
+ try_again:
   status = nl_sendreq(sd, request, NLM_F_ROOT|NLM_F_MATCH, &seq);
   if (status < 0)
     return status;
   if (seq == 0)
     seq = (int)time(NULL);
   while(!done){
+    struct pollfd pfd;
+
+    pfd.fd = sd;
+    pfd.events = POLLIN | POLLPRI;
+    pfd.revents = 0;
+    status = poll(&pfd, 1, 1000);
+    if (status < 0)
+ return status;
+    else if (status == 0) {
+ seq++;
+ if (tries-- > 0)
+    goto try_again;
+ return -1;
+    }
+
     status = nl_getmsg(sd, request, seq, &nlh, &done);
     if (status < 0)
       return status;

attachment0 (487 bytes) Download Attachment