Message ID | 20220215231052.3378121-1-aurelien@aurel32.net |
---|---|
State | New |
Headers | show |
Series | _dl_discover_osversion: clamp parts to 255 | expand |
* Aurelien Jarno: > Some stable Linux kernels have a lowest version part greater than 255, > and _dl_discover_osversion returns the wrong version for them as it uses > only 8 bits per part (just like LINUX_VERSION_CODE). For instance kernel > version 4.4.268 is reported as 0x4050c, ie 4.5.12. Kernel version > 4.14.266 is reported as 4.15.10. The 4.9 and 4.19 branches are not > affected at this stage as the lower bit of the second part is already > set. > > Fix that by clamping the parts to 255. This is fine given that the GNU > libc requires at least a kernel in version 3.2, and since kernel version > 3.x.y the third part is not meaningful anymore from the GNU libc point > of view. > --- > sysdeps/unix/sysv/linux/dl-sysdep.c | 4 ++++ > 1 file changed, 4 insertions(+) > > diff --git a/sysdeps/unix/sysv/linux/dl-sysdep.c b/sysdeps/unix/sysv/linux/dl-sysdep.c > index 8ad72c4b7b..1be3867226 100644 > --- a/sysdeps/unix/sysv/linux/dl-sysdep.c > +++ b/sysdeps/unix/sysv/linux/dl-sysdep.c > @@ -379,6 +379,10 @@ _dl_discover_osversion (void) > here += *cp++ - '0'; > } > > + /* Clamp parts to 255 as they are later saved using 8 bits only. */ > + if (here > 255) > + here = 255; > + > ++parts; > version <<= 8; > version |= here; I wonder if we should just remove the version checks, including the one for NT_GNU_ABI_TAG. The latter has had serious impact on Qt users even without this particular problem. Thanks, Florian
On 16/02/2022 03:35, Florian Weimer via Libc-alpha wrote: > * Aurelien Jarno: > >> Some stable Linux kernels have a lowest version part greater than 255, >> and _dl_discover_osversion returns the wrong version for them as it uses >> only 8 bits per part (just like LINUX_VERSION_CODE). For instance kernel >> version 4.4.268 is reported as 0x4050c, ie 4.5.12. Kernel version >> 4.14.266 is reported as 4.15.10. The 4.9 and 4.19 branches are not >> affected at this stage as the lower bit of the second part is already >> set. >> >> Fix that by clamping the parts to 255. This is fine given that the GNU >> libc requires at least a kernel in version 3.2, and since kernel version >> 3.x.y the third part is not meaningful anymore from the GNU libc point >> of view. >> --- >> sysdeps/unix/sysv/linux/dl-sysdep.c | 4 ++++ >> 1 file changed, 4 insertions(+) >> >> diff --git a/sysdeps/unix/sysv/linux/dl-sysdep.c b/sysdeps/unix/sysv/linux/dl-sysdep.c >> index 8ad72c4b7b..1be3867226 100644 >> --- a/sysdeps/unix/sysv/linux/dl-sysdep.c >> +++ b/sysdeps/unix/sysv/linux/dl-sysdep.c >> @@ -379,6 +379,10 @@ _dl_discover_osversion (void) >> here += *cp++ - '0'; >> } >> >> + /* Clamp parts to 255 as they are later saved using 8 bits only. */ >> + if (here > 255) >> + here = 255; >> + >> ++parts; >> version <<= 8; >> version |= here; > > I wonder if we should just remove the version checks, including the one > for NT_GNU_ABI_TAG. The latter has had serious impact on Qt users even > without this particular problem. I agree, I think we can also print the minimum kernel version when executing libc.so (to show the information similar to what 'file' tool does).
diff --git a/sysdeps/unix/sysv/linux/dl-sysdep.c b/sysdeps/unix/sysv/linux/dl-sysdep.c index 8ad72c4b7b..1be3867226 100644 --- a/sysdeps/unix/sysv/linux/dl-sysdep.c +++ b/sysdeps/unix/sysv/linux/dl-sysdep.c @@ -379,6 +379,10 @@ _dl_discover_osversion (void) here += *cp++ - '0'; } + /* Clamp parts to 255 as they are later saved using 8 bits only. */ + if (here > 255) + here = 255; + ++parts; version <<= 8; version |= here;