Discussion:
[Bug build/22873] New: ada-lex.c: races and non-robust build rules
jreiser at BitWagon dot com
2018-02-21 18:22:46 UTC
Permalink
https://sourceware.org/bugzilla/show_bug.cgi?id=22873

Bug ID: 22873
Summary: ada-lex.c: races and non-robust build rules
Product: gdb
Version: HEAD
Status: UNCONFIRMED
Severity: normal
Priority: P2
Component: build
Assignee: unassigned at sourceware dot org
Reporter: jreiser at BitWagon dot com
Target Milestone: ---

The build rules for ada-lex.c have races and are not robust in the face of
common situations. They are a barrier for contributing to gdb.

In the generated gdb/Makefile:
.PRECIOUS: ada-lex.c
means that most variations of "make clean" do not remove ada-lex.c. The
exception is "make local-maintainer-clean" which requires extra learning by a
newbie whose Linux distribution demands "report all gdb bugs upstream [i.e., at
sourceware.org]."

Why does it matter? Because of races in the building of ada-lex.c:
=====
%.c: %.l
if [ "$(FLEX)" ] && $(FLEX) --version >/dev/null 2>&1; then \
$(FLEX) -o$@ $< && \
rm -f $@.new && \
sed -e '/extern.*malloc/d' \
-e '/extern.*realloc/d' \
-e '/extern.*free/d' \
-e '/include.*malloc.h/d' \
-e 's/\([^x]\)malloc/\1xmalloc/g' \
-e 's/\([^x]\)realloc/\1xrealloc/g' \
-e 's/\([ \t;,(]\)free\([ \t]*[&(),]\)/\1xfree\2/g' \
-e 's/\([ \t;,(]\)free$$/\1xfree/g' \
-e 's/yy_flex_xrealloc/yyxrealloc/g' \
< $@ > $@.new && \
rm -f $@ && \
mv $@.new $@; \
=====
The first thing that "flex -oada-lex.c ..." does is open("ada-lex.c", 0666,
O_CREAT). So if the user types ^C (SIGINT) after the open() but before flex
does any write() to the file [flex thinks for a while before writing], then the
result is an ada-lex.c file that exists but is empty (has .st_size of 0). This
causes gdb/ada-lex.y to be incomplete, and subsequent compilations will fail
because 'yyin' is undefined. "make clean" will not help because ada-lex.c is
.PRECIOUS. If you haven't seen this before and do not stumble onto
'local-maintainer-clean' then apparently the only way forward is to start over
from the very beginning. Any file of zero length should not be .PRECIOUS.

But wait, there's more! Any SIGINT after flex and before the rm will leave
ada-lex.c exactly as flex wrote it. All the processing by sed will be ignored,
and the original ada-lex.c result of flex will persist because ada-lex.c is
.PRECIOUS.

Finally in the last two commands:
rm -f $@ && \
mv $@.new $@
the 'rm' is superfluous and should not be used. Just the 'mv' by itself has
the same effect, does it atomically, and has exactly the same error conditions.

Looking at the rule as a whole and in general, it is poor practice to generate
a file that has the name of the end result (ada-lex.c: "$(FLEX) -o$@ ")
anywhere except at the very last step.

[Somewhat less important: why not pipe "flex --stdout ... | sed ..." ?]
--
You are receiving this mail because:
You are on the CC list for the bug.
tromey at sourceware dot org
2018-04-19 09:47:35 UTC
Permalink
https://sourceware.org/bugzilla/show_bug.cgi?id=22873

Tom Tromey <tromey at sourceware dot org> changed:

What |Removed |Added
----------------------------------------------------------------------------
CC| |tromey at sourceware dot org

--- Comment #1 from Tom Tromey <tromey at sourceware dot org> ---
Thanks for the report.

How about writing a patch for this?
The contribution guidelines are here:

https://sourceware.org/gdb/wiki/ContributionChecklist
--
You are receiving this mail because:
You are on the CC list for the bug.
cvs-commit at gcc dot gnu.org
2018-04-29 15:58:43 UTC
Permalink
https://sourceware.org/bugzilla/show_bug.cgi?id=22873

--- Comment #2 from cvs-commit at gcc dot gnu.org <cvs-commit at gcc dot gnu.org> ---
The master branch has been updated by Simon Marchi <***@sourceware.org>:

https://sourceware.org/git/gitweb.cgi?p=binutils-gdb.git;h=cd8c76e410a5f16a170cc680be1ae2ecb5528821

commit cd8c76e410a5f16a170cc680be1ae2ecb5528821
Author: John Reiser <***@BitWagon.com>
Date: Sun Apr 29 11:57:38 2018 -0400

Fix race when building ada-lex.c

Prevent a race when building ada-lex.c, and any target of rules .c:.l or
.c:.y. The target should be written only at the last step, else SIGINT
(^C) can leave an inconsistent state. Being .PRECIOUS makes it even
worse.

gdb/ChangeLog:

PR build/22873
* gdb/Makefile.in: (.c:.l, .c:.y): Write the target only in the
last step, and do it atomically.
--
You are receiving this mail because:
You are on the CC list for the bug.
simon.marchi at ericsson dot com
2018-04-29 16:00:52 UTC
Permalink
https://sourceware.org/bugzilla/show_bug.cgi?id=22873

Simon Marchi <simon.marchi at ericsson dot com> changed:

What |Removed |Added
----------------------------------------------------------------------------
Status|UNCONFIRMED |RESOLVED
CC| |simon.marchi at ericsson dot com
Resolution|--- |FIXED

--- Comment #3 from Simon Marchi <simon.marchi at ericsson dot com> ---
Thanks for the patch, it's now pushed.
--
You are receiving this mail because:
You are on the CC list for the bug.
Loading...