CCing Martin.

On Sat, Jan 15, 2022 at 09:04:35AM +0000, Richard W.M. Jones wrote:
> There is a new warning in gcc-12.0.0-0.4.fc36.x86_64.  In this code:
> 
>   int
>   guestfs_int_create_socketname (guestfs_h *g, const char *filename,
>                                  char (*sockpath)[UNIX_PATH_MAX])
>   {
>     if (guestfs_int_lazy_make_sockdir (g) == -1)
>       return -1;
>   
>     if (strlen (g->sockdir) + 1 + strlen (filename) > UNIX_PATH_MAX-1) {
>       error (g, _("socket path too long: %s/%s"), g->sockdir, filename);
>       return -1;
>     }
>   
>     snprintf (*sockpath, UNIX_PATH_MAX, "%s/%s", g->sockdir, filename);
>   
>     return 0;
>   }
> 
> [https://github.com/libguestfs/libguestfs/blob/d1e7e1a323619d8f1e913a7833d07009f02a2d33/lib/launch.c#L324]
> 
> the new warning is:
> 
>   launch.c: In function ‘guestfs_int_create_socketname’:
>   launch.c:336:43: error: ‘%s’ directive output may be truncated writing up 
> to 106 bytes into a region of size between 1 and 107 
> [-Werror=format-truncation=]
>     336 |   snprintf (*sockpath, UNIX_PATH_MAX, "%s/%s", g->sockdir, 
> filename);
>         |                                           ^~
>   In file included from /usr/include/stdio.h:894,
>                    from launch.c:30:
>   In function ‘snprintf’,
>       inlined from ‘guestfs_int_create_socketname’ at launch.c:336:3:
> /usr/include/bits/stdio2.h:71:10: note: ‘__snprintf_chk’ output between 2 and 
> 2  14 bytes into a destination of size 108
>      71 |   return __builtin___snprintf_chk (__s, __n, __USE_FORTIFY_LEVEL - 
> 1,
>         |          
> ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
>      72 |                                    __glibc_objsize (__s), __fmt,
>         |                                    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
>      73 |                                    __va_arg_pack ());
>         |                                    ~~~~~~~~~~~~~~~~~
>   cc1: all warnings being treated as errors
> 
> *sockpath is a fixed buffer of size UNIX_PATH_MAX == 108.  We check
> that strlen (g->sockdir) + strlen (filename) + 1 (for the '/'
> character) > UNIX_PATH_MAX - 1 (for the terminating '\0').
> 
> The check seems correct as far as I can tell.  I don't think I'm
> making a fencepost error here.  Why does GCC 12 think there should be
> a warning when GCC 11 didn't?
> 
> I've attached a standalone test case.
> 
>   $ gcc -O2 -Wall sp.c -o sp
>   sp.c: In function ‘create_sockpath’:
>   sp.c:12:43: warning: ‘%s’ directive output may be truncated writing up to 
> 106 bytes into a region of size between 1 and 107 [-Wformat-truncation=]
>      12 |   snprintf (*sockpath, UNIX_PATH_MAX, "%s/%s", sockdir, filename);
>         |                                           ^~
>   sp.c:12:3: note: ‘snprintf’ output between 2 and 214 bytes into a 
> destination of size 108
>      12 |   snprintf (*sockpath, UNIX_PATH_MAX, "%s/%s", sockdir, filename);
>         |   ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
> 
> (No warning with gcc-11.2.1-1.fc35.x86_64)
> 
> Rich.
> 
> -- 
> Richard Jones, Virtualization Group, Red Hat http://people.redhat.com/~rjones
> Read my programming and virtualization blog: http://rwmj.wordpress.com
> virt-p2v converts physical machines to virtual machines.  Boot with a
> live CD or over the network (PXE) and turn machines into KVM guests.
> http://libguestfs.org/virt-v2v

> /* gcc -O2 -Wall sp.c -o sp */
> 
> #include <stdio.h>
> #include <stdlib.h>
> #include <string.h>
> #include <linux/un.h>
> 
> void
> create_sockpath (const char *sockdir, const char *filename,
>                  char (*sockpath)[UNIX_PATH_MAX])
> {
>   if (strlen (sockdir) + 1 + strlen (filename) > UNIX_PATH_MAX - 1)
>     abort ();
>   snprintf (*sockpath, UNIX_PATH_MAX, "%s/%s", sockdir, filename);
> }
> 
> int
> main (int argc, char *argv[])
> {
>   char sockpath[UNIX_PATH_MAX];
> 
>   if (argc != 3) {
>     fprintf (stderr, "%s sockdir filename\n", argv[0]);
>     exit (EXIT_FAILURE);
>   }
> 
>   create_sockpath (argv[1], argv[2], &sockpath);
>   printf ("sockpath = %s\n", sockpath);
>   exit (EXIT_SUCCESS);
> }

        Jakub
_______________________________________________
devel mailing list -- devel@lists.fedoraproject.org
To unsubscribe send an email to devel-le...@lists.fedoraproject.org
Fedora Code of Conduct: 
https://docs.fedoraproject.org/en-US/project/code-of-conduct/
List Guidelines: https://fedoraproject.org/wiki/Mailing_list_guidelines
List Archives: 
https://lists.fedoraproject.org/archives/list/devel@lists.fedoraproject.org
Do not reply to spam on the list, report it: 
https://pagure.io/fedora-infrastructure

Reply via email to