From patchwork Tue Nov 18 18:21:18 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: "H. Peter Anvin" X-Patchwork-Id: 124666 Return-Path: X-Original-To: patchwork@sourceware.org Delivered-To: patchwork@sourceware.org Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id EAF75385842D for ; Tue, 18 Nov 2025 18:23:06 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org EAF75385842D Authentication-Results: sourceware.org; dkim=pass (2048-bit key, unprotected) header.d=zytor.com header.i=@zytor.com header.a=rsa-sha256 header.s=2025102301 header.b=qR3nSe/r X-Original-To: libc-alpha@sourceware.org Delivered-To: libc-alpha@sourceware.org Received: from mail.zytor.com (terminus.zytor.com [IPv6:2607:7c80:54:3::136]) by sourceware.org (Postfix) with ESMTPS id 0B2393858C40 for ; Tue, 18 Nov 2025 18:21:31 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org 0B2393858C40 Authentication-Results: sourceware.org; dmarc=pass (p=none dis=none) header.from=zytor.com Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=zytor.com ARC-Filter: OpenARC Filter v1.0.0 sourceware.org 0B2393858C40 Authentication-Results: server2.sourceware.org; arc=none smtp.remote-ip=2607:7c80:54:3::136 ARC-Seal: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1763490093; cv=none; b=tLpdalQxVxthRhPd4C4CFcUveDtetFg3mUbqhpCyhpe1ce+l9GRWNfqqQDz8lODyqonMSG+6PDKsnWGlxgnP/DLaM1+vSCn0WGZH9pmGuvIHUfvu9WKVJhAjMwdiGrUAMOrosOSo52N/jPDFbXgSkIcpg/QiQlKr9s8AOvsOCY0= ARC-Message-Signature: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1763490093; c=relaxed/simple; bh=lfbf0HnjTftnr4tTNPU+6v0jTHVpqALMMyDWcLclMMM=; h=DKIM-Signature:From:To:Subject:Date:Message-ID:MIME-Version; b=FshA3ugEknHMnXFNn+z49kDKu6U/rfDGyZM4v/BS430d0oJ36cnY1t8PClSwjdFbrPQzL87eRL8YBQ8XA5OG8xx3aH36JAa6blKVYASxEpxQotcv5KZVWyhh3XWTMJgLpIrkhOgVh3L96hixqYmuZoGbghRvjyO+o3V5gdglAwI= ARC-Authentication-Results: i=1; server2.sourceware.org DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 0B2393858C40 Received: from mail.zytor.com ([IPv6:2601:646:8081:9484:7ccc:663a:75c9:3b5f]) (authenticated bits=0) by mail.zytor.com (8.18.1/8.17.1) with ESMTPSA id 5AIILPLV965602 (version=TLSv1.3 cipher=TLS_AES_256_GCM_SHA384 bits=256 verify=NO); Tue, 18 Nov 2025 10:21:27 -0800 DKIM-Filter: OpenDKIM Filter v2.11.0 mail.zytor.com 5AIILPLV965602 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=zytor.com; s=2025102301; t=1763490088; bh=9s/wBLK6ZOXRPqIbdTa2/Q1XDic/an6hmcQ7aXzZSdE=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=qR3nSe/rzB+8l3UiswVf7rxtijKofrKPWPiKpsmN+Os38Kg7kLKKZCYJZa6Hhx68z AK9Qbh+0ZRWtkjiM27fBdfll/R5x9zDbY7DnnkShyhOhKSoxIWLGLZbbXlE3VuVmlB s/Y8KlmbTMHUMKmPrRA5ACJlEyy89vZQSAN06gRQSA1DzhChIwM4Taj5CZBGkv1sGP rxt6jigTpkFDPiHKwDjALgQ22wdDtRzjpPkOr+RB+m+6pFSZS0c/42xfmBzoIo48TT vwOMNUTv7HobpNwUFCRABdsaVXP1wi+T8BW9PTDRypI17Gjdtzao84lincir8oRdy4 cmxJl8RIzdUJA== From: "H. Peter Anvin" To: GNU C Library Cc: "H. Peter Anvin" , Collin Funk , Adhemerval Zanella , Florian Weimer , "H.J. Lu" Subject: [PATCH v4 1/1] linux/termios: test the kernel-side termios canonicalization Date: Tue, 18 Nov 2025 10:21:18 -0800 Message-ID: <20251118182120.2450549-2-hpa@zytor.com> X-Mailer: git-send-email 2.51.1 In-Reply-To: <20251118182120.2450549-1-hpa@zytor.com> References: <20251118182120.2450549-1-hpa@zytor.com> MIME-Version: 1.0 X-Spam-Status: No, score=-10.9 required=5.0 tests=BAYES_00, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, GIT_PATCH_0, SPF_HELO_PASS, SPF_PASS, TXREP autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on server2.sourceware.org X-BeenThere: libc-alpha@sourceware.org X-Mailman-Version: 2.1.30 Precedence: list List-Id: Libc-alpha mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: libc-alpha-bounces~patchwork=sourceware.org@sourceware.org Verify that the kernel side of the termios interface gets the various speed fields set according to our current canonicalization policy. [ v2.1: fix formatting - Adhemerval Netto ] [ v4: fix typo in patch description - Dan HorĂ¡k ] Signed-off-by: H. Peter Anvin (Intel) Reviewed-by: Adhemerval Zanella (v2.1) Reviewed-by: H.J. Lu --- sysdeps/unix/sysv/linux/tst-termios-linux.c | 61 ++++++++++++++++++++- 1 file changed, 58 insertions(+), 3 deletions(-) diff --git a/sysdeps/unix/sysv/linux/tst-termios-linux.c b/sysdeps/unix/sysv/linux/tst-termios-linux.c index e4b0c8bcd6ed..80ba9e885363 100644 --- a/sysdeps/unix/sysv/linux/tst-termios-linux.c +++ b/sysdeps/unix/sysv/linux/tst-termios-linux.c @@ -38,6 +38,8 @@ #include #include +#include /* Definitions for the raw ioctl interface */ + /* Evaluate an expression and make sure errno did not get set; return the value of the expression */ #define CHECKERR(expr) \ @@ -226,13 +228,66 @@ static void check_speeds_cf (const struct termios *tio_p, CHECKERR (cfgetibaud (tio_p)), 'i'); } -/* Use this after tc[gs]etattr () */ +/* Access the raw kernel interface and verify that the result is + canonicalized properly; this should be run after tcsetattr (). */ +static void +check_speeds_kernel (int fd, speed_t ospeed, speed_t ispeed) +{ + struct termios2 k_termios; + tcflag_t expect_cbaud = speed_to_cbaud (ospeed); + tcflag_t expect_cibaud; + + if (!ispeed) + ispeed = ospeed; + + /* If ospeed == ispeed, tcsetattr() should set the kernel CIBAUD to 0, + for compatibility with programs that use the direct ioctl interface + but fail to account for CIBAUD. c_ispeed should still be correct. */ + if (ospeed == ispeed) + expect_cibaud = 0; + else + expect_cibaud = speed_to_cbaud (ispeed); + + memset (&k_termios, 0xed, sizeof k_termios); /* Fill with nonsense */ + CHECKZERO (ioctl(fd, TCGETS2, &k_termios)); + + tcflag_t k_cbaud = k_termios.c_cflag & CBAUD; + tcflag_t k_cibaud = (k_termios.c_cflag >> IBSHIFT) & CBAUD; + + if (k_termios.c_ospeed != ospeed) + FAIL ("opeed %u ispeed %u: kernel c_ospeed = %u, expected %u", + ospeed, ispeed, + k_termios.c_ospeed, ospeed); + + if (k_cbaud != expect_cbaud) + FAIL ("ospeed %u ispeed %u: kernel CBAUD = %s (%06o), expected %s (%06o)", + ospeed, ispeed, + cbaud_name (k_cbaud), k_cbaud, + cbaud_name (expect_cbaud), expect_cbaud); + + if (k_termios.c_ispeed != ispeed) + FAIL ("ospeed %u ispeed %u: kernel c_ispeed == %u, expected %u", + ospeed, ispeed, + k_termios.c_ispeed, ispeed); + + if (k_cibaud != expect_cibaud) + FAIL ("ospeed %u ispeed %u: kernel CIBAUD = %s (%06o), expected %s (%06o)", + ospeed, ispeed, + cbaud_name (k_cibaud), k_cibaud, + cbaud_name (expect_cibaud), expect_cibaud); +} + +/* Use this after tcsetattr () */ static void check_speeds_tc (int fd, speed_t ospeed, speed_t ispeed) { struct termios tio; + if (!ispeed) + ispeed = ospeed; + CHECKZERO (tcgetattr (fd, &tio)); - check_speeds_cf (&tio, ospeed, ispeed ? ispeed : ospeed); + check_speeds_cf (&tio, ospeed, ispeed); + check_speeds_kernel (fd, ospeed, ispeed); } /* For search and replace convenience */ @@ -250,7 +305,7 @@ set_speeds (int fd, speed_t ospeed, speed_t ispeed) CHECKZERO (cfsetispeed (&tio, ispeed)); check_speeds_cf (&tio, ospeed, ispeed); CHECKZERO (tcsetattr (fd, TCSANOW, &tio)); - check_speeds_tc (fd, ospeed, ispeed ? ispeed : ospeed); + check_speeds_tc (fd, ospeed, ispeed); } /* Actual tests */