linux-nfs.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Matthias Gerstner <matthias.gerstner@nefkom.net>
To: linux-nfs@vger.kernel.org
Subject: nfs-utils: rpc.svcgssd segmentation fault in nss_gss_princ_to_ids()
Date: Tue, 20 Feb 2018 23:48:58 +0100	[thread overview]
Message-ID: <20180220224858.GA14972@q910.gerrit.home> (raw)


[-- Attachment #1.1: Type: text/plain, Size: 4162 bytes --]

Hello!

I hope I have found the right place to report this.

I have recently upgraded from nfs-utils-1.3.4 to nfs-utils-2.3.1 on a Gentoo
Linux (hardened) system. After this upgrade the rpc.svcgssd crashes on my
kerberized NFS server each time a client tries to mount an NFS export.

The crash is a segmentation fault:

  kernel: rpc.svcgssd[19772]: segfault at 8 ip 00007f6b6aafa98c sp 00007fff2ca8ce30 error 4 in nsswitch.so[7f6b6aaf9000+7000]

The call stack leading up to this looks as follows:

  (gdb) 
  Program received signal SIGSEGV, Segmentation fault.
  nss_gss_princ_to_ids (secname=<optimized out>, princ=0x55cabc7d9940 "nfs/host.example.domain@EXAMPLE.HOME", 
      uid=0x7ffca550e0d8, gid=0x7ffca550e0dc, UNUSED_ex=<optimized out>) at nss.c:415
  415	nss.c: No such file or directory.

  (gdb) bt
  #0  nss_gss_princ_to_ids (secname=<optimized out>, princ=0x55cabc7d9940 "nfs/host.example.domain@EXAMPLE.HOME", 
      uid=0x7ffca550e0d8, gid=0x7ffca550e0dc, UNUSED_ex=<optimized out>) at nss.c:415
  #1  0x00007f6c97cc2886 in nfs4_gss_princ_to_ids (secname=secname@entry=0x55caba8e2030 <m2f+16> "krb5", 
      princ=princ@entry=0x55cabc7d9940 "nfs/host.example.domain@EXAMPLE.HOME", uid=0x7ffca550e0d8, uid@entry=0x1, 
      gid=0x7ffca550e0dc, gid@entry=0x7f6c95cf3a76 <conf_get_section+86>) at libnfsidmap.c:682
  #2  0x000055caba6da138 in get_ids (cred=0x7ffca550e038, mech=<optimized out>, client_name=<optimized out>)
      at svcgssd_proc.c:251
  #3  handle_nullreq (f=f@entry=3) at svcgssd_proc.c:407
  #4  0x000055caba6d996a in gssd_run () at svcgssd_main_loop.c:91
  #5  0x000055caba6d83b1 in main (argc=1, argv=<optimized out>) at svcgssd.c:211

  (gdb) p realms
  $1 = (struct conf_list *) 0x0

