Skip to content

x/sys/unix: C->Go type converter does not take integer field sign into account #44794

@anatol

Description

@anatol

I am looking at Linux statfs structure that is defined in Linux UAPI as

/*
 * Most 64-bit platforms use 'long', while most 32-bit platforms use '__u32'.
 * Yes, they differ in signedness as well as size.
 * Special cases can override it for themselves -- except for S390x, which
 * is just a little too special for us. And MIPS, which I'm not touching
 * with a 10' pole.
 */
#ifndef __statfs_word
#if __BITS_PER_LONG == 64
#define __statfs_word __kernel_long_t
#else
#define __statfs_word __u32
#endif
#endif

struct statfs {
	__statfs_word f_type;
	__statfs_word f_bsize;
	__statfs_word f_blocks;
	__statfs_word f_bfree;
	__statfs_word f_bavail;
	__statfs_word f_files;
	__statfs_word f_ffree;
	__kernel_fsid_t f_fsid;
	__statfs_word f_namelen;
	__statfs_word f_frsize;
	__statfs_word f_flags;
	__statfs_word f_spare[4];
};

__statfs_word is marked as unsigned 32bit at 32bit platforms.

Now let's look at the generated code for a 32bit platform e.g. arm (unix/ztypes_linux_arm.go):

type Statfs_t struct {
        Type    int32
        Bsize   int32
        Blocks  uint64
        Bfree   uint64
        Bavail  uint64
        Files   uint64
        Ffree   uint64
        Fsid    Fsid
        Namelen int32
        Frsize  int32
        Flags   int32
        Spare   [4]int32
        _       [4]byte
}

Here Type field is signed int that differs from the UAPI intention.

This causes issues with a compiled code, like this for example:

if statfs.Type != unix.RAMFS_MAGIC {
  // foo bar
}

This code fails to compile for arm because unix.RAMFS_MAGIC is 0x858458f6 and does not match int32 at the left side.

statfs.Type should really be a uint32 type.

Metadata

Metadata

Assignees

No one assigned

    Labels

    NeedsInvestigationSomeone must examine and confirm this is a valid issue and not a duplicate of an existing one.compiler/runtimeIssues related to the Go compiler and/or runtime.

    Type

    No type

    Projects

    Status

    Triage Backlog

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions