linux-sound.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH] ALSA: hwdep: Move put_user() call out of scoped_guard() in snd_hwdep_control_ioctl()
@ 2024-03-01 17:08 Nathan Chancellor
  2024-03-01 17:11 ` Takashi Iwai
  0 siblings, 1 reply; 2+ messages in thread
From: Nathan Chancellor @ 2024-03-01 17:08 UTC (permalink / raw)
  To: perex, tiwai
  Cc: ndesaulniers, morbo, justinstitt, linux-sound, llvm, patches,
	Nathan Chancellor

Clang prior to 17.0.0 has a bug in its asm goto jump scope analysis to
determine that no variables with the cleanup attribute are skipped by an
indirect jump. Instead of only checking the scope of each label that is
a possible target of each asm goto statement, it checks the scope of
every label, which can cause an error when a variable with the cleanup
attribute is used between two asm goto statements with different scopes,
even if they have completely different label targets:

  sound/core/hwdep.c:273:8: error: cannot jump from this asm goto statement to one of its possible targets
                          if (get_user(device, (int __user *)arg))
                              ^
  arch/powerpc/include/asm/uaccess.h:295:5: note: expanded from macro 'get_user'
                    __get_user(x, _gu_addr) :                             \
                    ^
  arch/powerpc/include/asm/uaccess.h:283:2: note: expanded from macro '__get_user'
          __get_user_size_allowed(__gu_val, __gu_addr, __gu_size, __gu_err);      \
          ^
  arch/powerpc/include/asm/uaccess.h:199:3: note: expanded from macro '__get_user_size_allowed'
                  __get_user_size_goto(x, ptr, size, __gus_failed);       \
                  ^
  arch/powerpc/include/asm/uaccess.h:187:10: note: expanded from macro '__get_user_size_goto'
          case 1: __get_user_asm_goto(x, (u8 __user *)ptr, label, "lbz"); break;  \
                  ^
  arch/powerpc/include/asm/uaccess.h:158:2: note: expanded from macro '__get_user_asm_goto'
          asm_volatile_goto(                                      \
          ^
  include/linux/compiler_types.h:366:33: note: expanded from macro 'asm_volatile_goto'
  #define asm_volatile_goto(x...) asm goto(x)
                                  ^
  sound/core/hwdep.c:291:9: note: possible target of asm goto statement
                                  if (put_user(device, (int __user *)arg))
                                      ^
  arch/powerpc/include/asm/uaccess.h:66:5: note: expanded from macro 'put_user'
                    __put_user(x, _pu_addr) : -EFAULT;                    \
                    ^
  arch/powerpc/include/asm/uaccess.h:52:9: note: expanded from macro '__put_user'
                                                                  \
                                                                  ^
  sound/core/hwdep.c:276:4: note: jump bypasses initialization of variable with __attribute__((cleanup))
                          scoped_guard(mutex, &register_mutex) {
                          ^
  include/linux/cleanup.h:169:20: note: expanded from macro 'scoped_guard'
          for (CLASS(_name, scope)(args),                                 \

To avoid this issue, move the put_user() call out of the scoped_guard()
scope, which allows the asm goto scope analysis to see that the variable
with the cleanup attribute will never be skipped by the asm goto
statements.

There should be no functional change because prior to the refactoring,
put_user() was not called under register_mutex, so this call does not
even need to be in the scoped_guard() in the first place.

Fixes: e6684d08cc19 ("ALSA: hwdep: Use guard() for locking")
Closes: https://github.com/ClangBuiltLinux/linux/issues/2003
Signed-off-by: Nathan Chancellor <nathan@kernel.org>
---
 sound/core/hwdep.c | 7 +++----
 1 file changed, 3 insertions(+), 4 deletions(-)

diff --git a/sound/core/hwdep.c b/sound/core/hwdep.c
index 9d7e5039c893..09200df2932c 100644
--- a/sound/core/hwdep.c
+++ b/sound/core/hwdep.c
@@ -288,11 +288,10 @@ static int snd_hwdep_control_ioctl(struct snd_card *card,
 				}
 				if (device >= SNDRV_MINOR_HWDEPS)
 					device = -1;
-				if (put_user(device, (int __user *)arg))
-					return -EFAULT;
-				return 0;
 			}
-			break;
+			if (put_user(device, (int __user *)arg))
+				return -EFAULT;
+			return 0;
 		}
 	case SNDRV_CTL_IOCTL_HWDEP_INFO:
 		{

---
base-commit: 7dba48a474e68dcdda2b212cea131b4c9ddc7d89
change-id: 20240301-fix-snd-hwdep-guard-ab9fe85731af

Best regards,
-- 
Nathan Chancellor <nathan@kernel.org>


^ permalink raw reply related	[flat|nested] 2+ messages in thread

* Re: [PATCH] ALSA: hwdep: Move put_user() call out of scoped_guard() in snd_hwdep_control_ioctl()
  2024-03-01 17:08 [PATCH] ALSA: hwdep: Move put_user() call out of scoped_guard() in snd_hwdep_control_ioctl() Nathan Chancellor
@ 2024-03-01 17:11 ` Takashi Iwai
  0 siblings, 0 replies; 2+ messages in thread
