Skip to content

Conversation

@ACEx86
Copy link

@ACEx86 ACEx86 commented Dec 24, 2025

No description provided.

@ACEx86 ACEx86 changed the title Fix potential nil deref on resolve.go Fix potential nil and panics Dec 24, 2025
@welwood08
Copy link
Contributor

From just a quick look, it seems most of these changes don't actually fix panics, just move them to later in the functions. How many of these were suggested by AI?

ips = append(ips, answer.(*dns.A).A.Addr.AsSlice())
case dns.TypeAAAA:
ips = append(ips, answer.(*dns.AAAA).AAAA.Addr.AsSlice())
if msg != nil {
Copy link
Contributor

Choose a reason for hiding this comment

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

This could probably be simplified to if msg == nil -> continue instead. Either way, agree this needs a nil check of some kind.

@ACEx86
Copy link
Author

ACEx86 commented Dec 24, 2025

None of the suggested panic fixes is by AI i just came accross some of the program crashes that had to do with the deferer.

client := &dns.Client{Transport: transport}
msg := dns.NewMsg(qName, qType)
if msg == nil {
return nil, errors.New("Query message error.")
Copy link
Contributor

Choose a reason for hiding this comment

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

As per the dns.NewMsg docs, nil is returned when the type is unknown so we should be able to say that in the error message. Otherwise agree a nil check is needed here.

@welwood08
Copy link
Contributor

None of the suggested panic fixes is by AI i just came accross some of the program crashes that had to do with the deferer.

Interesting, I'm not sure how some of those values could become nil. Do you have logs to share?

I assume it's not as simple as checking for nil at the same time as checking for err != nil? If so then it's strange to me that the rest of the function executes successfully on a non-nil value and it somehow transforms into nil in the deferred function...

@ACEx86
Copy link
Author

ACEx86 commented Dec 24, 2025

None of the suggested panic fixes is by AI i just came accross some of the program crashes that had to do with the deferer.

Interesting, I'm not sure how some of those values could become nil. Do you have logs to share?

I assume it's not as simple as checking for nil at the same time as checking for err != nil? If so then it's strange to me that the rest of the function executes successfully on a non-nil value and it somehow transforms into nil in the deferred function...

If you close the thread or the handle what will happen?
It's just a shield unexpected case in most of the times it hasn't to do with program exec.

@welwood08
Copy link
Contributor

If you close the thread or the handle what will happen? It's just a shield unexpected case in most of the times it hasn't to do with program exec.

I'm not sure what you mean by closing the thread or the handle in this context. If you mean some action external to the Go program, I don't see how that would set a value to nil before a deferred function can call Close() on it.

Are you actually seeing panics at all these places with the deferred close or is it just defensive programming?

}
defer pc.Close()
defer func(pc net.Conn) {
if pc != nil {
Copy link
Contributor

Choose a reason for hiding this comment

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

The only possible way I can see this being nil here is if net.DialTimeout returned nil, nil. If we don't trust net.DialTimeout then it's simpler to check at the same time as if err != nil above.

}
defer pc.Close()
defer func(pc net.Conn) {
if pc != nil {
Copy link
Contributor

Choose a reason for hiding this comment

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

This has more potential for an unknown proxy's Dial function to incorrectly return nil, nil. If that's the case, again the simpler guard is to check for nil at the same time as if err != nil above.

func (proxy *Proxy) localDoHListener(acceptPc *net.TCPListener) {
defer acceptPc.Close()
defer func(acceptPc *net.TCPListener) {
if acceptPc != nil {
Copy link
Contributor

Choose a reason for hiding this comment

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

In this case, if for some reason acceptPc is nil then there's no point doing anything in localDoHListener. The simpler solution here is an early return.

}
defer fSrc.Close()
defer func(fSrc *safefile.File) {
if fSrc != nil {
Copy link
Contributor

Choose a reason for hiding this comment

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

If safefile.Create returns nil, nil for whatever reason, it is again simpler to check before the defer call and return some new error instead of continuing to attempt to write anything. I don't see any other code that would change the value of either fSrc or fSig after each safefile.Create call.

for i, file := range files {
defer file.Close()
defer func(file *os.File) {
if file != nil {
Copy link
Contributor

Choose a reason for hiding this comment

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

Once again, nothing seems to set the value of file to nil within the loop. If it's nil at the start of the loop for whatever reason, we can just continue before the defer instead of trying to register a listener at all.

Copy link
Author

Choose a reason for hiding this comment

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

The 'defined' execution isn't the only specified thing that can happen.
I don't know if this will result to a panic on linux but if you rm the file after use and before return what will happen trying to close without nil check? And i mean rm it from the system not the program.

Copy link
Contributor

Choose a reason for hiding this comment

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

file here is unrelated to any Linux file handle, it will not magically become nil without something within the Go program setting it so.

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.

2 participants