Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

IsClientAuthorized() memory leak #87

Closed
deynekoaa opened this issue Oct 17, 2020 · 10 comments
Closed

IsClientAuthorized() memory leak #87

deynekoaa opened this issue Oct 17, 2020 · 10 comments
Assignees
Labels

Comments

@deynekoaa
Copy link

OS:

  • centos 8
  • fedora 32

How to reproduce leaks:

  1. start pcscd: /usr/sbin/pcscd --foreground --auto-exit
  2. start pkcs11_eventmgr (from pam_pkcs11): pkcs11_eventmgr nodaemon debug

valgrind output:

==114799== 24 bytes in 1 blocks are still reachable in loss record 361 of 1,071
==114799==    at 0x483CCE8: realloc (vg_replace_malloc.c:834)
==114799==    by 0x4A18A0F: g_realloc (gmem.c:167)
==114799==    by 0x498B882: g_bsearch_array_grow (gbsearcharray.h:212)
==114799==    by 0x498B882: g_bsearch_array_insert (gbsearcharray.h:227)
==114799==    by 0x498BAA3: signal_add_class_closure (gsignal.c:1652)
==114799==    by 0x498EF94: g_signal_newv (gsignal.c:1883)
==114799==    by 0x498F848: g_signal_new_valist (gsignal.c:1987)
==114799==    by 0x498F934: g_signal_new (gsignal.c:1516)
==114799==    by 0x4F9A34C: g_dbus_proxy_class_init (gdbusproxy.c:591)
==114799==    by 0x4F9A34C: g_dbus_proxy_class_intern_init (gdbusproxy.c:175)
==114799==    by 0x4998528: type_class_init_Wm (gtype.c:2235)
==114799==    by 0x4998528: g_type_class_ref (gtype.c:2950)
==114799==    by 0x4F9CDA8: ensure_type (gdbusprivate.c:222)
==114799==    by 0x4F9CDA8: ensure_required_types (gdbusprivate.c:256)
==114799==    by 0x4F9CDA8: _g_dbus_initialize.part.0 (gdbusprivate.c:1972)
==114799==    by 0x4F9B764: g_dbus_proxy_new_for_bus_sync (gdbusproxy.c:2210)
==114799==    by 0x4950939: polkit_authority_initable_init (polkitauthority.c:317)
==114799==    by 0x4951ECA: polkit_authority_get_sync (polkitauthority.c:567)
==114799==    by 0x10CEDB: IsClientAuthorized (auth.c:83)
==114799==    by 0x11C159: ContextThread (winscard_svc.c:333)
==114799==    by 0x4AFD431: start_thread (pthread_create.c:477)
==114799==    by 0x4C17912: clone (clone.S:95)

ps output:

