Skip to content

Fix ROBOSPECT to be compatible with GSL 2.x#2

Open
gszasz wants to merge 4 commits intoczwa:masterfrom
gszasz:fix-gsl2
Open

Fix ROBOSPECT to be compatible with GSL 2.x#2
gszasz wants to merge 4 commits intoczwa:masterfrom
gszasz:fix-gsl2

Conversation

@gszasz
Copy link

@gszasz gszasz commented Nov 25, 2024

Motivation

This PR is addressing the note mentioned in the second paragraph of the ROBOSPECT webpage:

NOTE: After major development of ROBOSPECT stopped in 2013, GSL updated to version 2, which is incompatible with the current source code. The previous version is still packaged for Debian/Ubuntu systems, as the libgsl0-dev package. Please use this version of GSL until ROBOSPECT has been rewritten for the newer version.

The libgsl0-dev package mentioned above, containing GSL 1.16, was indeed shipped with Ubuntu 14.04 LTS, released on April 17, 2014. Even though the extended standard support of Ubuntu 14.04 LTS was prolonged to 10 years in September 2021, it reached its end of life on April 17, 2024. It means that over the past 8 months, nobody could use ROBOSPECT in a supported environment. At the same time, the project development has stopped and the promised rewritten newer version of ROBOSPECT has never been delivered.

@czwa decided to transfer ROBOSPECT from its original private CSV repo to GitHub on August 28, 2018, allowing the community to continue in his work; nevertheless, no progress was done over the past 6 years.

@pavolgaj filed the issue #1 on December 20, 2021, pinpointing the exact design change in GSL 2.0 that broke the backward compatibility in 2013, asking for advice on how to fix it. Nobody addressed the issue for the following 3 years.

Our Open Cluster Working Group, led by @epaunzen, actively uses the ROBOSPECT code for years, especially within the research projects conducted by @PraptiMondal and @iamasciencer. With the Ubuntu 14.04 LTS reaching its end of life, we have decided to step in.

Description

Our goal was to resolve #1 filed by @pavolgaj, who found out that starting from GSL 2.0, the following code is no longer valid, since the Jacobian matrix is no longer part of the gsl_multifit_fdfsolver structure:

gsl_multifit_covar(S->J,0.0,covar);

It turned out that the Jacobian needs to be allocated and defined separately. The gsl_mulitifit_fdfsolver_jac() is a new function that was introduced in GSL 2.0.

gsl_matrix *J = gsl_matrix_alloc(f.n, f.p);
gsl_multifit_fdfsolver_jac(S, J);
gsl_multifit_covar(J, 0.0, covar);

We also resolved all warnings reported by gcc to simplify testing. These warnings turned out to be caused with the minor bugs clustered around the following four lines of code:

  • fileio.c:5: The pointer to the local statically allocated char array cannot be returned from the function, because once the program leaves the scope of the function, there is no guarantee that the array will be preserved.
  • fileio/input_fitsWCS.c:93: The k variable can contain a signed integer number (from -2147483646 to 2147483646) that will occupy between 3 and 11 bytes when formatted into a %03d string. Note that the %03d format specifies the minimum number of digits, but it does not prevent from including a number greater than 999. The snprintf() function then does the truncation, and thus prevents buffer overflow, but this is generally bad coding style. In this scenario, the -Wformat-truncation compiler argument generates the warning, if a developer does not check the return value of snprintf().
  • fileio/input_fitsWCS.c:97: The sprintf() function simply cannot read and write into the same string at the same time. Furthermore, the space character as a flag of the format string does not have any role in the %s format, and it is ignored by sprintf().
  • models/continuum_blackbody.c:76: The undeclared chi variable contains a random value during the first log_comment() call.

Additionally, we found out that Ubuntu 24.04 LTS uses string_fortified.h instead of string.h and thus it is more sensitive to buffer overflow errors in config.c, which needed to be fixed before testing the patch in this environment.

We also added preventive checks of the return value of malloc() and realloc() calls across the entire ROBOSPECT code.

Test Results

