Re: [PATCH] ioctl_ns.2, stat.2: Fix signedness of printf specifiers

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Hi Alex,

On 9/23/20 4:54 PM, Alejandro Colomar wrote:
> These variables are either of an unsigned integer type per POSIX;
> or of an integer type per POSIX, that Linux defines as an unsigned integer type.
> 
> Print them with 'uintmax_t' instead of 'intmax_t' to avoid
> big positive numbers being printed as negative numbers.
> 
> Bug report:
> From: Konstantin Bukin @ 2020-09-13 15:04 UTC
>   To: mtk.manpages; +Cc: Konstantin Bukin, linux-man
> 
> inode numbers are expected to be positive. Casting them to a signed type
> may result in printing negative values. E.g. running example program on
> the following file:
> 
> $ ls -li test.txt
> 9280843260537405888 -r--r--r-- 1 kbukin hardware 300 Jul 21 06:36 test.txt
> 
> resutls in the following output:
> 
> $ ./example test.txt
> ID of containing device:  [0,480]
> File type:                regular file
> I-node number:            -9165900813172145728
> Mode:                     100444 (octal)
> Link count:               1
> Ownership:                UID=2743   GID=30
> Preferred I/O block size: 32768 bytes
> File size:                300 bytes
> Blocks allocated:         8
> Last status change:       Tue Jul 21 06:36:50 2020
> Last file access:         Sat Sep 12 14:13:38 2020
> Last file modification:   Tue Jul 21 06:36:50 2020
> 
> Such erroneous reporting happens for inode values greater than maximum
> value which can be stored in signed long. Casting does not seem to be
> necessary here. Printing inode as unsigned long fixes the issue.
> 
> Reported-by: Konstantin Bukin <kbukin@xxxxxxxxx>
> Signed-off-by: Alejandro Colomar <colomar.6.4.3@xxxxxxxxx>

Thanks! Patch applied.

Cheers,

Michael

> ---
> 
> Hi Michael,
> 
> I wrote a patch similar to Konstantin's patch,
> but using `uintmax_t` as we discussed.
> I further fixed a few more cases of incorrect casts.
> I found all of those related to `struct stat`'s members,
> but there may be more incorrect casts out there.
> 
> Cheers,
> 
> Alex
> 
>  man2/ioctl_ns.2 | 8 ++++----
>  man2/stat.2     | 8 ++++----
>  2 files changed, 8 insertions(+), 8 deletions(-)
> 
> diff --git a/man2/ioctl_ns.2 b/man2/ioctl_ns.2
> index b83db74e0..87b5168a7 100644
> --- a/man2/ioctl_ns.2
> +++ b/man2/ioctl_ns.2
> @@ -317,10 +317,10 @@ main(int argc, char *argv[])
>              exit(EXIT_FAILURE);
>          }
>          printf("Device/Inode of owning user namespace is: "
> -                "[%jx,%jx] / %jd\en",
> +                "[%jx,%jx] / %ju\en",
>                  (uintmax_t) major(sb.st_dev),
>                  (uintmax_t) minor(sb.st_dev),
> -                (intmax_t) sb.st_ino);
> +                (uintmax_t) sb.st_ino);
>  
>          close(userns_fd);
>      }
> @@ -347,10 +347,10 @@ main(int argc, char *argv[])
>              perror("fstat\-parentns");
>              exit(EXIT_FAILURE);
>          }
> -        printf("Device/Inode of parent namespace is: [%jx,%jx] / %jd\en",
> +        printf("Device/Inode of parent namespace is: [%jx,%jx] / %ju\en",
>                  (uintmax_t) major(sb.st_dev),
>                  (uintmax_t) minor(sb.st_dev),
> -                (intmax_t) sb.st_ino);
> +                (uintmax_t) sb.st_ino);
>  
>          close(parent_fd);
>      }
> diff --git a/man2/stat.2 b/man2/stat.2
> index f71cc3831..13a1f37f7 100644
> --- a/man2/stat.2
> +++ b/man2/stat.2
> @@ -682,14 +682,14 @@ main(int argc, char *argv[])
>      default:       printf("unknown?\en");                break;
>      }
>  
> -    printf("I\-node number:            %jd\en", (intmax_t) sb.st_ino);
> +    printf("I\-node number:            %ju\en", (uintmax_t) sb.st_ino);
>  
>      printf("Mode:                     %jo (octal)\en",
>              (uintmax_t) sb.st_mode);
>  
> -    printf("Link count:               %jd\en", (intmax_t) sb.st_nlink);
> -    printf("Ownership:                UID=%jd   GID=%jd\en",
> -            (intmax_t) sb.st_uid, (intmax_t) sb.st_gid);
> +    printf("Link count:               %ju\en", (uintmax_t) sb.st_nlink);
> +    printf("Ownership:                UID=%ju   GID=%ju\en",
> +            (uintmax_t) sb.st_uid, (uintmax_t) sb.st_gid);
>  
>      printf("Preferred I/O block size: %jd bytes\en",
>              (intmax_t) sb.st_blksize);
> 


-- 
Michael Kerrisk
Linux man-pages maintainer; http://www.kernel.org/doc/man-pages/
Linux/UNIX System Programming Training: http://man7.org/training/



[Index of Archives]     [Kernel Documentation]     [Netdev]     [Linux Ethernet Bridging]     [Linux Wireless]     [Kernel Newbies]     [Security]     [Linux for Hams]     [Netfilter]     [Bugtraq]     [Yosemite News]     [MIPS Linux]     [ARM Linux]     [Linux RAID]     [Linux Admin]     [Samba]

  Powered by Linux