> No, because if nbytes > sizeof(*hwrpb), your version causes the kernel to only write part of the buffer, and then when the app accesses fields at the end of the struct, it would read uninitialized data, which is very bad.
> I would agree with you if the kernel had some other mechanism to pass the size of the buffer that was actually filled to the client (like e.g. the read() syscall does) but the getsysinfo() API doesn't return that data, so the kernel must either fill the buffer entirely or return failure.
As you mention, this struct is versioned. Userspace can tell how much of the struct was filled by checking the size field (hwrpb->size).
> But allowing nbytes < sizeof(*hwrpb) has the benefit that the kernel developers can add fields at the end of the struct without breaking backward compatibility with older applications.
That's a related but separate issue. Backward compatibility can be handled by switching on nbytes or by copying fewer bytes with a carefully designed struct. It's not clear that backward compatibility was the original intention of this code, the original intention more seems to be sanitizing tainted input. This struct has not changed in at least 16 years.
> I would agree with you if the kernel had some other mechanism to pass the size of the buffer that was actually filled to the client (like e.g. the read() syscall does) but the getsysinfo() API doesn't return that data, so the kernel must either fill the buffer entirely or return failure.
As you mention, this struct is versioned. Userspace can tell how much of the struct was filled by checking the size field (hwrpb->size).
> But allowing nbytes < sizeof(*hwrpb) has the benefit that the kernel developers can add fields at the end of the struct without breaking backward compatibility with older applications.
That's a related but separate issue. Backward compatibility can be handled by switching on nbytes or by copying fewer bytes with a carefully designed struct. It's not clear that backward compatibility was the original intention of this code, the original intention more seems to be sanitizing tainted input. This struct has not changed in at least 16 years.