Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

add missing sigemptyset() to init sigset_t #29554

Open
wants to merge 1 commit into
base: main
Choose a base branch
from

Conversation

mcpiroman
Copy link

@mcpiroman mcpiroman commented Sep 14, 2019

Checklist
  • make -j4 test (UNIX), or vcbuild test (Windows) passes
  • commit message follows commit guidelines

This conforms to posix saying that sigset_t cannot be initialized through memset but rather sigemptyset() or sigfillset()

@nodejs-github-bot nodejs-github-bot added c++ Issues and PRs that require attention from people who are familiar with C++. process Issues and PRs related to the process subsystem. labels Sep 14, 2019
@mscdex
Copy link
Contributor

mscdex commented Sep 14, 2019

If that's the case, shouldn't we be removing the memset() also?

@mcpiroman
Copy link
Author

In struct sigaction , sa_handler is being set explicitly and now sa_mask is being set via sigemptyset(), so memset() really only inits sa_flags to 0. So memset() could be replaced by sa_flags = 0 which should be more readable.

@bnoordhuis
Copy link
Member

This conforms to posix saying that sigset_t cannot be initialized through memset

Where in the spec does it say that?

Leaving out the memset() leaves other fields uninitialized. That's probably going to cause trouble sooner or later.

(I fixed a bug to that effect years ago but I can't find the commit anymore.)

@mcpiroman
Copy link
Author

Where in the spec does it say that?

I was refering to the book "The Linux programming interface". Relevent quotes:

On Linux, as on most UNIX implementations, the sigset_t data type is a bit
mask. However, SUSv3 doesn’t require this. A signal set could conceivably be
represented using some other kind of structure. SUSv3 requires only that the
type of sigset_t be assignable. [...] One of sigemptyset() or sigaddset() must be used to initialize a signal set. [...] the initialization of static variables to 0 can’t portably be relied upon as indicating an empty signal set, since signal sets may be implemented using structures other than bit masks. (For the same reason, it is incorrect to use memset(3) to zero the contents of a signal set in order to mark it as empty.)


Leaving out the memset() leaves other fields uninitialized. That's probably going to cause trouble sooner or later.

sigaction only has 3 members (for application usage) and I've made sure these are always initialized. This is made the same way as examples in mentioned book.

@bnoordhuis
Copy link
Member

Ah, okay. I wouldn't equate TLPI with POSIX but POSIX.2008 mentions that:

[..] it would be reasonable to initialize part of the structure, such as a version field, to permit binary-compatibility between releases where the size of the set varies. For such reasons, either sigemptyset() or sigfillset() must be called prior to any other use of the signal set

So okay, from a correctness perspective, sigemptyset() is an improvement over memset().

This however:

sigaction only has 3 members (for application usage) and I've made sure these are always initialized.

Assumes that struct sigaction is the same everywhere but that's not necessarily true. POSIX only describes greatest common denominator behavior. I'd like to see memset() + sigemptyset().

@devnexen
Copy link
Contributor

devnexen commented Sep 16, 2019

Assumes that struct sigaction is the same everywhere but that's not necessarily true. POSIX only describes greatest common denominator behavior. I'd like to see memset() + sigemptyset().

That is pretty unusual honestly, seems "overdoing" to me, but I won't argue if it gets the upper vote.

@bnoordhuis
Copy link
Member

The same can be said about changing memset() to sigemptyset(). There's no platform we support where it makes a functional difference.

Not properly initializing all struct sigaction fields on the other hand has been the cause of at least one bug in the past.

@mcpiroman
Copy link
Author

This however:

sigaction only has 3 members (for application usage) and I've made sure these are always initialized.

Assumes that struct sigaction is the same everywhere but that's not necessarily true. POSIX only describes greatest common denominator behavior. I'd like to see memset() + sigemptyset().

If it contains additional fields, then how do you know that 0 is the right value for them? Unless posix says to initialize them to 0 if not used, then such implementation would be non-conformant. However I'll restore memsets if you're willing to.

There's no platform we support where it makes a functional difference.

We support right now + implementations are free to change this (not that it's very likely but save than sorry story).

I wouldn't equate TLPI with POSIX

Actually TLPI just quotes sus so ~ posix.

@bnoordhuis
Copy link
Member

If it contains additional fields, then how do you know that 0 is the right value for them?

I'd say the odds are > 50% that 0 is more likely to do the right thing than whatever random value is on the stack at the time of the call. :-)

If nothing else, it stops tools like valgrind from overzealously complaining about uninitialized padding.

@devnexen
Copy link
Contributor

I would say finally let s go with memset + sigemptyset @bnoordhuis made a valid point.

src/node.cc Outdated
@@ -176,6 +176,8 @@ void WaitForInspectorDisconnect(Environment* env) {
#if defined(__POSIX__) && !defined(NODE_SHARED_MODE)
struct sigaction act;
memset(&act, 0, sizeof(act));
sigemptyset(&act.sa_mask);
act.sa_flags = 0;
Copy link
Member

Choose a reason for hiding this comment

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

Explicitly zeroing the sa_flags field isn't necessary with the memset() back.

Copy link
Author

Choose a reason for hiding this comment

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

But indicates that we haven't forgotten about it / reminds reader about this field. Should I remove it?

Copy link
Member

Choose a reason for hiding this comment

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

It's superfluous so yes please.

@addaleax
Copy link
Member

@mcpiroman This needs to be rebased against Node.js master

@BridgeAR
Copy link
Member

BridgeAR commented Jan 12, 2020

@mcpiroman would you be so kind and rebase and force push instead of merging? Our CI does not work otherwise. You can do that along of these commands:

git fetch upstream master
git rebase -i upstream/master
git push --force-with-lease

upstream depends on your settings.

@BridgeAR BridgeAR force-pushed the master branch 2 times, most recently from 8ae28ff to 2935f72 Compare May 31, 2020 12:19
@jasnell jasnell added the stalled Issues and PRs that are stalled. label Jun 25, 2020
@aduh95
Copy link
Contributor

aduh95 commented Oct 19, 2020

@mcpiroman Can you rebase again please?

@bnb
Copy link
Contributor

bnb commented Jan 11, 2022

heya @mcpiroman, any chance you'd be able to address the above requests? Would love to get this merged if possible.

@mcpiroman
Copy link
Author

@bnb Not soon, at best after 3 weeks. But github now allows 'changes from the maintainers' so trival changes you may attempt to do yourself.

@aduh95 aduh95 added author ready PRs that have at least one approval, no pending requests for changes, and a CI started. request-ci Add this label to start a Jenkins CI on a PR. review wanted PRs that need reviews. labels Feb 11, 2022
@github-actions github-actions bot removed the request-ci Add this label to start a Jenkins CI on a PR. label Feb 11, 2022
@nodejs-github-bot
Copy link
Collaborator

@aduh95
Copy link
Contributor

aduh95 commented Feb 19, 2022

@mcpiroman can you have a look to make sure the rebase I made aligns with what you had in mind for this PR? I'd like to have at least another pair of eyes validating the code before merging in case I made a mistake.

@mcpiroman
Copy link
Author

Otherwise LGTM, though I it looks like force push covered my original commit and I don't remember that closely how it looked.

@aduh95
Copy link
Contributor

aduh95 commented Mar 7, 2022

Your original commits were f9c16b8...905dcc9.

sigfillset(&sa.sa_mask);
sa.sa_flags = reset_handler ? SA_RESETHAND : 0;
Copy link

Choose a reason for hiding this comment

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

Could you please clarify why it's moved below sigfillset?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
c++ Issues and PRs that require attention from people who are familiar with C++. process Issues and PRs related to the process subsystem. review wanted PRs that need reviews. stalled Issues and PRs that are stalled.
Projects
None yet
Development

Successfully merging this pull request may close these issues.