From mboxrd@z Thu Jan  1 00:00:00 1970
Authentication-Results: passt.top; dmarc=pass (p=quarantine dis=none) header.from=redhat.com
Authentication-Results: passt.top;
	dkim=pass (1024-bit key; unprotected) header.d=redhat.com header.i=@redhat.com header.a=rsa-sha256 header.s=mimecast20190719 header.b=QQ5S90OP;
	dkim-atps=neutral
Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.133.124])
	by passt.top (Postfix) with ESMTPS id C18735A0008
	for <passt-dev@passt.top>; Fri, 28 Mar 2025 15:29:19 +0100 (CET)
DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com;
	s=mimecast20190719; t=1743172158;
	h=from:from:reply-to:subject:subject:date:date:message-id:message-id:
	 to:to:cc:cc:mime-version:mime-version:content-type:content-type:
	 content-transfer-encoding:content-transfer-encoding:
	 in-reply-to:in-reply-to:references:references;
	bh=K/NTrthXMavToQ+LXxhxbtNFLRaIjBu8/B5MwpNkaXM=;
	b=QQ5S90OPUY0iB0BjBh6tUlpWk/M9fRKziJhow/SrggYmNMQbqeENnpw1UvLSHi1F7qHgMB
	/gAezXZkC5k4WtJz7t+FbmnPiE8JbgfAqG75K6KuQ7N/RO3W+6/tUWr3hjnQwgy1abS0ls
	+20juJRFvQT4qI2+KaRUvOeBoJFlEZ0=
