Segfault after running 'saveconfig' when adding a new user from a python module [$50] #286

Closed
opened 2026-10-05 04:10:10 +02:00 by adam · 4 comments
Owner

ZNC 1.2, Ubuntu 12.04

  1. Run the below python module code
  2. From a connected client, run 'saveconfig'

ZNC now segfaults. Backtrace found below

Python module:

username = "testusername"
password = "testpassword"

if (username == "" or password == ""):
    return znc.CONTINUE

self.PutModule("Creating new user")
salt = znc.CUtils.GetSalt()
hash = znc.CUser.SaltedHash(password, salt)

new_user = znc.CUser(username)
new_user.SetPass(hash, znc.CUser.HASH_DEFAULT, salt)

str_err = znc.String()
if (znc.CZNC.Get().AddUser(new_user, str_err) == False):
    self.PutModule("adduser error [" + str_err.s + "]")
    return znc.CONTINUE

self.PutModule("User added [" + new_user.GetUserName() + ", " + new_user.GetPass() + "]")

Backtrace:

Program received signal SIGSEGV, Segmentation fault.
CUser::IsValid (this=0x555556b11c30, sErrMsg=..., bSkipPass=false) at src/User.cpp:836
836     src/User.cpp: No such file or directory.
(gdb) backtrace
#0  CUser::IsValid (this=0x555556b11c30, sErrMsg=..., bSkipPass=false) at src/User.cpp:836
#1  0x00005555555aba71 in CZNC::WriteConfig (this=0x555555893040) at src/znc.cpp:503
#2  0x00005555556449cc in CClient::UserCommand (this=0x555556b215f0, sLine=...) at src/ClientCommand.cpp:156
#3  0x00005555555e738d in CClient::ReadLine (this=0x555556b215f0, sData=...) at src/Client.cpp:337
#4  0x0000555555591cb2 in Csock::PushBuff (this=0x555556b215f0, data=<optimized out>, len=<optimized out>, bStartAtZero=<optimized out>) at src/Csocket.cpp:1986
#5  0x000055555559beb3 in CSocketManager::Loop (this=0x5555558930c8) at src/Csocket.cpp:2894
#6  0x00005555555983ef in CSocketManager::DynamicSelectLoop (this=0x5555558930c8, iLowerBounds=100000, iUpperBounds=600000000, iMaxResolution=<optimized out>)
    at src/Csocket.cpp:2952
#7  0x00005555555b0ef0 in CZNC::Loop (this=0x555555893040) at src/znc.cpp:213
#8  0x0000555555581c0c in main (argc=2, argv=0x7fffffffe158) at src/main.cpp:352