I debugged this a bit and strange things came about. There seem to be
duplicate instances of the local_realms variable in the
support/nfsidmap/nfsidmap_common.c compilation unit:

  gdb --args /usr/sbin/rpc.svcgssd  -f
  (gdb) start
  Temporary breakpoint 1 at 0x2170: file svcgssd.c, line 94.
  Starting program: /usr/sbin/rpc.svcgssd -f
  Temporary breakpoint 1, main (argc=2, argv=0x7fffffffddc8) at svcgssd.c:94
  94	svcgssd.c: No such file or directory.

  (gdb) b get_local_realms 
  Breakpoint 2 at 0x7ffff7bd1fc0: file nfsidmap_common.c, line 30.
  (gdb) c
  Continuing.

  Breakpoint 2, get_local_realms () at nfsidmap_common.c:30
  30	nfsidmap_common.c: No such file or directory.
  (gdb) disassemble 
  Dump of assembler code for function get_local_realms:
  => 0x00007ffff5e0b4a0 <+0>:	sub    $0x1038,%rsp
     0x00007ffff5e0b4a7 <+7>:	orq    $0x0,(%rsp)
     0x00007ffff5e0b4ac <+12>:	add    $0x1020,%rsp
     0x00007ffff5e0b4b3 <+19>:	mov    %fs:0x28,%rax
     0x00007ffff5e0b4bc <+28>:	mov    %rax,0x8(%rsp)
     0x00007ffff5e0b4c1 <+33>:	xor    %eax,%eax
     0x00007ffff5e0b4c3 <+35>:	mov    0x204f7e(%rip),%rax        # 0x7ffff6010448 <local_realms>
     0x00007ffff5e0b4ca <+42>:	mov    0x8(%rsp),%rdx
     0x00007ffff5e0b4cf <+47>:	xor    %fs:0x28,%rdx
     0x00007ffff5e0b4d8 <+56>:	jne    0x7ffff5e0b4df <get_local_realms+63>
     0x00007ffff5e0b4da <+58>:	add    $0x18,%rsp
     0x00007ffff5e0b4de <+62>:	retq   
     0x00007ffff5e0b4df <+63>:	callq  0x7ffff5e0a250 <__stack_chk_fail@plt>

  End of assembler dump.

  (gdb) p local_realms
  $1 = (struct conf_list *) 0x555555764300
  (gdb) p &local_realms
  $2 = (struct conf_list **) 0x7ffff7dd7208 <local_realms>

  (gdb) x /1g 0x7ffff6010448
  0x7ffff6010448 <local_realms>:	0x0000000000000000

So there's one instance of the variable that was actually assigned the
expected data. And there's another one that is at NULL and returned from
get_local_realms().

This is related to the "#pragma GCC visibility push(hidden)" in the
compilation unit. Moving it after the local_realms variable declaration fixes
the issue. I've attached a patch that does just this.

I am not quite sure whether this is a compiler issue or an invalid use of the
visibility hidden pragma. The compiler used is:

  gcc (Gentoo Hardened 6.4.0-r1 p1.3) 6.4.0

Please advise.

Regards

Matthias

[-- Attachment #1.2: local_realms_segfault.patch --]
[-- Type: text/x-diff, Size: 1109 bytes --]

commit b1935a982aa68890ffe888381f7905f57c6b055d
Author: Matthias Gerstner <Matthias.Gerstner@nefkom.net>
Date:   Tue Feb 20 23:33:18 2018 +0100

    get_local_realms: work around strange duplication of local_realms
    
    The hidden visibility seems to cause the get_local_realms() function to
    return a NULL pointer, although the local_realms global variable is
    actually assigned. Assembler code shows there are two instances of this
    variable around, one set to NULL, the other to the expected value.
    
    This happened on Gentoo Hardened with gcc 4.6.0-r1.

diff --git a/support/nfsidmap/nfsidmap_common.c b/support/nfsidmap/nfsidmap_common.c
index 891c855..e5c33a8 100644
--- a/support/nfsidmap/nfsidmap_common.c
+++ b/support/nfsidmap/nfsidmap_common.c
@@ -19,13 +19,13 @@
 #include "nfsidmap_plugin.h"
 #include "conffile.h"
 
-#pragma GCC visibility push(hidden)
-
 int reformat_group = 0;
 int no_strip = 0;
 
 struct conf_list *local_realms;
 
+#pragma GCC visibility push(hidden)
+
 struct conf_list *get_local_realms(void)
 {
 	return local_realms;

[-- Attachment #2: Digital signature --]
[-- Type: application/pgp-signature, Size: 833 bytes --]

             reply	other threads:[~2018-02-20 22:49 UTC|newest]

Thread overview: 6+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2018-02-20 22:48 Matthias Gerstner [this message]
2018-02-21 16:08 ` nfs-utils: rpc.svcgssd segmentation fault in nss_gss_princ_to_ids() Steve Dickson
2018-02-22  8:17   ` Matthias Gerstner
2018-02-21 16:49 ` Justin Mitchell
2018-02-22  8:18   ` Matthias Gerstner
2018-02-22 23:10   ` matthias.gerstner

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20180220224858.GA14972@q910.gerrit.home \
    --to=matthias.gerstner@nefkom.net \
    --cc=linux-nfs@vger.kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).