Received: from mail-wr1-f70.google.com (mail-wr1-f70.google.com
 [209.85.221.70]) by relay.mimecast.com with ESMTP with STARTTLS
 (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id
 us-mta-260-3Nls1H7JP-usJdTJh4GaIg-1; Fri, 28 Mar 2025 10:29:15 -0400
X-MC-Unique: 3Nls1H7JP-usJdTJh4GaIg-1
X-Mimecast-MFC-AGG-ID: 3Nls1H7JP-usJdTJh4GaIg_1743172153
Received: by mail-wr1-f70.google.com with SMTP id ffacd0b85a97d-39abdadb0f0so1256775f8f.0
        for <passt-dev@passt.top>; Fri, 28 Mar 2025 07:29:14 -0700 (PDT)
X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed;
        d=1e100.net; s=20230601; t=1743172153; x=1743776953;
        h=content-transfer-encoding:mime-version:organization:references
         :in-reply-to:message-id:subject:cc:to:from:date:x-gm-message-state
         :from:to:cc:subject:date:message-id:reply-to;
        bh=K/NTrthXMavToQ+LXxhxbtNFLRaIjBu8/B5MwpNkaXM=;
        b=MvB2HEOG4gIlBhKxrZkrHtBcYRw8gVpddCDCV5CSjFX1tqTkfbJ0z8Wuqz70HOGteE
         nm6KQKO214KLa8QU3pP76fqcILXEQhcG8OfQJHqwf4hkQtz0XePe7949f7KQXyuXIQS+
         Emm1kVzNBYfVT+aajl7J2BRuPXX/ltBl0JZurNnyb+Da+63s9+xk+2Mi8maZQkjxxHHZ
         qqCgyvCM5sRSxYPgMfJyZI+JD3Sy7sB9Dct8TeS7ZXDIHCCWJNo8nlvwNKB89NMsPuX5
         bSk7jWdiDrXZOnP1FdMKQFZkqjToF863iopH2Dvse85ChZozu3rXcPP5MBqCUbEvGCN/
         F48g==
X-Gm-Message-State: AOJu0YyKTGTkhRjPTzLzyV2T9/EEDV77XD4npLgD/f1F1oIqpTw0+4Yj
	uMW7npiTa47dkaTurXQ6DY8oxebHTiHFWWA0WsyMYJCDvEpPmTwG6w2d3BX4fV3gLyIphRsvfgS
	iattkAn1tTpwTEj19aEG0RtLK+aEjWYlguRtU2z0rHMSlvUPHuK/j+ZJzxw==
X-Gm-Gg: ASbGncuuOSlbCnqbMevEQfiiD9JsLs3R1nPbi8SWeQk0rmb8G3YImFcdzGAY8BddhAQ
	5j/eQsYCnfMLk+VmnMMiChoOb4Bdw7jQkOaDTV9y39rX0pgldQTpolVnEErJNA9/2J0Uu48Pms/
	/h2RK15EIowIUTrLzVBzAftjm9SuXkf8TZfEPqNX1IYY7ClnvRf30Tv5Of8qBInN5t/EOeM4Me/
	6/AC3K6nSBG2ARkkiIF/DuBa3+TtnjCKs8rvob/3ZGXijoZ8E34XRVWwRkKOFkckVa486sL3bBb
	ZnXk5zvnjtrAWEkrA/t1mFbhJys=
X-Received: by 2002:a05:6000:1a8d:b0:391:3b11:d604 with SMTP id ffacd0b85a97d-39ad178dac7mr7616662f8f.54.1743172152791;
        Fri, 28 Mar 2025 07:29:12 -0700 (PDT)
X-Google-Smtp-Source: AGHT+IG4T3ktzRv1B4Z1F/vbu9RI2bdvTVbFOfwfGdFiDuOCBTTu0njsdABUMmBdc6AelVeIiDidxg==
X-Received: by 2002:a05:6000:1a8d:b0:391:3b11:d604 with SMTP id ffacd0b85a97d-39ad178dac7mr7616637f8f.54.1743172152357;
        Fri, 28 Mar 2025 07:29:12 -0700 (PDT)
Received: from maya.myfinge.rs (ifcgrfdd.trafficplex.cloud. [2a10:fc81:a806:d6a9::1])
        by smtp.gmail.com with ESMTPSA id ffacd0b85a97d-39c0b79e0basm2790607f8f.63.2025.03.28.07.29.11
        (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256);
        Fri, 28 Mar 2025 07:29:11 -0700 (PDT)
Date: Fri, 28 Mar 2025 15:29:10 +0100
From: Stefano Brivio <sbrivio@redhat.com>
To: David Gibson <david@gibson.dropbear.id.au>
Subject: Re: [PATCH v2] pasta, passt-repair: Support multiple events per
 read() in inotify handlers
Message-ID: <20250328152910.19365ba8@elisabeth>
In-Reply-To: <20250328003958.3570775-1-david@gibson.dropbear.id.au>
References: <20250328003958.3570775-1-david@gibson.dropbear.id.au>
Organization: Red Hat
X-Mailer: Claws Mail 4.2.0 (GTK 3.24.41; x86_64-pc-linux-gnu)
MIME-Version: 1.0
X-Mimecast-Spam-Score: 0
X-Mimecast-MFC-PROC-ID: GGWciGWabBPFnJbJfN0HrAbvhOSPCOAz75taIhqnCt4_1743172153
X-Mimecast-Originator: redhat.com
Content-Type: text/plain; charset=US-ASCII
Content-Transfer-Encoding: 7bit
Message-ID-Hash: PH5OXZBU4AJL5AN5DDMOOBVP3WPM6LEI
X-Message-ID-Hash: PH5OXZBU4AJL5AN5DDMOOBVP3WPM6LEI
X-MailFrom: sbrivio@redhat.com
X-Mailman-Rule-Misses: dmarc-mitigation; no-senders; approved; emergency; loop; banned-address; member-moderation; nonmember-moderation; administrivia; implicit-dest; max-recipients; max-size; news-moderation; no-subject; digests; suspicious-header
CC: passt-dev@passt.top
X-Mailman-Version: 3.3.8
Precedence: list
List-Id: Development discussion and patches for passt <passt-dev.passt.top>
Archived-At: <https://archives.passt.top/passt-dev/20250328152910.19365ba8@elisabeth/>
Archived-At: <https://passt.top/hyperkitty/list/passt-dev@passt.top/message/PH5OXZBU4AJL5AN5DDMOOBVP3WPM6LEI/>
List-Archive: <https://archives.passt.top/passt-dev/>
List-Archive: <https://passt.top/hyperkitty/list/passt-dev@passt.top/>
List-Help: <mailto:passt-dev-request@passt.top?subject=help>
List-Owner: <mailto:passt-dev-owner@passt.top>
List-Post: <mailto:passt-dev@passt.top>
List-Subscribe: <mailto:passt-dev-join@passt.top>
List-Unsubscribe: <mailto:passt-dev-leave@passt.top>

On Fri, 28 Mar 2025 11:39:58 +1100
David Gibson <david@gibson.dropbear.id.au> wrote:

> From: Stefano Brivio <sbrivio@redhat.com>
> 
> The current code assumes that we'll get one event per read() on
> inotify descriptors, but that's not the case, not from documentation,
> and not from reports.
> 
> Add loops in the two inotify handlers we have, in pasta-specific code
> and passt-repair, to go through all the events we receive.
> 
> Link: https://bugs.passt.top/show_bug.cgi?id=119
> 
> Signed-off-by: Stefano Brivio <sbrivio@redhat.com>
> [dwg: Remove unnecessary buffer expansion, use strnlen instead of strlen
>  to make Coverity happier]

I have to admit I didn't know about strnlen(). POSIX.1-2008, that's
bleeding edge stuff. :)