--- Did you help close this issue? Go claim the **[$50 bounty](https://www.bountysource.com/issues/1376369-segfault-after-running-saveconfig-when-adding-a-new-user-from-a-python-module?utm_campaign=plugin&utm_content=tracker%2F1759&utm_medium=issues&utm_source=github)** on [Bountysource](https://www.bountysource.com/?utm_campaign=plugin&utm_content=tracker%2F1759&utm_medium=issues&utm_source=github).
ZNC 1.2, Ubuntu 12.04 1. Run the below python module code 2. From a connected client, run 'saveconfig' ZNC now segfaults. Backtrace found below Python module: ``` username = "testusername" password = "testpassword" if (username == "" or password == ""): return znc.CONTINUE self.PutModule("Creating new user") salt = znc.CUtils.GetSalt() hash = znc.CUser.SaltedHash(password, salt) new_user = znc.CUser(username) new_user.SetPass(hash, znc.CUser.HASH_DEFAULT, salt) str_err = znc.String() if (znc.CZNC.Get().AddUser(new_user, str_err) == False): self.PutModule("adduser error [" + str_err.s + "]") return znc.CONTINUE self.PutModule("User added [" + new_user.GetUserName() + ", " + new_user.GetPass() + "]") ``` Backtrace: ``` Program received signal SIGSEGV, Segmentation fault. CUser::IsValid (this=0x555556b11c30, sErrMsg=..., bSkipPass=false) at src/User.cpp:836 836 src/User.cpp: No such file or directory. (gdb) backtrace #0 CUser::IsValid (this=0x555556b11c30, sErrMsg=..., bSkipPass=false) at src/User.cpp:836 #1 0x00005555555aba71 in CZNC::WriteConfig (this=0x555555893040) at src/znc.cpp:503 #2 0x00005555556449cc in CClient::UserCommand (this=0x555556b215f0, sLine=...) at src/ClientCommand.cpp:156 #3 0x00005555555e738d in CClient::ReadLine (this=0x555556b215f0, sData=...) at src/Client.cpp:337 #4 0x0000555555591cb2 in Csock::PushBuff (this=0x555556b215f0, data=<optimized out>, len=<optimized out>, bStartAtZero=<optimized out>) at src/Csocket.cpp:1986 #5 0x000055555559beb3 in CSocketManager::Loop (this=0x5555558930c8) at src/Csocket.cpp:2894 #6 0x00005555555983ef in CSocketManager::DynamicSelectLoop (this=0x5555558930c8, iLowerBounds=100000, iUpperBounds=600000000, iMaxResolution=<optimized out>) at src/Csocket.cpp:2952 #7 0x00005555555b0ef0 in CZNC::Loop (this=0x555555893040) at src/znc.cpp:213 #8 0x0000555555581c0c in main (argc=2, argv=0x7fffffffe158) at src/main.cpp:352 ``` ## <bountysource-plugin> --- Did you help close this issue? Go claim the **[$50 bounty](https://www.bountysource.com/issues/1376369-segfault-after-running-saveconfig-when-adding-a-new-user-from-a-python-module?utm_campaign=plugin&utm_content=tracker%2F1759&utm_medium=issues&utm_source=github)** on [Bountysource](https://www.bountysource.com/?utm_campaign=plugin&utm_content=tracker%2F1759&utm_medium=issues&utm_source=github). </bountysource-plugin> <!-- github-sync-id:25507022 -->
adam closed this issue 2026-10-05 04:10:10 +02:00
Author
Owner

For future, bt full shows better backtrace
But in this case, as psychon said on channel, the user gets deleted by modpython when last reference to the python new_user object goes away. The workaround is to store array of such added users somewhere in member of module, so that it will always have a python reference to it. But it will still fail, e.g. when module unloads.
The proper fix would be to add a way to modpython to release ownership of an object.

For future, `bt full` shows better backtrace But in this case, as psychon said on channel, the user gets deleted by modpython when last reference to the python `new_user` object goes away. The workaround is to store array of such added users somewhere in member of module, so that it will always have a python reference to it. But it will still fail, e.g. when module unloads. The proper fix would be to add a way to modpython to release ownership of an object. <!-- github-comment-id:32209823 -->
Author
Owner

I guess it should have been obvious, but the same effect happens with CIRCNetwork objects and presumably any other object types too.

I guess it should have been obvious, but the same effect happens with CIRCNetwork objects and presumably any other object types too. <!-- github-comment-id:32252950 -->
Author
Owner

If you want to release python ownership of a new created object you can set the thisown attribute to 0:

 new_user.thisown = 0

Will prevent SWIG from cleaning up the object and keep it at live.

If you want to release python ownership of a new created object you can set the thisown attribute to 0: ``` new_user.thisown = 0 ``` Will prevent SWIG from cleaning up the object and keep it at live. <!-- github-comment-id:41963762 -->
Author
Owner
Was fixed by https://github.com/znc/znc/commit/a66c6164a7c7085e8fc8b9655fead3ac2affad80. <!-- github-comment-id:122344592 -->
Sign in to join this conversation.
No labels
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: adam/znc#286