# while true; do ps aux | grep pcscd | grep -v grep; sleep 2; done
root       47830  0.0  0.0  27868  5480 ?        Ssl  20:19   0:00 /usr/sbin/pcscd --foreground --auto-exit
root       47830  0.0  0.0  27868  5480 ?        Ssl  20:19   0:00 /usr/sbin/pcscd --foreground --auto-exit
root       47830  0.0  0.0  27868  5480 ?        Ssl  20:19   0:00 /usr/sbin/pcscd --foreground --auto-exit
root       47830  0.0  0.0  27868  5480 ?        Ssl  20:19   0:00 /usr/sbin/pcscd --foreground --auto-exit
root       47830  0.0  0.0  27868  5480 ?        Ssl  20:19   0:00 /usr/sbin/pcscd --foreground --auto-exit
root       47830  0.4  0.0 331020  6912 ?        Ssl  20:19   0:00 /usr/sbin/pcscd --foreground --auto-exit
root       47830  0.3  0.0 331020  6960 ?        Ssl  20:19   0:00 /usr/sbin/pcscd --foreground --auto-exit
root       47830  0.3  0.0 331020  6968 ?        Ssl  20:19   0:00 /usr/sbin/pcscd --foreground --auto-exit
root       47830  0.3  0.0 331020  6972 ?        Ssl  20:19   0:00 /usr/sbin/pcscd --foreground --auto-exit
root       47830  0.3  0.0 331020  6980 ?        Ssl  20:19   0:00 /usr/sbin/pcscd --foreground --auto-exit
root       47830  0.3  0.0 331020  6984 ?        Ssl  20:19   0:00 /usr/sbin/pcscd --foreground --auto-exit
root       47830  0.3  0.0 331020  6988 ?        Ssl  20:19   0:00 /usr/sbin/pcscd --foreground --auto-exit
root       47830  0.2  0.0 331020  6992 ?        Ssl  20:19   0:00 /usr/sbin/pcscd --foreground --auto-exit
root       47830  0.2  0.0 331020  7000 ?        Ssl  20:19   0:00 /usr/sbin/pcscd --foreground --auto-exit
root       47830  0.3  0.0 331020  7000 ?        Ssl  20:19   0:00 /usr/sbin/pcscd --foreground --auto-exit
root       47830  0.3  0.0 331020  7004 ?        Ssl  20:19   0:00 /usr/sbin/pcscd --foreground --auto-exit
root       47830  0.2  0.0 331020  7012 ?        Ssl  20:19   0:00 /usr/sbin/pcscd --foreground --auto-exit
root       47830  0.3  0.0 331020  7020 ?        Ssl  20:19   0:00 /usr/sbin/pcscd --foreground --auto-exit
root       47830  0.3  0.0 331020  7028 ?        Ssl  20:19   0:00 /usr/sbin/pcscd --foreground --auto-exit
root       47830  0.3  0.0 331020  7032 ?        Ssl  20:19   0:00 /usr/sbin/pcscd --foreground --auto-exit
...
@LudovicRousseau
Copy link
Owner

It is a problem with polkit. I do not use this feature but it is enabled on RedHat and derivatives.

According to the polkit_authority_get_sync() documentation https://www.freedesktop.org/software/polkit/docs/latest/PolkitAuthority.html#polkit-authority-get-sync

Returns
A PolkitAuthority. Free it with g_object_unref() when done with it.

This is what my code is doing in https://github.com/LudovicRousseau/PCSC/blob/master/src/auth.c#L149

So maybe the problem is in polkit and not pcsclite.

Can you try to check if the memory allocated by polkit_authority_get_sync() is correctly un-allocated by g_object_unref()?

@deynekoaa
Copy link
Author

Thanks for your reply and help. Can you explain, how can I do it?
I know only one solution: run gdb, set brackpoints over g_object_unref() and go deper in function. But, may be, there are a better solution?

@LudovicRousseau
Copy link
Owner

I was thinking about a code that would do:

while (1)
{
  p = polkit_authority_get_sync(NULL, NULL);
  g_object_unref(p);
}

and watch if you have a memory leak.

That could indicate the problem is within polkit and not with pcsc-lite.

@deynekoaa
Copy link
Author

tpol.c

#include <polkit/polkit.h>

int main(int argc, char *argv[])
{
  while (1)
  {
    PolkitAuthority *pa = NULL;
    pa = polkit_authority_get_sync(NULL, NULL);
    g_object_unref(pa);
  }
  return 0;
}

compile options:

gcc -g `pkg-config --cflags glib-2.0 polkit-gobject-1` -o tpolkit tpol.c `pkg-config --libs glib-2.0 polkit-gobject-1`

result:

