Triggered during development of #48383. python ldap attempted this mod:
data; {'nsslapd-directory': ['/opt/dirsrv/var/lib/dirsrv/slapd-localhost/db/userRoot'], 'cn': ['userRoot'], 'objectclass': ['top', 'extensibleObject', 'nsBackendInstance'], 'nsslapd-require-index': ['off'], 'nsslapd-suffix': ['dc=example,dc=com'], 'nsslapd-readonly': ['off'], 'nsslapd-dncachememsize': ['10485760'], 'nsslapd-cachesize': ['-1'], 'nsslapd-cachememsize': ['1']} original data: {'nsslapd-directory': ['/opt/dirsrv/var/lib/dirsrv/slapd-localhost/db/userRoot'], 'cn': ['userRoot'], 'objectclass': ['top', 'extensibleObject', 'nsBackendInstance'], 'nsslapd-require-index': ['off'], 'nsslapd-suffix': ['dc=example,dc=com'], 'nsslapd-readonly': ['off'], 'nsslapd-dncachememsize': ['10485760'], 'nsslapd-cachesize': ['-1'], 'nsslapd-cachememsize': ['10485760']} mod :[(1, 'nsslapd-cachememsize', None), (0, 'nsslapd-cachememsize', ['1'])]
It looks like if you pass a None, or NULL to certain parts of the config modification code you can completely kill Directory Server.
(gdb) bt #0 0x00007fffea0ef396 in ldbm_instance_modify_config_entry_callback (pb=<optimized out>, entryBefore=<optimized out>, e=<optimized out>, returncode=0x7fffdce0c690, returntext=0x7fffdce0c8d0 "", arg=0x602e00006d00) at /home/wibrown/development/389ds/ds/ldap/servers/slapd/back-ldbm/ldbm_instance_config.c:803 #1 0x00007ffff49e05b1 in dse_call_callback (pb=pb@entry=0x7fffdce11a80, operation=operation@entry=8, flags=flags@entry=1, entryBefore=entryBefore@entry=0x60200046fa40, entryAfter=entryAfter@entry=0x60200046f840, returncode=returncode@entry=0x7fffdce0c690, returntext=returntext@entry=0x7fffdce0c8d0 "", pdse=<optimized out>) at /home/wibrown/development/389ds/ds/ldap/servers/slapd/dse.c:2634 #2 0x00007ffff49e4765 in dse_modify (pb=0x7fffdce11a80) at /home/wibrown/development/389ds/ds/ldap/servers/slapd/dse.c:1852 #3 0x00007ffff4a52733 in op_shared_modify (pb=pb@entry=0x7fffdce11a80, pw_change=pw_change@entry=0, old_pw=0x0) at /home/wibrown/development/389ds/ds/ldap/servers/slapd/modify.c:1054 #4 0x00007ffff4a5527e in do_modify (pb=pb@entry=0x7fffdce11a80) at /home/wibrown/development/389ds/ds/ldap/servers/slapd/modify.c:387 #5 0x0000000000426ab3 in connection_dispatch_operation (pb=0x7fffdce11a80, op=0x602e000243a0, conn=0x7fffe0847200) at /home/wibrown/development/389ds/ds/ldap/servers/slapd/connection.c:627 #6 connection_threadmain () at /home/wibrown/development/389ds/ds/ldap/servers/slapd/connection.c:1759 #7 0x00007ffff25477bb in _pt_root (arg=0x6026000670e0) at ../../../nspr/pr/src/pthreads/ptthread.c:212 #8 0x00007ffff4e64a98 in __asan::AsanThread::ThreadStart (this=0x7fffdce14000) at ../../../../libsanitizer/asan/asan_thread.cc:99 #9 0x00007ffff1ee8dc5 in start_thread (arg=0x7fffdce12700) at pthread_create.c:308 #10 0x00007ffff1c1621d in clone () at ../sysdeps/unix/sysv/linux/x86_64/clone.S:113 (gdb) list 798 if (ldbm_config_ignored_attr(attr_name)) { 799 continue; 800 } 801 802 /* This assumes there is only one bval for this mod. */ 803 rc = ldbm_config_set((void *) inst, attr_name, 804 ldbm_instance_config, mods[i]->mod_bvalues[0], returntext, 805 CONFIG_PHASE_RUNNING, apply_mod, mods[i]->mod_op); 806 } 807 } (gdb) (gdb) print *inst $3 = {inst_name = 0x6004002c20b0 "userRoot", inst_be = 0x6022001359a0, inst_li = 0x602800012040, inst_flags = 0, inst_config_mutex = 0x601e00110d40, inst_ref_count = 0x6004002c1fd0, inst_dir_name = 0x6004002c1190 "userRoot", inst_parent_dir_name = 0x60080007f810 "/opt/dirsrv/var/lib/dirsrv/slapd-localhost/db", inst_db_mutex = 0x601e00110e30, inst_handle_head = 0x600600511ae0, inst_handle_tail = 0x600600545110, inst_handle_list_mutex = 0x601e00110f20, inst_id2entry = 0x604a00007580, inst_perf_private = {memory = 0x0}, inst_attrcrypt_state_private = 0x0, attrcrypt_configured = 0, inst_attrs = 0x6006004b4360, inst_cache = {c_maxsize = 10485760, c_cursize = 0x6004002c2090, c_maxentries = -1, c_curentries = 2, c_dntable = 0x7fffe6e3f800, c_idtable = 0x7fffe6e14800, c_hits = 0x6004002c2070, c_tries = 0x6004002c2050, c_lruhead = 0x60100001f5a0, c_lrutail = 0x60100001a320, c_mutex = 0x601e001112e0, c_emutexalloc_mutex = 0x601e001111f0}, inst_nextid_mutex = 0x601e00110c50, inst_nextid = 10, inst_indexer_cv = 0x600c0014e700, inst_indexer_tid = 0x0, inst_cache_hits = 0, inst_cache_misses = 0, inst_dataversion = 0x0, import_env = 0x0, require_index = 0, inst_dncache = { c_maxsize = 10485760, c_cursize = 0x6004002c2030, c_maxentries = -1, c_curentries = 2, c_dntable = 0x0, c_idtable = 0x7fffe6de9800, c_hits = 0x6004002c2010, c_tries = 0x6004002c1ff0, c_lruhead = 0x600c001a9240, c_lrutail = 0x600c00197c00, c_mutex = 0x601e00111100, c_emutexalloc_mutex = 0x601e00111010}} (gdb) print attr_name $2 = 0x60060085ad40 "nsslapd-cachememsize" (gdb) print ldbm_instance_config $4 = {{config_name = 0x7fffea18abe0 "nsslapd-cachesize", config_type = 4, config_default_value = 0x7fffea18ac20 "-1", config_get_fn = 0x7fffea0edb30 <ldbm_instance_config_cachesize_get>, config_set_fn = 0x7fffea0edb00 <ldbm_instance_config_cachesize_set>, config_flags = 7}, {config_name = 0x7fffea18ac60 "nsslapd-cachememsize", config_type = 6, config_default_value = 0x7fffea18aca0 "10485760", config_get_fn = 0x7fffea0ed9b0 <ldbm_instance_config_cachememsize_get>, config_set_fn = 0x7fffea0ee250 <ldbm_instance_config_cachememsize_set>, config_flags = 7}, {config_name = 0x7fffea18ace0 "nsslapd-readonly", config_type = 1, config_default_value = 0x7fffea18ad20 "off", config_get_fn = 0x7fffea0ed870 <ldbm_instance_config_readonly_get>, config_set_fn = 0x7fffea0ed9d0 <ldbm_instance_config_readonly_set>, config_flags = 7}, { config_name = 0x7fffea18ad60 "nsslapd-require-index", config_type = 1, config_default_value = 0x7fffea18ad20 "off", config_get_fn = 0x7fffea0ed8d0 <ldbm_instance_config_require_index_get>, config_set_fn = 0x7fffea0ed910 <ldbm_instance_config_require_index_set>, config_flags = 7}, {config_name = 0x7fffea18ada0 "nsslapd-directory", config_type = 2, config_default_value = 0x0, config_get_fn = 0x7fffea0ee5f0 <ldbm_instance_config_instance_dir_get>, config_set_fn = 0x7fffea0ee3a0 <ldbm_instance_config_instance_dir_set>, config_flags = 3}, {config_name = 0x7fffea18ade0 "nsslapd-dncachememsize", config_type = 6, config_default_value = 0x7fffea18aca0 "10485760", config_get_fn = 0x7fffea0ed990 <ldbm_instance_config_dncachememsize_get>, config_set_fn = 0x7fffea0ee100 <ldbm_instance_config_dncachememsize_set>, config_flags = 7}, {config_name = 0x0, config_type = 0, config_default_value = 0x0, config_get_fn = 0x0, config_set_fn = 0x0, config_flags = 0}} (gdb) print mods[i]->mod_bvalues[0] Cannot access memory at address 0x0 (gdb) print mods[i]->mod_op $1 = 129
This is specifically triggered if you attempt to MOD_DELETE on cachememsize.
Yep, this could easily crash the server. :( $ ldapmodify -D 'cn=directory manager' ... dn: cn=userRoot,cn=ldbm database,cn=plugins,cn=config changetype: modify delete: nsslapd-cachememsize
We certainly need to check mods[i]->mod_bvalues in ldbm_instance_modify_config_entry_callback... A nice finding!!
Comment by William:
I think the bigger concern would be other values that cause this to crash .... Should this cause us to write a "chaos-monkey" style tester that just deletes and trashes a DS install to see what it shakes out?
I agree. I would think backend config parameters cause the crash...
(Frontend ones are tested and supposed to fall back to the init value.)
attachment 0001-Ticket-48665-Prevent-sefault-in-ldbm_instance_modify.patch
Add extra test case. 0001-Ticket-48665-Prevent-sefault-in-ldbm_instance_modify.2.patch
Relies on https://fedorahosted.org/389/attachment/ticket/48663/0001-Ticket-48663-Implement-get-and-set-properties-for-ba.2.patch for the extra test case.
Your fix looks good to me. But could you give us some more details about the "real fix" in this comment? 804 / This avoids the null pointer deref, but the real 805 * fix is in ldbm_config.c ldbm_config_set. This is where 806 * we check to make sure we aren't doing bad things with 807 * null values 808 /
I left the comment there thinking I would need to alter ldbm_config_set, turns out it already protected from NULL in mod[i]->bvalues. So I can clean up that comment.
commit 3c402a56982ca63595d4a2afca599926a279a791
Total 11 (delta 8), reused 0 (delta 0) To ssh://git.fedorahosted.org/git/389/ds.git 415d855..9134b00 master -> master
Backport to 1.3.4 and 1.2.11
e6ba96d..2dd62a7 389-ds-base-1.3.4 -> 389-ds-base-1.3.4 commit 2dd62a7
7930571..fa54d0c 389-ds-base-1.2.11 -> 389-ds-base-1.2.11 commit fa54d0c Author: William Brown firstyear@redhat.com Date: Wed Mar 9 14:00:42 2016 +1000
attachment 0001-Ticket-48665-Fix-RHEL6-test-compatibility-issues.patch
To ssh://git.fedorahosted.org/git/389/ds.git 8a99552..9feca58 master -> master commit 9feca58 Author: Simon Pichugin spichugi@redhat.com Date: Tue Jan 10 13:55:30 2017 +0100
Metadata Update from @firstyear: - Issue assigned to firstyear - Issue set to the milestone: 1.2.11.33
389-ds-base is moving from Pagure to Github. This means that new issues and pull requests will be accepted only in 389-ds-base's github repository.
This issue has been cloned to Github and is available here: - https://github.com/389ds/389-ds-base/issues/1794
If you want to receive further updates on the issue, please navigate to the github issue and click on subscribe button.
subscribe
Thank you for understanding. We apologize for all inconvenience.
Metadata Update from @spichugi: - Issue close_status updated to: wontfix (was: Fixed)
Login to comment on this ticket.