[PATCH] debuginfod/debuginfod-client.c: correct string format on 32bit arches with 64bit time_t

2021-11-19 Thread Alexander Kanavin via Elfutils-devel
From: Alexander Kanavin 

Use intmax_t to print time_t

time_t is platform dependent and some of architectures e.g.
x32, riscv32, arc use 64bit time_t even while they are 32bit
architectures, therefore directly using integer printf formats will not
work portably, use intmax_t to typecast time_t into printf family of
functions

Signed-off-by: Alexander Kanavin 
Signed-off-by: Khem Raj 
---
 debuginfod/debuginfod-client.c | 8 
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/debuginfod/debuginfod-client.c b/debuginfod/debuginfod-client.c
index c875ee62..afd223b3 100644
--- a/debuginfod/debuginfod-client.c
+++ b/debuginfod/debuginfod-client.c
@@ -231,7 +231,7 @@ debuginfod_config_cache(char *config_path,
   if (fd < 0)
 return -errno;
 
-  if (dprintf(fd, "%ld", cache_config_default_s) < 0)
+  if (dprintf(fd, "%jd", (intmax_t)cache_config_default_s) < 0)
 return -errno;
 }
 
@@ -239,7 +239,7 @@ debuginfod_config_cache(char *config_path,
   FILE *config_file = fopen(config_path, "r");
   if (config_file)
 {
-  if (fscanf(config_file, "%ld", &cache_config) != 1)
+  if (fscanf(config_file, "%jd", (intmax_t*)(&cache_config)) != 1)
 cache_config = cache_config_default_s;
   fclose(config_file);
 }
@@ -272,7 +272,7 @@ debuginfod_init_cache (char *cache_path, char 
*interval_path, char *maxage_path)
   if (fd < 0)
 return -errno;
 
-  if (dprintf(fd, "%ld", cache_clean_default_interval_s) < 0)
+  if (dprintf(fd, "%jd", (intmax_t)cache_clean_default_interval_s) < 0)
 return -errno;
 
   /* init max age config file.  */
@@ -280,7 +280,7 @@ debuginfod_init_cache (char *cache_path, char 
*interval_path, char *maxage_path)
   && (fd = open(maxage_path, O_CREAT | O_RDWR, DEFFILEMODE)) < 0)
 return -errno;
 
-  if (dprintf(fd, "%ld", cache_default_max_unused_age_s) < 0)
+  if (dprintf(fd, "%jd", (intmax_t)cache_default_max_unused_age_s) < 0)
 return -errno;
 
   return 0;
-- 
2.20.1



Re: [PATCH] debuginfod/debuginfod-client.c: correct string format on 32bit arches with 64bit time_t

2021-11-20 Thread Alexander Kanavin via Elfutils-devel
On Sat, 20 Nov 2021 at 05:13, Érico Nogueira  wrote:

> For what it's worth, most of the time64 support patches that I have seen
> use "%lld" and `long long` as the type for portable representation of
> time, instead of intmax_t, but each should work just as well as the
> other.
>

My original version did use %lld, but Khem tweaked it to use intmax_t.
Perhaps he can comment?


> Might be worth mentioning in the commit that musl 1.2.0 and above uses
> time64 on all platforms, and that glibc 2.34 has added support for
> time64 (which might be enabled by distro-wide CFLAGS), with possibly
> 2.35 or 2.36 making it enabled by default.
>

Yes, I can add that.


> This is the wrong fix, a temporary variable should be used. When time_t
> is still 32 bits, it means you can accidentally write out of bounds for
> times after 2038 on little endian plaforms; and on big endian platforms,
> it's always writing out of bounds (and *only out of bounds*, before
> 2038, so you can't even access the result of fscanf).
>
> Having now taken a second look at the code, I don't think this needs to
> be treated as time_t, anyway? cache_config is a `long`, and it's reading
> a max timeout value, which is unlikely to go beyond the hundreds of
> seconds... Given that the function returns an `int`, I'd even consider
> making `cache_config` an `int` directly.
>

I can fix this as well if Khem confirms.

Thanks for the review.

Alex


[PATCH] debuginfod/debuginfod-client.c: correct string format on 32bit arches with 64bit time_t

2021-11-21 Thread Alexander Kanavin via Elfutils-devel
From: Alexander Kanavin 

Use intmax_t to print time_t