Distribution Arch. Platform Tested by Test Result
Fedora Linux 41 Workstation Edition x86_64 bare-metal @gszasz, @PraptiMondal PASSED
Ubuntu 24.04.1 LTS Workstation x86_64 bare-metal @iamasciencer PASSED
Ubuntu 24.04.1 LTS Workstation x86_64 QEMU/KVM @gszasz PASSED
Ubuntu 22.04.5 LTS Workstation x86_64 QEMU/KVM @gszasz PASSED
Ubuntu 22.04.5 LTS WSL x86_64 Windows 10 WSL @gszasz, @epaunzen PASSED

GSL 2.0 broke backward compatibility with GSL 1.x code, which prevented
ROBOSPECT from being used with modern Linux distributions.

The fix was relatively easy. The only relevant difference that affected
the ROBOSPECT code was the need to calculate the Jacobian matrix
explicitly via the gsl_mulitifit_fdfsolver_jac() function.
@gszasz gszasz changed the title Fix ROBOSPECT to compile with GSL 2.x Fix #1: Make ROBOSPECT compatible with GSL 2.x Nov 25, 2024
@gszasz gszasz changed the title Fix #1: Make ROBOSPECT compatible with GSL 2.x Fix ROBOSPECT to be compatible with GSL 2.x Nov 25, 2024
The compiler shows several warnings which should be addressed:

fileio.c:5: Pointer to the local statically allocated char array cannot
be returned from the function, because once the program leaves the scope
of the function, there is no guarantee that the array will be preserved.
Making the variable static is the easiest fix of this issue.

fileio/input_fitsWCS.c:93: The k variable can contain a signed integer
number (from -2147483646 to 2147483646) that will occupy between 3 and
11 bytes when formatted into a %03d string.  Note that the %03d format
specifies the *minimum* number of digits, but it does not prevent from
including number greater than 999.  The snprintf() function then does
the truncation, and thus prevents buffer overflow, but this is generally
quite a bad practice.  In this scenario the -Wformat-truncation compiler
argument generates the warning if a developer does not at least check if
the return value of snprintf() is not negative.

fileio/input_fitsWCS:97: This is one of the most dangerous pieces of
code within the ROBOSPECT that is most likely responsible for
unpredictable behavior.  The sprintf() function simply cannot read and
write into the same string at the same time.  Furthermore, space (' ')
as a flag of the format string do not have any function in "%s" format
and it is simply ignored by sprintf().  I have rewritten this code using
pointer arithmetic to avoid frequent NULL pointer checking.

models/continuum_blackbody.c:76: The undeclared chi variable contains a
random value during the first log_comment() call.  Although it is not
critical, accessing undeclared variable should be avoided in any
circumstances.  The iterations starts with chi square value 99e99 and
this is exactly what we should be printed during the first log_comment()
call.
The return value of the malloc() and realloc() calls was never checked
for an error.  Although this did not produce any warning, it is
generally a very bad practice.

My implementation of the memory allocation error handling might be
simplistic, but it represents the bare minimum that should have been
implemented a long ago.
Lukas Kueß (@iamasciencer) has encountered enigmatic buffer overflow
errors when testing ROBOSPECT on Ubuntu 24.02 LTS.  It turned out that
Ubuntu 24.02 LTS uses fortified strings by default and since the
ROBOSPECT's string memory allocation handling is suboptimal, it did not
comply the strict rules of fortified strings.

I had to rewrite several parts of config.c to make this work properly.
@gszasz gszasz mentioned this pull request Nov 29, 2024
@PraptiMondal
Copy link

I used to hit issue #1, and this PR fixed it for me. I tested it on Fedora Linux 41 Workstation Edition (x86_64 architecture), and it works without any issues. The code looks good to me.

Copy link

@iamasciencer iamasciencer left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good to me, tested on Ubuntu 24.04.1 LTS, it worked

@iamasciencer
Copy link

I ran into buffer overflows on Ubuntu 24.04.1 (64 bit), the patches addressed this issue ant it works now without problems

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Compilation

3 participants