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

[NTOBJSHEX] Return early from GetInfoFromPidl when pcidl is null in LPCITEMIDLIST #4946

Merged
merged 3 commits into from Dec 31, 2022

Conversation

muthu90tech
Copy link
Contributor

@muthu90tech muthu90tech commented Dec 18, 2022

Purpose

This fixes crash when attempting to drag n drop items from NTObject Namespace and System Registry.

Do a quick recap of your work here.

JIRA issues: CORE-18480, CORE-18481

Proposed changes

Perform a null check in GetInfoFromPidel on mkid in LPCITEMIDLIST

avoid_drag_drop_crash.mp4

(refer video, no more crash)

LPCITEMIDLIST, this fixes crash when attempting to drag n drop items
from NTObject Namespace and System Registry.
@katahiromz katahiromz changed the title [SHELL] Return early from GetInfoFromPidl when mkid is null in LPCITEMIDLIST [SHELL32] Return early from GetInfoFromPidl when mkid is null in LPCITEMIDLIST Dec 18, 2022
@katahiromz katahiromz added the bugfix For bugfix PRs. label Dec 18, 2022
@katahiromz katahiromz added this to New PRs in ReactOS PRs via automation Dec 18, 2022
dll/shellext/ntobjshex/ntobjfolder.cpp Outdated Show resolved Hide resolved
ReactOS PRs automation moved this from New PRs to Approved by reviewers Dec 18, 2022
@binarymaster binarymaster added the shell All PR's related to the shell (and shell extensions) label Dec 18, 2022
@binarymaster binarymaster changed the title [SHELL32] Return early from GetInfoFromPidl when mkid is null in LPCITEMIDLIST [NTOBJSHEX] Return early from GetInfoFromPidl when mkid is null in LPCITEMIDLIST Dec 18, 2022
@ghost
Copy link

ghost commented Dec 18, 2022

lgtm as based on my patch.

Copy link
Member

@learn-more learn-more left a comment

Choose a reason for hiding this comment

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

This is a very unreadable way of checking pcidl for null, please do that instead.

ReactOS PRs automation moved this from Approved by reviewers to WIP / Waiting on contributor Dec 18, 2022
@JoachimHenze
Copy link
Contributor

This is a very unreadable way of checking pcidl for null, please do that instead.

?
Wouldn't he need to check "pcidl->mkid" for being NULL instead?
If pcidl was indeed NULL, then his code would not work, but crash due to null-dereference already. Which is obviously not the case.

If he was to check something else than entry, then it would also make sense to move up the check.

But honestly I do not really understand your request yet, Mark.

@learn-more
Copy link
Member

learn-more commented Dec 21, 2022

This is a very unreadable way of checking pcidl for null, please do that instead.

? Wouldn't he need to check "pcidl->mkid" for being NULL instead? If pcidl was indeed NULL, then his code would not work, but crash due to null-dereference already.

No, checking pcidl->mkid is also wrong if pcidl is null.

Which is obviously not the case.

Think again.

If he was to check something else than entry, then it would also make sense to move up the check.

indeed.

But honestly I do not really understand your request yet, Mark.

I am unsure what is unclear about 'xxx' is an unreadable way of doing 'yyy', please do 'yyy' instead.

If the pointer math is confusing to you, try it out with a char* array on something like https://godbolt.org/

@muthu90tech
Copy link
Contributor Author

This is a very unreadable way of checking pcidl for null, please do that instead.

? Wouldn't he need to check "pcidl->mkid" for being NULL instead? If pcidl was indeed NULL, then his code would not work, but crash due to null-dereference already.

No, checking pcidl->mkid is also wrong if pcidl is null.

The GetInfoFromPidl(pidl, &info) gets called only if pidl in not null. Please see: https://github.com/reactos/reactos/blob/master/dll/shellext/ntobjshex/regfolder.cpp#L191

So pcidl in GetInfoFromPidl can not be null.

@learn-more
Copy link
Member

This is a very unreadable way of checking pcidl for null, please do that instead.

? Wouldn't he need to check "pcidl->mkid" for being NULL instead? If pcidl was indeed NULL, then his code would not work, but crash due to null-dereference already.

No, checking pcidl->mkid is also wrong if pcidl is null.