time_t is platform dependent and some of architectures e.g.
x32, riscv32, arc use 64bit time_t even while they are 32bit
architectures, therefore directly using integer printf formats will not
work portably, use intmax_t to typecast time_t into printf family of
functions.

musl 1.2.0 and above uses time64 on all platforms; glibc 2.34 has added support 
for
time64 (which might be enabled by distro-wide CFLAGS), with possibly
2.35 or 2.36 making it enabled by default.

Use a plain int for scanning cache_config, as that's what the function
returns.

Signed-off-by: Alexander Kanavin 
Signed-off-by: Khem Raj 
---
 debuginfod/debuginfod-client.c | 10 +-
 1 file changed, 5 insertions(+), 5 deletions(-)

diff --git a/debuginfod/debuginfod-client.c b/debuginfod/debuginfod-client.c
index c875ee62..df9737d2 100644
--- a/debuginfod/debuginfod-client.c
+++ b/debuginfod/debuginfod-client.c
@@ -231,15 +231,15 @@ debuginfod_config_cache(char *config_path,
   if (fd < 0)
 return -errno;
 
-  if (dprintf(fd, "%ld", cache_config_default_s) < 0)
+  if (dprintf(fd, "%jd", (intmax_t)cache_config_default_s) < 0)
 return -errno;
 }
 
-  long cache_config;
+  int cache_config;
   FILE *config_file = fopen(config_path, "r");
   if (config_file)
 {
-  if (fscanf(config_file, "%ld", &cache_config) != 1)
+  if (fscanf(config_file, "%d", &cache_config) != 1)
 cache_config = cache_config_default_s;
   fclose(config_file);
 }
@@ -272,7 +272,7 @@ debuginfod_init_cache (char *cache_path, char 
*interval_path, char *maxage_path)
   if (fd < 0)
 return -errno;
 
-  if (dprintf(fd, "%ld", cache_clean_default_interval_s) < 0)
+  if (dprintf(fd, "%jd", (intmax_t)cache_clean_default_interval_s) < 0)
 return -errno;
 
   /* init max age config file.  */
@@ -280,7 +280,7 @@ debuginfod_init_cache (char *cache_path, char 
*interval_path, char *maxage_path)
   && (fd = open(maxage_path, O_CREAT | O_RDWR, DEFFILEMODE)) < 0)
 return -errno;
 
-  if (dprintf(fd, "%ld", cache_default_max_unused_age_s) < 0)
+  if (dprintf(fd, "%jd", (intmax_t)cache_default_max_unused_age_s) < 0)
 return -errno;
 
   return 0;
-- 
2.20.1



Re: [PATCH] debuginfod/debuginfod-client.c: correct string format on 32bit arches with 64bit time_t

2021-11-25 Thread Alexander Kanavin via Elfutils-devel
According to 'man 3 printf' %j appeared in glibc 2.1 and seems to be C99
feature. That's decidedly ancient.

And may I be allowed to suggest, unless elfutils is tested in upstream CI
with decade-old toolchains, you should not be considering its compatibility
with them.

Alex

On Thu, 25 Nov 2021 at 18:51, Frank Ch. Eigler  wrote:

> Hi -
>
> > Use intmax_t to print time_t
> > [...]
> > -  if (dprintf(fd, "%ld", cache_config_default_s) < 0)
> > +  if (dprintf(fd, "%jd", (intmax_t)cache_config_default_s) < 0)
> > [...]
>
> I'm not a compatibility specialist, but note that elfutils is sometimes
> built on decade-old toolchains, where use of %lld and (long long) would
> certainly work.  We have such in the code base already, whereas this would
> be the first %j.
>
> - FChE
>
>


Re: [PATCH] debuginfod/debuginfod-client.c: correct string format on 32bit arches with 64bit time_t

2021-12-05 Thread Alexander Kanavin via Elfutils-devel
I'm not sure; the point of this patch is simply to ensure debuginfod builds
everywhere without errors. Making the types consistent is perhaps better
done as a followup?

Alex

On Sun, 5 Dec 2021 at 21:31, Mark Wielaard  wrote:

