Skip to content

Conversation

@pepone
Copy link
Member

@pepone pepone commented Nov 3, 2025

Fix #4547

Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull Request Overview

This PR addresses a potential null pointer dereference in the updateRevision method by adding a null check for _desc before accessing it. The change recognizes that _desc can be nullptr if the server's initial load has not completed yet.

Key changes:

  • Added null check guard for _desc before updating uuid and revision
  • Introduced local variable desc to avoid repeated member access
  • Applied the same pattern to the _load path for consistency

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines 2459 to 2468
string idFilePath = _serverDir + "/revision";
ofstream os(IceInternal::streamFilename(idFilePath).c_str()); // idFilePath is a UTF-8 string
if (os.good())
{
os << "#" << endl;
os << "# This server belongs to the application '" << _desc->application << "'" << endl;
os << "# This server belongs to the application '" << desc->application << "'" << endl;
os << "#" << endl;
os << "uuid: " << _desc->uuid << endl;
os << "revision: " << _desc->revision << endl;
os << "uuid: " << desc->uuid << endl;
os << "revision: " << desc->revision << endl;
}
Copy link

Copilot AI Nov 3, 2025

Choose a reason for hiding this comment

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

Potential null pointer dereference. The variable desc could be nullptr if both _desc is nullptr and _load is also nullptr (or if the initial _desc is nullptr and we skip the if (_load) block). Before accessing desc->application, desc->uuid, and desc->revision at lines 2464-2467, a null check should be added to prevent undefined behavior.

Copilot uses AI. Check for mistakes.
{
os << "#" << endl;
os << "# This server belongs to the application '" << _desc->application << "'" << endl;
os << "# This server belongs to the application '" << desc->application << "'" << endl;
Copy link
Member

Choose a reason for hiding this comment

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

I'm not quite following. Can't desc be null here still?

Copy link
Member Author

Choose a reason for hiding this comment

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

This is just inside updateRevision writing the revision file, if it was null before, it will still be null. This method doesn't update _desc.

Copy link
Member

Choose a reason for hiding this comment

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

But it _load is false, then desc will be nullptr. This deference will crash.

Copy link
Member Author

Choose a reason for hiding this comment

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

_desc is set if already loaded.
_load is set if loading.

We don't call this method if neither is set, I will add an assert.

Copy link
Member Author

Choose a reason for hiding this comment

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

see:

    auto d = _load ? _load->getInternalServerDescriptor() : _desc;
    if (d && (replicaName != "Master" || d->sessionId == desc->sessionId) && !descriptorUpdated(d, desc))
    {
        if (d->revision != desc->revision)
        {
            updateRevision(desc->uuid, desc->revision);
        }

The if (d && ensures either _load or _desc is set.

Next call is:

_load->addCallback(response, exception); // Must be called before startRuntimePropertiesUpdate!
updateRevision(desc->uuid, desc->revision);

Here _load is set.

The third call hasppens inside updateImpl and both are set in this case:

void
ServerI::updateImpl(const shared_ptr<InternalServerDescriptor>& descriptor)
{
    assert(_load && descriptor);

    _desc = descriptor;
    _waitForReplication = true;

    // Remember if the server was just released by a session, this will be used later to not update the configuration
    // on the disk (as an optimization and to allow users to review the configuration file after allocating a server --
    // that's useful if the server configuration is bogus and the session server can't start).
    bool serverSessionReleased = _desc && _desc->activation == "session" && _desc->revision == descriptor->revision &&
                                 !_desc->sessionId.empty() && descriptor->sessionId.empty();

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.

IceGrid/update test failure (Windows)

2 participants