Bug 629640
Summary: | Wrong open file flags result in wrong behaviour when opening un-existed file for reading | ||||||
---|---|---|---|---|---|---|---|
Product: | Red Hat Enterprise Linux 6 | Reporter: | Jim Meyering <meyering> | ||||
Component: | gdbm | Assignee: | Marek Skalický <mskalick> | ||||
Status: | CLOSED ERRATA | QA Contact: | Robin Hack <rhack> | ||||
Severity: | medium | Docs Contact: | |||||
Priority: | low | ||||||
Version: | 6.1 | CC: | cww, databases-maint, dowdle, hhorak, mskalick, olchansk, ovasik, pasteur, ppisar, psklenar, rhack, rmj | ||||
Target Milestone: | rc | Keywords: | Patch | ||||
Target Release: | --- | ||||||
Hardware: | All | ||||||
OS: | Linux | ||||||
Whiteboard: | |||||||
Fixed In Version: | gdbm-1.8.0-37.el6 | Doc Type: | Bug Fix | ||||
Doc Text: |
Cause: Wrong open file flags.
Consequence: Result in wrong behaviour when opening un-existed file for reading.
Fix: Fixed file flags.
Result: Opening un-existed file for reading does not create file.
|
Story Points: | --- | ||||
Clone Of: | Environment: | ||||||
Last Closed: | 2015-01-05 08:20:43 UTC | Type: | --- | ||||
Regression: | --- | Mount Type: | --- | ||||
Documentation: | --- | CRM: | |||||
Verified Versions: | Category: | --- | |||||
oVirt Team: | --- | RHEL 7.3 requirements from Atomic Host: | |||||
Cloudforms Team: | --- | Target Upstream Version: | |||||
Embargoed: | |||||||
Bug Depends On: | |||||||
Bug Blocks: | 1075802 | ||||||
Attachments: |
|
Description
Jim Meyering
2010-09-02 14:53:38 UTC
Yes, with gdbm 1.8.3 it works as expected, and with gdmb 1.8.0 it does not. Most flaws fixed in 1.8.3 are also fixed in our 1.8.0, and the diff between our 1.8.0 and 1.8.3 is surprisingly small. Unfortunately this particular bug remains unfixed. This request was evaluated by Red Hat Product Management for inclusion in the current release of Red Hat Enterprise Linux. Because the affected component is not scheduled to be updated in the current release, Red Hat is unfortunately unable to address this request at this time. Red Hat invites you to ask your support representative to propose this request, if appropriate and relevant, in the next release of Red Hat Enterprise Linux. If you would like it considered as an exception in the current release, please ask your support representative. This request was evaluated by Red Hat Product Management for inclusion in the current release of Red Hat Enterprise Linux. Because the affected component is not scheduled to be updated in the current release, Red Hat is unfortunately unable to address this request at this time. Red Hat invites you to ask your support representative to propose this request, if appropriate and relevant, in the next release of Red Hat Enterprise Linux. If you would like it considered as an exception in the current release, please ask your support representative. Created attachment 591139 [details]
proposed patch used in gdbm-1.8.3
This fix is used in gdbm-1.8.3 and works on the reproducer above.
Related changelog comment:
* gdbmopen.c: Fix typo; s/GDBM_OPENMASK/GDBM_WRITER/.
Updating Bug summary, since we will rather fix the particular bug instead of rebasing. Steps to Reproduce: 1. Here's a quick test to demonstrate the problem: ruby -e 'require "gdbm"; gdbm = GDBM.open("x", nil); print gdbm' Actual results: prints a non-nil value and creates a file named "x" Expected results: prints "nil" and does *not* create any file Since the problem described in this bug report should be resolved in a recent advisory, it has been closed with a resolution of ERRATA. For information on the advisory, and where to find the updated files, follow the link below. If the solution does not work for you, open a new bug report. https://rhn.redhat.com/errata/RHBA-2015-0005.html This change breaks perl test suite. (In reply to Petr Pisar from comment #25) > This change breaks perl test suite. Can you be more specific? (In reply to Honza Horak from comment #26) > (In reply to Petr Pisar from comment #25) > > This change breaks perl test suite. > > Can you be more specific? I have not yet investigated it. Rebuilding perl fails with gdbm-1.8.0-37.el6 on x86_64 only. It passes with gdbm-1.8.0-36.el6. (In reply to Petr Pisar from comment #27) > I have not yet investigated it. Rebuilding perl fails with gdbm-1.8.0-37.el6 > on x86_64 only. It passes with gdbm-1.8.0-36.el6. Please, give us know as soon as you find out more. Thanks. This Perl code changed behaviour: $ cat gdbmfix #!/usr/bin/perl use strict; use warnings; use GDBM_File; unlink <Op.dbmx*>; my %h; tie(%h, 'GDBM_File', 'Op.dbmx', &GDBM_WRCREAT, 0640) or die "Initialization failed"; $h{'goner1'} = 'snork'; untie(%h); $ ./gdbmfix gdbm store returned -1, errno 0, key "goner1" at ./gdbmfix line 10. The failed line 10 is the "$h{'goner1'} = 'snork';" line. I debugged the gdbm library and the -1 comes from this check at the very beginning of gdbm_store(): /* First check to make sure this guy is a writer. */ if (dbf->read_write != GDBM_WRITER) { gdbm_errno = GDBM_READER_CANT_STORE; return -1; } Debugger show that the dbf->read_write holds value 2 while GDBM_WRITER macro is declared as 1. It looks like the gdbm_open() does not set the database handle is opened for writing: When calling gdbm_open(): Breakpoint 1, gdbm_open (file=0x63f1f0 "Op.dbmx", block_size=0, flags=2, mode=416, fatal_func=0x7ffff7d25420 <Perl_croak_nocontext>) at gdbmopen.c:76 When leaving the gdbm_open(): Breakpoint 2, gdbm_open (file=0x63f1f0 "Op.dbmx", block_size=0, flags=2, mode=416, fatal_func=0x7ffff7d25420 <Perl_croak_nocontext>) at gdbmopen.c:398 398 return dbf; (gdb) p *dbf $6 = {name = 0x62d090 "Op.dbmx", read_write = 2, fast_write = 1, central_free = 0, coalesce_blocks = 0, file_locking = 1, fatal_err = 0x7ffff7d25420 <Perl_croak_nocontext>, desc = 7, header = 0x62a8f0, dir = 0x69b720, bucket_cache = 0x0, cache_size = 0, last_read = -1, bucket = 0x0, bucket_dir = 0, cache_entry = 0x0, header_changed = 0 '\000', directory_changed = 0 '\000', bucket_changed = 0 '\000', second_changed = 0 '\000'} The flags=2 is GDBM_WRCREAT which corresponds to the Perl code. This is caused by the last hunk of the gdbm patch: diff -up gdbm-1.8.0/gdbmopen.c.gdbmopen gdbm-1.8.0/gdbmopen.c --- gdbm-1.8.0/gdbmopen.c.gdbmopen 2012-06-12 10:08:02.853499099 +0200 +++ gdbm-1.8.0/gdbmopen.c 2012-06-12 10:08:13.620769745 +0200 @@ -129,19 +129,17 @@ gdbm_open (file, block_size, flags, mode dbf->desc = open (dbf->name, O_RDONLY, 0); break; - case GDBM_OPENMASK: + case GDBM_WRITER: dbf->desc = open (dbf->name, O_RDWR, 0); break; case GDBM_NEWDB: dbf->desc = open (dbf->name, O_RDWR|O_CREAT, mode); - flags = GDBM_WRITER; need_trunc = TRUE; break; default: dbf->desc = open (dbf->name, O_RDWR|O_CREAT, mode); - flags = GDBM_WRITER; ← THIS IS MISSING break; This update breaks NIS: [root@ladd00 LADD-NIS]# rpm -q gdbm gdbm-1.8.0-37.el6.x86_64 [root@ladd00 LADD-NIS]# make -C /var/yp make: Entering directory `/var/yp' ... gmake[1]: Entering directory `/var/yp/LADD-NIS' Updating auto.daq... makedbm: dbm_store: Success gmake[1]: [auto.daq] Error 1 (ignored) ... [root@ladd00 LADD-NIS]# ls -l /var/yp/LADD-NIS total 268 -rw------- 1 root root 12481 Jan 7 14:11 auto.daq -rw------- 1 root root 12288 Jan 7 14:18 auto.daq~ ... (observe how file auto.daq is not updated, auto.daq~ is left behind instead) K.O. I reported the regression as bug #1180392. I concur. I opened up bug 1183180 prior to finding this... and yes since reverting back to gdbm-devel-1.8.0-36.el6.x86_64.rpm ypserv (specifically tools like ypinit and makedbm) works again. With this update, ypserv breaks because it can no longer update it's data in /var/yp/{domain}. This is serious breakage for anyone using ypserv. |