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

x/sys/unix: Utsname.Version is too small? #65585

Closed
seeplusplus opened this issue Feb 7, 2024 · 5 comments
Closed

x/sys/unix: Utsname.Version is too small? #65585

seeplusplus opened this issue Feb 7, 2024 · 5 comments
Labels
compiler/runtime Issues related to the Go compiler and/or runtime. NeedsInvestigation Someone must examine and confirm this is a valid issue and not a duplicate of an existing one. OS-FreeBSD
Milestone

Comments

@seeplusplus
Copy link

seeplusplus commented Feb 7, 2024

Go version

go1.20.12 freebsd/386

Output of go env in your module/workspace:

Not relevant.

What did you do?

  1. Built the following minimal reproducible Go program targeting FreeBSD, shown here:
    FreeBSD: couldn't get uname: cannot allocate memory prometheus/node_exporter#2809 (comment)
  2. Copied the file to a running instances of pfSense
  3. Ran it
  4. Got an "Cannot allocate memory" error
  5. Cloned sys/unix locally and played around with the syscall_freebsd.go file, in particular I commented out sections of the Uname method until I found the section that caused the error. That was this section:
 mib = []_C_int{CTL_KERN, KERN_VERSION}
          n = unsafe.Sizeof(uname.Version)
          if err := sysctl(mib, &uname.Version[0], &n, nil, 0); err != nil {
                 return err
}   

Upon further digging I found that uname.Version is set to 256 bytes here:

https://cs.opensource.google/go/x/sys/+/master:unix/ztypes_freebsd_amd64.go;l=639-645;bpv=0?q=Utsname&ss=go%2Fx%2Fsys

so then I,
6. Modified the above locally to a larger value, 1024.
7. Rebuilt the test binary with all code from step 5 uncommented.
8. Reran the binary on the pfSense OS,
9. No error.

What did you see happen?

Got "cannot allocate memory" until I made the Utsname.Version field larger.

What did you expect to see?

The Uname to be returned.

Apologies if this isn't the correct venue for this report. I'm not a Go developer, nor have I ever worked on FreeBSD or pfSense. I am willing to do what's needed to fix this, but I'm not sure exactly what's "wrong" here. I know the types_freebsd.go file is auto-generated, but I'm not familiar with the domain to know if:

  1. pfSense is errantly reporting a KERN_VERSION larger than 256 bytes, or
  2. the types_freebsd.go file needs to be regenerated/modified in some way.

Edit: Fwiw I was doing some reading and it looks like maybe this isn't the first time someone has encountered this issue in FreeBSD?

https://github.com/freebsd/freebsd-src/blob/82bebc7936581e9c4ff3604d4cb998f8cc017f50/sys/kern/kern_xxx.c#L351-L371

@gopherbot gopherbot added the compiler/runtime Issues related to the Go compiler and/or runtime. label Feb 7, 2024
@gopherbot gopherbot added this to the Unreleased milestone Feb 7, 2024
@bcmills
Copy link
Contributor

bcmills commented Feb 7, 2024

(attn @golang/freebsd)

@dr2chase dr2chase added the NeedsInvestigation Someone must examine and confirm this is a valid issue and not a duplicate of an existing one. label Feb 9, 2024
@paulzhol
Copy link
Member

@paulzhol
Copy link
Member

The following C reproducer returns ENOMEM on pfSense CE 2.7.2, while successful on FreeBSD 14.0-RELEASE:

#include <sys/utsname.h>
#include <sys/cdefs.h>
#include <sys/param.h>
#include <sys/sysctl.h>
#include <errno.h>
#include <stdlib.h>

int main(int argc, char **argv) {
        struct utsname u = {0};
        int mib[2], rval;
        size_t len;
        mib[0] = CTL_KERN;
        mib[1] = KERN_VERSION;
        len = sizeof u.version;
        char* q = (char *)u.version;
        rval = sysctl(mib, 2, q, &len, NULL, 0);
        printf("rval: %d, errno: %d\n", rval, errno);
        printf("u.version: %s\n", &u.version[0]);
        return 0;
}
rval: -1, errno: 12
u.version: FreeBSD 14.0-CURRENT amd64 1400094 #1 RELENG_2_7_2-n255948-8d2b56da39c: Wed Dec  6 20:45:47 UTC 2023
    root@freebsd:/var/jenkins/workspace/pfSense-CE-snapshots-2_7_2-main/obj/amd64/StdASW5b/var/jenkins/workspace/pfSense-CE-snapshots-2_7_2-main/sources/Fr
rval: 0, errno: 0
u.version: FreeBSD 14.0-RELEASE-p3 #0: Mon Dec 11 04:56:01 UTC 2023
    root@amd64-builder.daemonology.net:/usr/obj/usr/src/amd64.amd64/sys/GENERIC

Looks like we should suppress ENOMEM and truncate to match the __xuname behavior in eg:
https://github.com/golang/sys/blob/2f2cc5dae4e240ccd9b4142205a71a311328419f/unix/syscall_freebsd.go#L190-L192

@gopherbot
Copy link

Change https://go.dev/cl/562617 mentions this issue: unix: supress ENOMEM errors from sysctl's implementing Uname(uname *Utsname) due to truncated fields.

@seeplusplus
Copy link
Author

Change https://go.dev/cl/562617 mentions this issue: unix: supress ENOMEM errors from sysctl's implementing Uname(uname *Utsname) due to truncated fields.

@paulzhol I have tested the above patch on my pfSense machine, this works, thank you!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
compiler/runtime Issues related to the Go compiler and/or runtime. NeedsInvestigation Someone must examine and confirm this is a valid issue and not a duplicate of an existing one. OS-FreeBSD
Projects
None yet
Development

No branches or pull requests

5 participants