From: Takashi Iwai @ 2024-03-01 17:11 UTC (permalink / raw)
  To: Nathan Chancellor
  Cc: perex, tiwai, ndesaulniers, morbo, justinstitt, linux-sound, llvm,
	patches

On Fri, 01 Mar 2024 18:08:22 +0100,
Nathan Chancellor wrote:
> 
> Clang prior to 17.0.0 has a bug in its asm goto jump scope analysis to
> determine that no variables with the cleanup attribute are skipped by an
> indirect jump. Instead of only checking the scope of each label that is
> a possible target of each asm goto statement, it checks the scope of
> every label, which can cause an error when a variable with the cleanup
> attribute is used between two asm goto statements with different scopes,
> even if they have completely different label targets:
> 
>   sound/core/hwdep.c:273:8: error: cannot jump from this asm goto statement to one of its possible targets
>                           if (get_user(device, (int __user *)arg))
>                               ^
>   arch/powerpc/include/asm/uaccess.h:295:5: note: expanded from macro 'get_user'
>                     __get_user(x, _gu_addr) :                             \
>                     ^
>   arch/powerpc/include/asm/uaccess.h:283:2: note: expanded from macro '__get_user'
>           __get_user_size_allowed(__gu_val, __gu_addr, __gu_size, __gu_err);      \
>           ^
>   arch/powerpc/include/asm/uaccess.h:199:3: note: expanded from macro '__get_user_size_allowed'
>                   __get_user_size_goto(x, ptr, size, __gus_failed);       \
>                   ^
>   arch/powerpc/include/asm/uaccess.h:187:10: note: expanded from macro '__get_user_size_goto'
>           case 1: __get_user_asm_goto(x, (u8 __user *)ptr, label, "lbz"); break;  \
>                   ^
>   arch/powerpc/include/asm/uaccess.h:158:2: note: expanded from macro '__get_user_asm_goto'
>           asm_volatile_goto(                                      \
>           ^
>   include/linux/compiler_types.h:366:33: note: expanded from macro 'asm_volatile_goto'
>   #define asm_volatile_goto(x...) asm goto(x)
>                                   ^
>   sound/core/hwdep.c:291:9: note: possible target of asm goto statement
>                                   if (put_user(device, (int __user *)arg))
>                                       ^
>   arch/powerpc/include/asm/uaccess.h:66:5: note: expanded from macro 'put_user'
>                     __put_user(x, _pu_addr) : -EFAULT;                    \
>                     ^
>   arch/powerpc/include/asm/uaccess.h:52:9: note: expanded from macro '__put_user'
>                                                                   \
>                                                                   ^
>   sound/core/hwdep.c:276:4: note: jump bypasses initialization of variable with __attribute__((cleanup))
>                           scoped_guard(mutex, &register_mutex) {
>                           ^
>   include/linux/cleanup.h:169:20: note: expanded from macro 'scoped_guard'
>           for (CLASS(_name, scope)(args),                                 \
> 
> To avoid this issue, move the put_user() call out of the scoped_guard()
> scope, which allows the asm goto scope analysis to see that the variable
> with the cleanup attribute will never be skipped by the asm goto
> statements.
> 
> There should be no functional change because prior to the refactoring,
> put_user() was not called under register_mutex, so this call does not
> even need to be in the scoped_guard() in the first place.
> 
> Fixes: e6684d08cc19 ("ALSA: hwdep: Use guard() for locking")
> Closes: https://github.com/ClangBuiltLinux/linux/issues/2003
> Signed-off-by: Nathan Chancellor <nathan@kernel.org>

Applied now.  Thanks!


Takashi

^ permalink raw reply	[flat|nested] 2+ messages in thread

end of thread, other threads:[~2024-03-01 17:11 UTC | newest]

Thread overview: 2+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2024-03-01 17:08 [PATCH] ALSA: hwdep: Move put_user() call out of scoped_guard() in snd_hwdep_control_ioctl() Nathan Chancellor
2024-03-01 17:11 ` Takashi Iwai

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).