RFC: strategies to provide y2038 support for stat functions

classic Classic list List threaded Threaded
3 messages Options
Reply | Threaded
Open this post in threaded view
|

RFC: strategies to provide y2038 support for stat functions

Sourceware - libc-alpha mailing list
Hi all

The current implementation for stat family functions (stat, stat64,
lstat, lstat64, fstat, fstat64, fstatat, fstatat64) poses some
challenges on how to provide the y2038 support.

Its implementation uses scheme where the stat.h header (io/sys/stat.h)
provides inline versions for the exported extensible version (__xstat for
instance).  A libc_nonshared wrappers is also provided if the inline
could not be satisfied (if __USE_EXTERN_INLINES could not defined).
The extended implementation receives as first argument the expected
'version' of the stat structure and thus either uses it directly on
the syscall or apply some conversion.

This mechanism was devised prior symbol versioning and besides the code
complexity it also has some other issues: the non-shared wrappers, exports
non-default symbols, it fails at runtime instead of load time for different
support stat version between application and libc.

So to support a y2038 interface using this mechanism the straightforward
way would to add a new _STAT_* version, the stat{64}_time64 definitions,
and adjust each *xstat*.c implementation to handle the new type:

  int
  __xstat (int vers, const char *name, struct stat *buf)
  {
    [...]
    if (vers == _STAT_VER_LINUX_TIME64)
      {
        // Call statx
        // Convert from statx to struct __stat_time64 and return
      }
    [...]
  }

And on header once the time64 support is enabled we would do

  [...]
  #if __TIMESIZE == 64
  __extern_inline int
  __NTH (stat (const char *__path, struct stat_time64 *__statbuf))
  {
    return __xstat (_STAT_LINUX_TIME64, __path, __statbuf);
  }
  #else
  [...]
  #endif

We will need to add the libc_nonshared wrapper as well.

Two additional issues on this approach are:

  1. There are multiple implementations of extended stat version (with
     and without LFS support) and we will need to adjust each of them.

  2. Testing won't be easy as for current way to add time64 support, where
     the time32 version call the time64 one.


Another possibility which would also require some plumbing is to:

  1. Move the extensible stat function to compat symbols

  2. Implement the stat family function as proper versioned symbols
     2.1. Add the required libc_hidden_def and call the internal calls to
          avoid internal plts.

  3. Implement the y2038 support as other symbols:
     3.1. Add struct __stat_time64 and __stat64_time64
     3.2. Add __stat_time64 and __stat64_time64
     3.3. Implement stat by calling __stat_time64 and covert the output.

A drawback is add new glibc symbols for stat, stat64, lstat, lstat64,
fstat, fstat64, fstatat, fstatat64.  In the other hand we can cleanup the
stat struct and use a default one for all architectures and also cleanup
the implementation to just use statx or fstatat64 syscall.

I am more inclined on second way, so we could move away from the stat
non_shared wrapper.

Thoughts?
Reply | Threaded
Open this post in threaded view
|

Re: RFC: strategies to provide y2038 support for stat functions

Sourceware - libc-alpha mailing list
* Adhemerval Zanella via Libc-alpha:

> Another possibility which would also require some plumbing is to:
>
>   1. Move the extensible stat function to compat symbols
>
>   2. Implement the stat family function as proper versioned symbols
>      2.1. Add the required libc_hidden_def and call the internal calls to
>           avoid internal plts.
>
>   3. Implement the y2038 support as other symbols:
>      3.1. Add struct __stat_time64 and __stat64_time64
>      3.2. Add __stat_time64 and __stat64_time64
>      3.3. Implement stat by calling __stat_time64 and covert the output.
>
> A drawback is add new glibc symbols for stat, stat64, lstat, lstat64,
> fstat, fstat64, fstatat, fstatat64.  In the other hand we can cleanup the
> stat struct and use a default one for all architectures and also cleanup
> the implementation to just use statx or fstatat64 syscall.
>
> I am more inclined on second way, so we could move away from the stat
> non_shared wrapper.

I agreed.  It would be nice if we could get rid of all statically linked
C code for shared objects, for an easier bootstrap GCC procedure.

Thanks,
Florian

Reply | Threaded
Open this post in threaded view
|

Re: RFC: strategies to provide y2038 support for stat functions

Sourceware - libc-alpha mailing list
In reply to this post by Sourceware - libc-alpha mailing list
On 7/14/20 12:49 PM, Adhemerval Zanella via Libc-alpha wrote:

> Another possibility which would also require some plumbing is to:
>
>   1. Move the extensible stat function to compat symbols
>
>   2. Implement the stat family function as proper versioned symbols
>      2.1. Add the required libc_hidden_def and call the internal calls to
>           avoid internal plts.
>
>   3. Implement the y2038 support as other symbols:
>      3.1. Add struct __stat_time64 and __stat64_time64
>      3.2. Add __stat_time64 and __stat64_time64
>      3.3. Implement stat by calling __stat_time64 and covert the output.
>
> A drawback is add new glibc symbols for stat, stat64, lstat, lstat64,
> fstat, fstat64, fstatat, fstatat64.  In the other hand we can cleanup the
> stat struct and use a default one for all architectures and also cleanup
> the implementation to just use statx or fstatat64 syscall.
>
> I am more inclined on second way, so we could move away from the stat
> non_shared wrapper.
>
> Thoughts?

I think such a cleanup would be worthwhile.

We should document the changes in such a way that developers writing
interposes have an easy time of updating and we can circulate these notes
to ensure people know this change is coming.

Existing interposers may need to be updated, so we should have a clearly
documented final set of public functions that require additional
interposition to completely cover the API. I think such preloads as
fakeroot and guix's own relocation support may require that these interfaces
be effectively interposed.

Thank you for writing this up.

--
Cheers,
Carlos.