Message ID | 20240209150657.1.I45addf7579e1233fa97c05ba72120cd1c57b4310@changeid |
---|---|
State | New |
Headers |
Return-Path: <linux-kernel+bounces-60135-ouuuleilei=gmail.com@vger.kernel.org> Delivered-To: ouuuleilei@gmail.com Received: by 2002:a05:7300:50ea:b0:106:860b:bbdd with SMTP id r10csp1182911dyd; Fri, 9 Feb 2024 15:07:58 -0800 (PST) X-Forwarded-Encrypted: i=3; AJvYcCWz2jlx4qPtyiNF2CjS8PMbDN5e6wRJeoSWJboMtuxki/Wvwh+TjKaQHqJgZtoW+IaIoebc4Q+io16ppFcy3QzdlnXlcw== X-Google-Smtp-Source: AGHT+IE6Nr3baW9HYLB7hBGSARh/pyoOGYpBpN+po4dihc9jRLcSmD9SAhAaFfp65JveOu1Gdhd0 X-Received: by 2002:a17:906:9815:b0:a37:e33b:816a with SMTP id lm21-20020a170906981500b00a37e33b816amr315930ejb.26.1707520078706; Fri, 09 Feb 2024 15:07:58 -0800 (PST) ARC-Seal: i=2; a=rsa-sha256; t=1707520078; cv=pass; d=google.com; s=arc-20160816; b=SP9t+/mGH0sy8+VjysRIEcA3RXNSWyaSY4lIRO5DKz27bQpcbFu2Yzah0FUFAdCkG8 MwQUwrSkQx5pKRZMEl6Shms3RLGYIBNcdEpt9u3x8dCl0fJXBJreOfadhJz6wzO06wGz SYVQ1B0wsDZvbYXAAyX73gXaJVblm774YlGu5t89NU3WPeE1RKde0dIl6mhsenyKhDCK DL6m9m0TlsACxVrzaQH7M9R6RDm8HCg4BL9tNmuJ2PwwEDKBQCEBFpmUcKjAxNSC0aTG JiAXT88Erd8Z3G3tB7ixps36wKhlCxX3gmzG9xAvhozSvmH7GvoI8VxG8aI5JgBNgASS FF1Q== ARC-Message-Signature: i=2; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=content-transfer-encoding:mime-version:list-unsubscribe :list-subscribe:list-id:precedence:message-id:date:subject:cc:to :from:dkim-signature; bh=Z0AAKh3Wo2mucOY5wb8UuYlu0VE8Lc/bx4O9HZBol2Y=; fh=+e/d6hM6ncF0jUJyO59L0ALpcq+m/VBEwSryPobpb1M=; b=de4kFjcTKVLzOchZSWTdw8J1FW6sN8BD35R/azrRQac2AOOyBbCfIzrJ7h2ySATWeG YoPH7fvW8hTar4IUczEUaENsveRthJ7pT4cVW1Q5JQLHnzhVyMmVsg4Z4/2ywjx9WMF3 PkpJ964wHSkuRQ/RQlFwQZ9AlQOCuBMKz5mOde0CeOODLbPBGzv9wyDX7jYpo400u5hz VU+9dobU8uHhHjcTNOShNzyESC4J74wHUiUIPYJORuwgpxO02mJFUYrRQuw7GuBZgvnt /DzIv2WFdLhb/olG/W1ywUi2sNRYtvbMnuSc12mg/4iJltXbmORyX6mCvnRHf/BO4thA gFXA==; dara=google.com ARC-Authentication-Results: i=2; mx.google.com; dkim=pass header.i=@chromium.org header.s=google header.b=WJfR1ahq; arc=pass (i=1 spf=pass spfdomain=chromium.org dkim=pass dkdomain=chromium.org dmarc=pass fromdomain=chromium.org); spf=pass (google.com: domain of linux-kernel+bounces-60135-ouuuleilei=gmail.com@vger.kernel.org designates 147.75.80.249 as permitted sender) smtp.mailfrom="linux-kernel+bounces-60135-ouuuleilei=gmail.com@vger.kernel.org"; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=chromium.org X-Forwarded-Encrypted: i=2; AJvYcCWG5QqtQRIlU9kAiBJoBvoos54Gn+baZZQ+B1RVp6LMIvGx5OpZoFoTKc2gcoaqvEAUmGsv4HFgJAjbV0TYmh6hvfp5zA== Received: from am.mirrors.kernel.org (am.mirrors.kernel.org. [147.75.80.249]) by mx.google.com with ESMTPS id hp18-20020a1709073e1200b00a36730b50acsi1363120ejc.348.2024.02.09.15.07.58 for <ouuuleilei@gmail.com> (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 09 Feb 2024 15:07:58 -0800 (PST) Received-SPF: pass (google.com: domain of linux-kernel+bounces-60135-ouuuleilei=gmail.com@vger.kernel.org designates 147.75.80.249 as permitted sender) client-ip=147.75.80.249; Authentication-Results: mx.google.com; dkim=pass header.i=@chromium.org header.s=google header.b=WJfR1ahq; arc=pass (i=1 spf=pass spfdomain=chromium.org dkim=pass dkdomain=chromium.org dmarc=pass fromdomain=chromium.org); spf=pass (google.com: domain of linux-kernel+bounces-60135-ouuuleilei=gmail.com@vger.kernel.org designates 147.75.80.249 as permitted sender) smtp.mailfrom="linux-kernel+bounces-60135-ouuuleilei=gmail.com@vger.kernel.org"; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=chromium.org Received: from smtp.subspace.kernel.org (wormhole.subspace.kernel.org [52.25.139.140]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by am.mirrors.kernel.org (Postfix) with ESMTPS id 2E6BE1F25B70 for <ouuuleilei@gmail.com>; Fri, 9 Feb 2024 23:07:58 +0000 (UTC) Received: from localhost.localdomain (localhost.localdomain [127.0.0.1]) by smtp.subspace.kernel.org (Postfix) with ESMTP id 4D978381BF; Fri, 9 Feb 2024 23:07:44 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=chromium.org header.i=@chromium.org header.b="WJfR1ahq" Received: from mail-pl1-f179.google.com (mail-pl1-f179.google.com [209.85.214.179]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 18A0836AE3 for <linux-kernel@vger.kernel.org>; Fri, 9 Feb 2024 23:07:39 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.214.179 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1707520061; cv=none; b=TM/x9YDb2wCAZIhAlpDldmzNMWNZCMcdK6Xa2cKSWGlaIir+apMUJAjy47l3T7Fysd9j8C3p4qFP7lb9R2TDzueWByP48hW0XUn+qjy5CfeyB9hb1bbWHIG6Ijkr7QzAj7kxLcVjeBj49kY/H7PH6L83kHj/peWDLT3TnlsEGRc= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1707520061; c=relaxed/simple; bh=8HElzopGcSrPzjmzDlv/HH9iotHcogieQOgXsP+RqXg=; h=From:To:Cc:Subject:Date:Message-ID:MIME-Version; b=G2Kl4ws0LX/obKqIfUgdAwy/o+N8eZ0I4TnVgi3y4PlpTwnh2cpbBW1d5tqJFmaRLpTOgx7Yee72FWr9Gk+s/MGPm2TG8QsLHrdd+W4ay7+Gx2VJWqYKt/1D9MLXNp7Potb1ZV7rO87u5Z7fc2M+LRYTLoGRqkMpI2076KwgV6M= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=chromium.org; spf=pass smtp.mailfrom=chromium.org; dkim=pass (1024-bit key) header.d=chromium.org header.i=@chromium.org header.b=WJfR1ahq; arc=none smtp.client-ip=209.85.214.179 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=chromium.org Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=chromium.org Received: by mail-pl1-f179.google.com with SMTP id d9443c01a7336-1d8aadc624dso12541135ad.0 for <linux-kernel@vger.kernel.org>; Fri, 09 Feb 2024 15:07:39 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=chromium.org; s=google; t=1707520059; x=1708124859; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:message-id:date:subject:cc :to:from:from:to:cc:subject:date:message-id:reply-to; bh=Z0AAKh3Wo2mucOY5wb8UuYlu0VE8Lc/bx4O9HZBol2Y=; b=WJfR1ahqD8O7oAh+zpfWEx8wGoaOu9O6fC/fpWhSzc4pnxsbWZm2LBenJBevTdADgs xqFfSgqK4GITzO3c17nAnExv8T6WhcHtPbSvM5WJvkb9Zcw8eE9P5ybT5ID6H91R6Ejz EWbYTJiXiTKCLeAA4r+B4lnyQuYsIgpN8o4+E= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1707520059; x=1708124859; h=content-transfer-encoding:mime-version:message-id:date:subject:cc :to:from:x-gm-message-state:from:to:cc:subject:date:message-id :reply-to; bh=Z0AAKh3Wo2mucOY5wb8UuYlu0VE8Lc/bx4O9HZBol2Y=; b=oSQwSh9/J9eReBOMCDiOukiLWecvKU9YypNHUAQYJ5xIPymfcT5xo5CdsZ7vODuhtY 7kD74OxqldZESKLV6XoMBR/sKR52IExRrCcOLF/fBnGNR9PVdG+I0Y0BEA9B80SAdWHQ DdE61At/KT2f+jhoLnXj1hRKDrDSuMEr+XhgtJN7Ix5VPAFO8nzyfQiC/YoVOYvoEZvm 3M14Abe0AODXiOb1PZZWWVdXXC0BXNQYqJ+ymc9jlve+8dt7gnbfcBkUnqw9KjpQv+Dj OMkpOXGDJqAqPDrNeGKjiC5bZbWWx2xn4G8DJioYAC0lX0IOJayUp8UYtmm4Nd2rJrzm 7Bow== X-Gm-Message-State: AOJu0Yx5OfF9HCH9Y0G4wREDph10UOL0uLqABM0k+ZTkx0e7L6j9aq2o zSj2BbP+ao4OKTTuRA4uWtNuUO3Z2BA4y6R1nDmtfEyeU6Sn46IvbFON+RtsxeWRXEnZ43sc4YI = X-Received: by 2002:a17:903:3287:b0:1d8:ef8d:a7ec with SMTP id jh7-20020a170903328700b001d8ef8da7ecmr791832plb.2.1707520059124; Fri, 09 Feb 2024 15:07:39 -0800 (PST) X-Forwarded-Encrypted: i=1; AJvYcCVDE5Zm1a3P2M31ED2lYDsdVKWUiifBjfeD9GUtliSejJJrynoU9gkJUtoO6XXHnS1vOPr3E8JFge1ePG6ubgi4reDU62++bgfk8yAPJ5T/zMpnyWMmMD/NQdfb9XF6iA3IS9xdiVJ/EQObB3hAWcZ3wQqGeh47uF7AXwWWMUMUU2zpOeT2tSu2yvD50s3puYpYrIg+oVKUWO5IlGivHe/z3+FnkoQVIkzglH5cV0DRHdzWwWGKGVrcMBjwOcX8buRSldvAWrYvORxpkWt+NZP8eF5uXIDgmuVmTtiCPStVX89vIUqfAax0gMHLF5ZYqTzLtFqqZItDNIJ8KqYgxIZLk4yhng== Received: from localhost (209.148.168.34.bc.googleusercontent.com. [34.168.148.209]) by smtp.gmail.com with UTF8SMTPSA id v7-20020a170902b7c700b001d989dd19b0sm1988210plz.140.2024.02.09.15.07.38 (version=TLS1_3 cipher=TLS_AES_128_GCM_SHA256 bits=128/128); Fri, 09 Feb 2024 15:07:38 -0800 (PST) From: Abhishek Pandit-Subedi <abhishekpandit@chromium.org> To: linux-kernel@vger.kernel.org Cc: David.Laight@ACULAB.COM, pmalani@chromium.org, andriy.shevchenko@linux.intel.com, keescook@chromium.org, torvalds@linux-foundation.org, Abhishek Pandit-Subedi <abhishekpandit@chromium.org>, Andrew Morton <akpm@linux-foundation.org>, Herve Codina <herve.codina@bootlin.com>, "Matthew Wilcox (Oracle)" <willy@infradead.org> Subject: [PATCH] minmax: Add notes to min_t and max_t Date: Fri, 9 Feb 2024 15:07:02 -0800 Message-ID: <20240209150657.1.I45addf7579e1233fa97c05ba72120cd1c57b4310@changeid> X-Mailer: git-send-email 2.43.0.687.g38aa6559b0-goog Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: <linux-kernel.vger.kernel.org> List-Subscribe: <mailto:linux-kernel+subscribe@vger.kernel.org> List-Unsubscribe: <mailto:linux-kernel+unsubscribe@vger.kernel.org> MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-getmail-retrieved-from-mailbox: INBOX X-GMAIL-THRID: 1790464573807353126 X-GMAIL-MSGID: 1790464573807353126 |
Series |
minmax: Add notes to min_t and max_t
|
|
Commit Message
Abhishek Pandit-Subedi
Feb. 9, 2024, 11:07 p.m. UTC
Both min_t and max_t are problematic as they can hide issues when
comparing differently sized types (and especially differently signed
types). Update the comments to nudge users to other options until
there is a better fix for these macros.
Link: https://lore.kernel.org/all/01e3e09005e9434b8f558a893a47c053@AcuMS.aculab.com/
Link: https://lore.kernel.org/all/CAHk-=whwEAc22wm8h9FESPB5X+P4bLDgv0erBQMa1buTNQW7tA@mail.gmail.com/
Signed-off-by: Abhishek Pandit-Subedi <abhishekpandit@chromium.org>
---
Andy Shevchenko made me aware of this particular footgun in
https://lore.kernel.org/linux-usb/ZcZ_he1jYx8w57mK@smile.fi.intel.com/.
While David + others work on the full fix, I'm hoping to apply a
bandaid in the form of comments so the problem doesn't get worse by devs
(**cough** me **cough**) inadvertently doing the wrong thing.
include/linux/minmax.h | 16 ++++++++++++++++
1 file changed, 16 insertions(+)
Comments
On Fri, Feb 09, 2024 at 03:07:02PM -0800, Abhishek Pandit-Subedi wrote: > Both min_t and max_t are problematic as they can hide issues when > comparing differently sized types (and especially differently signed > types). Update the comments to nudge users to other options until > there is a better fix for these macros. > > Link: https://lore.kernel.org/all/01e3e09005e9434b8f558a893a47c053@AcuMS.aculab.com/ > Link: https://lore.kernel.org/all/CAHk-=whwEAc22wm8h9FESPB5X+P4bLDgv0erBQMa1buTNQW7tA@mail.gmail.com/ > > Signed-off-by: Abhishek Pandit-Subedi <abhishekpandit@chromium.org> > --- > Andy Shevchenko made me aware of this particular footgun in > https://lore.kernel.org/linux-usb/ZcZ_he1jYx8w57mK@smile.fi.intel.com/. > > While David + others work on the full fix, I'm hoping to apply a > bandaid in the form of comments so the problem doesn't get worse by devs > (**cough** me **cough**) inadvertently doing the wrong thing. I think a better example for the docs would be something like u16 (rather than size_t) which shows very quickly the potential for truncation. See, for example: https://lore.kernel.org/all/20230811054528.never.165-kees@kernel.org/ > > > include/linux/minmax.h | 16 ++++++++++++++++ > 1 file changed, 16 insertions(+) > > diff --git a/include/linux/minmax.h b/include/linux/minmax.h > index 2ec559284a9f..96646f840a1f 100644 > --- a/include/linux/minmax.h > +++ b/include/linux/minmax.h > @@ -154,6 +154,18 @@ > > /** > * min_t - return minimum of two values, using the specified type > + * > + * Note: Downcasting types in this macro can cause incorrect results. Prefer to > + * use min() which does typechecking. > + * > + * Prefer to use clamp if you are trying to compare to size_t. > + * > + * Don't: > + * min_t(size_t, buf_size, sizeof(foobar)) > + * > + * Do: > + * clamp(buf_size, 0, sizeof(foobar)) > + * > * @type: data type to use > * @x: first value > * @y: second value Please keep the types immediately after the definition -- notes can go after. > @@ -162,6 +174,10 @@ > > /** > * max_t - return maximum of two values, using the specified type > + * > + * Note: Downcasting types in this macro can cause incorrect results. Prefer to > + * use max() which does typechecking. > + * > * @type: data type to use > * @x: first value > * @y: second value Same. But yes, I welcome the added comments! :)
From: Kees Cook > Sent: 09 February 2024 23:56 > > On Fri, Feb 09, 2024 at 03:07:02PM -0800, Abhishek Pandit-Subedi wrote: > > Both min_t and max_t are problematic as they can hide issues when > > comparing differently sized types (and especially differently signed > > types). Update the comments to nudge users to other options until > > there is a better fix for these macros. > > > > Link: https://lore.kernel.org/all/01e3e09005e9434b8f558a893a47c053@AcuMS.aculab.com/ > > Link: https://lore.kernel.org/all/CAHk- > =whwEAc22wm8h9FESPB5X+P4bLDgv0erBQMa1buTNQW7tA@mail.gmail.com/ > > > > Signed-off-by: Abhishek Pandit-Subedi <abhishekpandit@chromium.org> > > --- > > Andy Shevchenko made me aware of this particular footgun in > > https://lore.kernel.org/linux-usb/ZcZ_he1jYx8w57mK@smile.fi.intel.com/. > > > > While David + others work on the full fix, I'm hoping to apply a > > bandaid in the form of comments so the problem doesn't get worse by devs > > (**cough** me **cough**) inadvertently doing the wrong thing. I'm not sure that adding a comment here actually helps. If you read it you probably know what is happening! With the changes I did (which I think got back-ported at least one release) it is actually moderately unlikely that you'll need to use min_t() or max_t() (and especially clamp_val() - definitely an accident waiting to happen). I think there is only one clamp_val() that can't just be replaced with clamp(). I did post an updated set that really just reduce the generated line length - I probably need to report them to wake people up. > I think a better example for the docs would be something like u16 > (rather than size_t) which shows very quickly the potential for > truncation. See, for example: > > https://lore.kernel.org/all/20230811054528.never.165-kees@kernel.org/ (I'd found that one when I tried to build with min_t() being min(). The bug was reported not long after!) Or an example using 'unsigned char' - there are some very dubious ones lurking. Also look at the code in tcp/udp that validates the length argument to getsockopt(). It checks for negative after doing min_t(unsigned, len, 4). It has always been thus, well before min_t() was added. .. > > /** > > * min_t - return minimum of two values, using the specified type > > + * > > + * Note: Downcasting types in this macro can cause incorrect results. Prefer to > > + * use min() which does typechecking. > > + * > > + * Prefer to use clamp if you are trying to compare to size_t. > > + * > > + * Don't: > > + * min_t(size_t, buf_size, sizeof(foobar)) > > + * > > + * Do: > > + * clamp(buf_size, 0, sizeof(foobar)) I'm not at all sure that is actually helpful. It might be better to just note that min_t(unsigned type, int val, xxx) will convert a negative value to a large positive one. In you case size_t is just the wrong type. You need to change the type of the constant (to int) not the type of the variable. So you want: min(buf_size, (int)sizeof(foobar)) I'm not at all sure that min_t() (casting both args) is actually a good idea, requiring the codes explicitly cast one (usually only one needs a cast) is likely to be less buggy, more obvious, and less typing. I think min_t() exists because it is an exact replacement for a static inline function where the cast was implicit in the call. Linus didn't like the change that would allow: min(int_size, sizeof(fubar)) (ie implicitly casting unsigned constants to int before the compare.) It does make the defines rather more complicated. Thinking... it might me easier to add smin() (cf umin()) that will convert an unsigned constant to int (and error for non-constant unsigned arguments). That would be much safer than min_t() and save all the extra complication min() would need, and also annotate the source. A long term plan would be to remove all the min_t() and max_t(). Sorting out some patches for simple cases (both args unsigned and the same size would be a start) isn't that hard. But they do need to get applied. David - Registered Address Lakeside, Bramley Road, Mount Farm, Milton Keynes, MK1 1PT, UK Registration No: 1397386 (Wales)
On Sat, Feb 10, 2024 at 4:04 AM David Laight <David.Laight@aculab.com> wrote: > > From: Kees Cook > > Sent: 09 February 2024 23:56 > > > > On Fri, Feb 09, 2024 at 03:07:02PM -0800, Abhishek Pandit-Subedi wrote: > > > Both min_t and max_t are problematic as they can hide issues when > > > comparing differently sized types (and especially differently signed > > > types). Update the comments to nudge users to other options until > > > there is a better fix for these macros. > > > > > > Link: https://lore.kernel.org/all/01e3e09005e9434b8f558a893a47c053@AcuMS.aculab.com/ > > > Link: https://lore.kernel.org/all/CAHk- > > =whwEAc22wm8h9FESPB5X+P4bLDgv0erBQMa1buTNQW7tA@mail.gmail.com/ > > > > > > Signed-off-by: Abhishek Pandit-Subedi <abhishekpandit@chromium.org> > > > --- > > > Andy Shevchenko made me aware of this particular footgun in > > > https://lore.kernel.org/linux-usb/ZcZ_he1jYx8w57mK@smile.fi.intel.com/. > > > > > > While David + others work on the full fix, I'm hoping to apply a > > > bandaid in the form of comments so the problem doesn't get worse by devs > > > (**cough** me **cough**) inadvertently doing the wrong thing. > > I'm not sure that adding a comment here actually helps. > If you read it you probably know what is happening! > > With the changes I did (which I think got back-ported at least > one release) it is actually moderately unlikely that you'll need > to use min_t() or max_t() (and especially clamp_val() - definitely > an accident waiting to happen). > > I think there is only one clamp_val() that can't just be replaced > with clamp(). > > I did post an updated set that really just reduce the generated > line length - I probably need to report them to wake people up. > > > I think a better example for the docs would be something like u16 > > (rather than size_t) which shows very quickly the potential for > > truncation. See, for example: > > > > https://lore.kernel.org/all/20230811054528.never.165-kees@kernel.org/ > > (I'd found that one when I tried to build with min_t() being min(). > The bug was reported not long after!) > > Or an example using 'unsigned char' - there are some very dubious > ones lurking. > > Also look at the code in tcp/udp that validates the length argument > to getsockopt(). > It checks for negative after doing min_t(unsigned, len, 4). > It has always been thus, well before min_t() was added. > > ... > > > /** > > > * min_t - return minimum of two values, using the specified type > > > + * > > > + * Note: Downcasting types in this macro can cause incorrect results Prefer to > > > + * use min() which does typechecking. > > > + * > > > + * Prefer to use clamp if you are trying to compare to size_t. > > > + * > > > + * Don't: > > > + * min_t(size_t, buf_size, sizeof(foobar)) > > > + * > > > + * Do: > > > + * clamp(buf_size, 0, sizeof(foobar)) > > I'm not at all sure that is actually helpful. > It might be better to just note that min_t(unsigned type, int val, xxx) > will convert a negative value to a large positive one. > > In you case size_t is just the wrong type. > You need to change the type of the constant (to int) not the > type of the variable. > So you want: > min(buf_size, (int)sizeof(foobar)) > > I'm not at all sure that min_t() (casting both args) is actually > a good idea, requiring the codes explicitly cast one (usually only > one needs a cast) is likely to be less buggy, more obvious, and > less typing. > > I think min_t() exists because it is an exact replacement for > a static inline function where the cast was implicit in the call. > > Linus didn't like the change that would allow: > min(int_size, sizeof(fubar)) > (ie implicitly casting unsigned constants to int before > the compare.) > It does make the defines rather more complicated. > > Thinking... it might me easier to add smin() (cf umin()) > that will convert an unsigned constant to int > (and error for non-constant unsigned arguments). > That would be much safer than min_t() and save all the extra > complication min() would need, and also annotate the source. I seemed to have somehow entirely missed umin and the static assert you added as it does exactly the thing that I would want out of the docs. https://lore.kernel.org/all/fe7e6c542e094bfca655abcd323c1c98@AcuMS.aculab.com/ I went back to my working tree (on 6.6) and rebased and I see the following error: min(16, buf_size) signedness error, fix types or consider umin() before min_t() This works great! Thanks for adding this! > > A long term plan would be to remove all the min_t() and max_t(). > Sorting out some patches for simple cases (both args unsigned > and the same size would be a start) isn't that hard. > But they do need to get applied. > > David > > - > Registered Address Lakeside, Bramley Road, Mount Farm, Milton Keynes, MK1 1PT, UK > Registration No: 1397386 (Wales) > Please consider this patch closed/abandoned since https://lore.kernel.org/all/fe7e6c542e094bfca655abcd323c1c98@AcuMS.aculab.com/ is already merged.
diff --git a/include/linux/minmax.h b/include/linux/minmax.h index 2ec559284a9f..96646f840a1f 100644 --- a/include/linux/minmax.h +++ b/include/linux/minmax.h @@ -154,6 +154,18 @@ /** * min_t - return minimum of two values, using the specified type + * + * Note: Downcasting types in this macro can cause incorrect results. Prefer to + * use min() which does typechecking. + * + * Prefer to use clamp if you are trying to compare to size_t. + * + * Don't: + * min_t(size_t, buf_size, sizeof(foobar)) + * + * Do: + * clamp(buf_size, 0, sizeof(foobar)) + * * @type: data type to use * @x: first value * @y: second value @@ -162,6 +174,10 @@ /** * max_t - return maximum of two values, using the specified type + * + * Note: Downcasting types in this macro can cause incorrect results. Prefer to + * use max() which does typechecking. + * * @type: data type to use * @x: first value * @y: second value