The GetInfoFromPidl(pidl, &info) gets called only if pidl in not null. Please see: https://github.com/reactos/reactos/blob/master/dll/shellext/ntobjshex/regfolder.cpp#L191

You have checked just one invocation:
https://git.reactos.org/?p=reactos.git&a=search&h=HEAD&st=grep&sr=1&s=GetInfoFromPidl

So pcidl in GetInfoFromPidl can not be null.

Clearly it is being called with null, otherwise your check would not catch it either.

@muthu90tech
Copy link
Contributor Author

muthu90tech commented Dec 21, 2022

This is a very unreadable way of checking pcidl for null, please do that instead.

? Wouldn't he need to check "pcidl->mkid" for being NULL instead? If pcidl was indeed NULL, then his code would not work, but crash due to null-dereference already.

No, checking pcidl->mkid is also wrong if pcidl is null.

The GetInfoFromPidl(pidl, &info) gets called only if pidl in not null. Please see: https://github.com/reactos/reactos/blob/master/dll/shellext/ntobjshex/regfolder.cpp#L191

You have checked just one invocation: https://git.reactos.org/?p=reactos.git&a=search&h=HEAD&st=grep&sr=1&s=GetInfoFromPidl

So pcidl in GetInfoFromPidl can not be null.

Clearly it is being called with null, otherwise your check would not catch it either.

Ok how about checking if pcidl is not null before checking pcidl->mkid in GetInfoFromPidl?

Like:

if (!pcidl)
{
    DbgPrint("PCIDL is NULL\n");
    return E_INVALIDARG;
}

Copy link
Contributor

@HBelusca HBelusca left a comment

Choose a reason for hiding this comment

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

OK; if pcidl is NULL then wouldn't this mean the GetInfoFromPidl function is called "incorrectly"? (if it's not expected to have either of its parameters being NULL)

@@ -484,6 +484,12 @@ HRESULT CNtObjectFolder::GetInfoFromPidl(LPCITEMIDLIST pcidl, const NtPidlEntry
{
NtPidlEntry * entry = (NtPidlEntry*) &(pcidl->mkid);

Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change

@@ -428,6 +428,12 @@ HRESULT CRegistryFolder::GetInfoFromPidl(LPCITEMIDLIST pcidl, const RegPidlEntry
{
RegPidlEntry * entry = (RegPidlEntry*) &(pcidl->mkid);

Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change

NtPidlEntry * entry = (NtPidlEntry*) &(pcidl->mkid);
if (!entry)
Copy link
Member

Choose a reason for hiding this comment

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

This check is completely useless.

Copy link

@ghost ghost Dec 22, 2022

Choose a reason for hiding this comment

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

I confirm that this check is not needed now that the preceeding check has been added (compiled and tested, crash is correctly protected). @muthu90tech : I suggest/support to remove this second useless check as suggested by Mark.

RegPidlEntry * entry = (RegPidlEntry*) &(pcidl->mkid);
if (!entry)
Copy link
Member

Choose a reason for hiding this comment

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

Same here, this check is completely useless

Copy link

@ghost ghost Dec 22, 2022

Choose a reason for hiding this comment

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

I confirm that this check is not needed now that the preceeding check has been added (compiled and tested, crash is correctly protected). @muthu90tech : I suggest/support to remove this second useless check as suggested by Mark.


NtPidlEntry * entry = (NtPidlEntry*) &(pcidl->mkid);
Copy link
Member

Choose a reason for hiding this comment

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

This is still a convoluted way of writing NtPidlEntry * entry = (NtPidlEntry*)pcidl;,
but whatever.

ReactOS PRs automation moved this from WIP / Waiting on contributor to Approved by reviewers Dec 28, 2022
@ghost
Copy link

ghost commented Dec 31, 2022

3 approved. Ready for merge ?

@HBelusca HBelusca changed the title [NTOBJSHEX] Return early from GetInfoFromPidl when mkid is null in LPCITEMIDLIST [NTOBJSHEX] Return early from GetInfoFromPidl when pcidl is null in LPCITEMIDLIST Dec 31, 2022
@HBelusca HBelusca merged commit 7fff96e into reactos:master Dec 31, 2022
ReactOS PRs automation moved this from Approved by reviewers to Done Dec 31, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bugfix For bugfix PRs. shell All PR's related to the shell (and shell extensions)
Projects
ReactOS PRs
  
Done
6 participants