> Hi,
>
> On Sun, Nov 21, 2021 at 11:14:11PM +0100, Alexander Kanavin via
> Elfutils-devel wrote:
> > From: Alexander Kanavin 
> >
> > Use intmax_t to print time_t
> >
> > time_t is platform dependent and some of architectures e.g.
> > x32, riscv32, arc use 64bit time_t even while they are 32bit
> > architectures, therefore directly using integer printf formats will not
> > work portably, use intmax_t to typecast time_t into printf family of
> > functions.
>
> OK, so there were some questions about whether using intmax_t and %jd
> are portable enough, but I think it is clear that everything these
> days support that. So that is good.
>
> > musl 1.2.0 and above uses time64 on all platforms; glibc 2.34 has added
> support for
> > time64 (which might be enabled by distro-wide CFLAGS), with possibly
> > 2.35 or 2.36 making it enabled by default.
> >
> > Use a plain int for scanning cache_config, as that's what the function
> > returns.
>
> So I think you are correct that printing/scanning/casting the time_t
> around is somewhat unfortunate because the size of time_t is not
> stable across architectures. Thanks for looking into this. I had no
> idea time_t was such a problematic data type.
>
> What makes it even more curious is that debuginfod_config_cache takes
> a long, not a time_t, while it is always called with a time_t
> argument. And then it returns an int... The result is interpreted as a
> negative errno number or is cast back to a time_t if it is positive.
>
> With this patch we write out the interval values "as big as possible"
> (intmax_t), but read it back in "as small as possible" (int). Would it
> make sense to also try to read it back in as intmax_t and then cast
> down to int? Or simply always cast down to int before writing it out,
> so reading and writing use the same data type?
>
> We seem to not expect these intervals to be much bigger than a week,
> so an int should always be big enough (even when stretched up to a
> whole year).
>
> Thanks,
>
> Mark
>


[PATCH] debuginfod/debuginfod-client.c: use long for cache time configurations

2021-12-09 Thread Alexander Kanavin via Elfutils-devel
time_t is platform dependent and some of architectures e.g.
x32, riscv32, arc use 64bit time_t even while they are 32bit
architectures, therefore directly using integer printf formats will not
work portably.

Use a plain long everywhere as the intervals are small enough
that it will not be problematic.

Signed-off-by: Alexander Kanavin 
---
 debuginfod/debuginfod-client.c | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/debuginfod/debuginfod-client.c b/debuginfod/debuginfod-client.c
index 9bf97bfc..024b0954 100644
--- a/debuginfod/debuginfod-client.c
+++ b/debuginfod/debuginfod-client.c
@@ -135,17 +135,17 @@ struct debuginfod_client
how frequently the cache should be cleaned. The file's st_mtime represents
the time of last cleaning.  */
 static const char *cache_clean_interval_filename = "cache_clean_interval_s";
-static const time_t cache_clean_default_interval_s = 86400; /* 1 day */
+static const long cache_clean_default_interval_s = 86400; /* 1 day */
 
 /* The cache_miss_default_s within the debuginfod cache specifies how
frequently the 000-permision file should be released.*/
-static const time_t cache_miss_default_s = 600; /* 10 min */
+static const long cache_miss_default_s = 600; /* 10 min */
 static const char *cache_miss_filename = "cache_miss_s";
 
 /* The cache_max_unused_age_s file within the debuginfod cache specifies the
the maximum time since last access that a file will remain in the cache.  */
 static const char *cache_max_unused_age_filename = "max_unused_age_s";
-static const time_t cache_default_max_unused_age_s = 604800; /* 1 week */
+static const long cache_default_max_unused_age_s = 604800; /* 1 week */
 
 /* Location of the cache of files downloaded from debuginfods.
The default parent directory is $HOME, or '/' if $HOME doesn't exist.  */
-- 
2.20.1



Re: [PATCH] debuginfod/debuginfod-client.c: correct string format on 32bit arches with 64bit time_t

2021-12-09 Thread Alexander Kanavin via Elfutils-devel
Alright, I just sent a patch that replaces time_t with long instead. I
tested it on x86, x86-x32, x86-64.

Alex

On Wed, 8 Dec 2021 at 16:31, Mark Wielaard  wrote:

> Hi Alexander,
>
> On Sun, 2021-12-05 at 21:45 +0100, Alexander Kanavin wrote:
> > I'm not sure; the point of this patch is simply to ensure debuginfod
> builds
> > everywhere without errors. Making the types consistent is perhaps better
> > done as a followup?
>
> I think the issue of the code not compiling in some environments is
> because of the inconsistent use of types. So I rather fix the build
> errors by fixing the used types than to simply cast the errors away.
>
> Cheers,
>
> Mark
>