Hey, Den 2026-03-03 kl. 20:58, skrev David Laight: > On Tue, 3 Mar 2026 18:44:59 +0100 > Julian Orth <[email protected]> wrote: > >> On Tue, Mar 3, 2026 at 6:41 PM Maarten Lankhorst >> <[email protected]> wrote: >>> >>> My point is that it works for old userspace without problems. It's only >>> newly compiled userspace with new headers that will run into problems. >>> The code as written would have continued to work, but if you update to >>> the new header and don't initialise the new members then it's a userspace >>> problem. It should not be worked around in the kernel, since it's newly >>> written bad userspace code, not old bad userspace code that stopped working >>> when the kernel changed. >> >> But it's not newly written. The example is, say, 5 year old code. The >> binary that was compiled 5 years ago works fine as you say. But if you >> take the same code and just run gcc again, the new binary will no >> longer work. >> > > Worse, the recompiled version may well work when you test it, and even > when deployed. > But you'll get non-obvious random failures - a support nightmare.
I believe in a lot of cases the headers are simply copied to the project, so it will continue to work. I don't see a difference between moving to a new compiler. Compiling code from 5 years ago might also run into new compiler warnings that didn't exist on the older version of the compiler. > Probably best code is something like: > case OLD_IOCTL_CODE: > if (ioc->flag & NEW_FLAG) > return -EINVAL; > /* FALLTHROUGH *. > case NEW_IOCTL_CODE: > if (!(ioc->flag & NEW_FLAG)) > ioc->new_field = 0; > > David Yeah, that is what we do by explicitly checking the size parameter. Any undefined members are zero'd. If you define the new member in userspace, you're also taking on the responsibility for having it contained defined information, even if you only zero the struct. Kind regards, ~Maarten Lankhorst
