diff mbox series

ALSA: hwdep: Move put_user() call out of scoped_guard() in snd_hwdep_control_ioctl()

Message ID 20240301-fix-snd-hwdep-guard-v1-1-6aab033f3f83@kernel.org (mailing list archive)
State Accepted
Commit 72165c867f21d0724a9c900ff6e8bb5ba10cd8a8
Headers show
Series ALSA: hwdep: Move put_user() call out of scoped_guard() in snd_hwdep_control_ioctl() | expand

Commit Message

Nathan Chancellor March 1, 2024, 5:08 p.m. UTC
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(-)


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

Best regards,

Comments

Takashi Iwai March 1, 2024, 5:11 p.m. UTC | #1
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
diff mbox series

Patch

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:
 		{