That wasn't actually enough though: in my Coverity scan, it was also
complaining about:

> Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
> ---
>  passt-repair.c | 27 ++++++++++++++++++++-------
>  pasta.c        | 20 +++++++++++++-------
>  2 files changed, 33 insertions(+), 14 deletions(-)
> 
> diff --git a/passt-repair.c b/passt-repair.c
> index 120f7aa7..d36c9c94 100644
> --- a/passt-repair.c
> +++ b/passt-repair.c
> @@ -111,14 +111,14 @@ int main(int argc, char **argv)
>  	}
>  
>  	if ((sb.st_mode & S_IFMT) == S_IFDIR) {
> -		char buf[sizeof(struct inotify_event) + NAME_MAX + 1];
> +		char buf[sizeof(struct inotify_event) + NAME_MAX + 1]
> +		   __attribute__ ((aligned(__alignof__(struct inotify_event))));
>  		const struct inotify_event *ev;
>  		char path[PATH_MAX + 1];
> +		bool found = false;
>  		ssize_t n;
>  		int fd;
>  
> -		ev = (struct inotify_event *)buf;
> -
>  		if ((fd = inotify_init1(IN_CLOEXEC)) < 0) {
>  			fprintf(stderr, "inotify_init1: %i\n", errno);
>  			_exit(1);
> @@ -130,6 +130,8 @@ int main(int argc, char **argv)
>  		}
>  
>  		do {
> +			char *p;
> +
>  			n = read(fd, buf, sizeof(buf));
>  			if (n < 0) {
>  				fprintf(stderr, "inotify read: %i", errno);
> @@ -138,11 +140,22 @@ int main(int argc, char **argv)
>  
>  			if (n < (ssize_t)sizeof(*ev)) {
>  				fprintf(stderr, "Short inotify read: %zi", n);
> -				_exit(1);
> +				continue;
> +			}
> +
> +			for (p = buf; p < buf + n; p += sizeof(*ev) + ev->len) {
> +				ev = (const struct inotify_event *)p;
> +
> +				if (ev->len >= REPAIR_EXT_LEN &&
> +				    !memcmp(ev->name +
> +					    strnlen(ev->name, ev->len) -
> +					    REPAIR_EXT_LEN,
> +					    REPAIR_EXT, REPAIR_EXT_LEN)) {
> +					found = true;
> +					break;
> +				}
>  			}
> -		} while (ev->len < REPAIR_EXT_LEN ||
> -			 memcmp(ev->name + strlen(ev->name) - REPAIR_EXT_LEN,
> -				REPAIR_EXT, REPAIR_EXT_LEN));
> +		} while (!found);
>  
>  		snprintf(path, sizeof(path), "%s/%s", argv[1], ev->name);

...ev->name not being necessarily NULL-terminated and passed to
snprintf() here. So I applied this with an additional (and useless, unless
the kernel is unrealistically buggy):

		if (ev->len > NAME_MAX + 1 || ev->name[ev->len] != '\0') {
			fprintf(stderr, "Invalid filename from inotify\n");
			_exit(1);
		}

-- 
Stefano