# while true; do ps aux | grep tpolkit | grep -v grep; sleep 1; done
root        1775 62.0  0.0 160232  7716 pts/1    Sl+  12:33   0:02 ./tpolkit
root        1775 66.4  0.0 160616  8140 pts/1    Sl+  12:33   0:03 ./tpolkit
root        1775 69.3  0.1 161296  8704 pts/1    Rl+  12:33   0:04 ./tpolkit
root        1775 71.2  0.1 161680  9284 pts/1    Sl+  12:33   0:04 ./tpolkit
root        1775 72.3  0.1 162192  9884 pts/1    Rl+  12:33   0:05 ./tpolkit
root        1775 74.2  0.1 162700 10448 pts/1    Rl+  12:33   0:06 ./tpolkit
root        1775 75.3  0.1 163208 11016 pts/1    Sl+  12:33   0:07 ./tpolkit
root        1775 76.0  0.1 163860 11684 pts/1    Sl+  12:33   0:08 ./tpolkit
root        1775 76.7  0.1 164372 12292 pts/1    Rl+  12:33   0:09 ./tpolkit
root        1775 77.6  0.1 164884 12860 pts/1    Rl+  12:33   0:10 ./tpolkit
root        1775 78.2  0.1 165396 13424 pts/1    Sl+  12:33   0:10 ./tpolkit
root        1775 78.7  0.1 165908 13836 pts/1    Rl+  12:33   0:11 ./tpolkit
root        1775 79.3  0.1 166416 14784 pts/1    Sl+  12:33   0:12 ./tpolkit
root        1775 79.7  0.1 166932 15352 pts/1    Sl+  12:33   0:13 ./tpolkit
root        1775 80.0  0.1 167444 15912 pts/1    Rl+  12:33   0:14 ./tpolkit

valgrind crashes with segfault: # valgrind --track-origins=yes --verbose --log-file=valgrind-out.txt ./tpolkit

@deynekoaa
Copy link
Author

Hm, but if I add sleep(1), all will be good:

#include <polkit/polkit.h>

int main(int argc, char *argv[])
{
  while (1)
  {
    PolkitAuthority *pa = NULL;
    pa = polkit_authority_get_sync(NULL, NULL);
    g_object_unref(pa);
    sleep(1);
  }
  return 0;
}

output:

# while true; do ps aux | grep tpolkit | grep -v grep; sleep 1; done
root        2058  0.0  0.0 158548  6212 pts/1    Sl+  12:48   0:00 ./tpolkit
...
root        2058  0.0  0.0 158548  6212 pts/1    Sl+  12:48   0:00 ./tpolkit

Magic...

@LudovicRousseau
Copy link
Owner

Very strange.
Does the sleep(1) hack also solves the problem with pcsc-lite?

@LudovicRousseau
Copy link
Owner

I think you should report the problem to polkit.
Maybe they can explain the effect of the sleep(1).

@deynekoaa
Copy link
Author

After some tests, memory leak repeated.
Then, I try to run throw valgrind

#include <polkit/polkit.h>

int main(int argc, char *argv[])
{
  int i;
  for (i = 0; i < 60; i++)
  {
    PolkitAuthority *pa = NULL;
    pa = polkit_authority_get_sync(NULL, NULL);
    g_object_unref(pa);
    sleep(1);
  }
  return 0;
}

And result was:

==2765== LEAK SUMMARY:
==2765==    definitely lost: 0 bytes in 0 blocks
==2765==    indirectly lost: 0 bytes in 0 blocks
==2765==      possibly lost: 2,416 bytes in 26 blocks
==2765==    still reachable: 141,686 bytes in 2,154 blocks
==2765==                       of which reachable via heuristic:
==2765==                         length64           : 832 bytes in 16 blocks
==2765==                         newarray           : 1,728 bytes in 28 blocks
==2765==         suppressed: 0 bytes in 0 blocks
==2765==
==2765== ERROR SUMMARY: 26 errors from 26 contexts (suppressed: 0 from 0)

@deynekoaa
Copy link
Author

I open issue to polkit: https://gitlab.freedesktop.org/polkit/polkit/-/issues/130
Thanks for help!

@LudovicRousseau
Copy link
Owner

The problem is not in pcsc-lite.
Closing.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

2 participants