Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

ALSA: control: Use automatic cleanup of kfree()

There are common patterns where a temporary buffer is allocated and
freed at the exit, and those can be simplified with the recent cleanup
mechanism via __free(kfree).

A caveat is that some allocations are memdup_user() and they return an
error pointer instead of NULL. Those need special cares and the value
has to be cleared with no_free_ptr() at the allocation error path.

Other than that, the conversions are straightforward.

No functional changes, only code refactoring.

Signed-off-by: Takashi Iwai <tiwai@suse.de>
Link: https://lore.kernel.org/r/20240222111509.28390-3-tiwai@suse.de

+34 -58
+8 -15
sound/core/control.c
··· 932 932 static int snd_ctl_card_info(struct snd_card *card, struct snd_ctl_file * ctl, 933 933 unsigned int cmd, void __user *arg) 934 934 { 935 - struct snd_ctl_card_info *info; 935 + struct snd_ctl_card_info *info __free(kfree) = NULL; 936 936 937 937 info = kzalloc(sizeof(*info), GFP_KERNEL); 938 938 if (! info) ··· 946 946 strscpy(info->mixername, card->mixername, sizeof(info->mixername)); 947 947 strscpy(info->components, card->components, sizeof(info->components)); 948 948 up_read(&snd_ioctl_rwsem); 949 - if (copy_to_user(arg, info, sizeof(struct snd_ctl_card_info))) { 950 - kfree(info); 949 + if (copy_to_user(arg, info, sizeof(struct snd_ctl_card_info))) 951 950 return -EFAULT; 952 - } 953 - kfree(info); 954 951 return 0; 955 952 } 956 953 ··· 1336 1339 1337 1340 result = snd_ctl_elem_read(card, control); 1338 1341 if (result < 0) 1339 - goto error; 1342 + return result; 1340 1343 1341 1344 if (copy_to_user(_control, control, sizeof(*control))) 1342 - result = -EFAULT; 1343 - error: 1344 - kfree(control); 1345 + return -EFAULT; 1345 1346 return result; 1346 1347 } 1347 1348 ··· 1401 1406 static int snd_ctl_elem_write_user(struct snd_ctl_file *file, 1402 1407 struct snd_ctl_elem_value __user *_control) 1403 1408 { 1404 - struct snd_ctl_elem_value *control; 1409 + struct snd_ctl_elem_value *control __free(kfree) = NULL; 1405 1410 struct snd_card *card; 1406 1411 int result; 1407 1412 1408 1413 control = memdup_user(_control, sizeof(*control)); 1409 1414 if (IS_ERR(control)) 1410 - return PTR_ERR(control); 1415 + return PTR_ERR(no_free_ptr(control)); 1411 1416 1412 1417 card = file->card; 1413 1418 result = snd_ctl_elem_write(card, file, control); 1414 1419 if (result < 0) 1415 - goto error; 1420 + return result; 1416 1421 1417 1422 if (copy_to_user(_control, control, sizeof(*control))) 1418 - result = -EFAULT; 1419 - error: 1420 - kfree(control); 1423 + return -EFAULT; 1421 1424 return result; 1422 1425 } 1423 1426
+26 -43
sound/core/control_compat.c
··· 79 79 static int snd_ctl_elem_info_compat(struct snd_ctl_file *ctl, 80 80 struct snd_ctl_elem_info32 __user *data32) 81 81 { 82 - struct snd_ctl_elem_info *data; 82 + struct snd_ctl_elem_info *data __free(kfree) = NULL; 83 83 int err; 84 84 85 85 data = kzalloc(sizeof(*data), GFP_KERNEL); 86 86 if (! data) 87 87 return -ENOMEM; 88 88 89 - err = -EFAULT; 90 89 /* copy id */ 91 90 if (copy_from_user(&data->id, &data32->id, sizeof(data->id))) 92 - goto error; 91 + return -EFAULT; 93 92 /* we need to copy the item index. 94 93 * hope this doesn't break anything.. 95 94 */ 96 95 if (get_user(data->value.enumerated.item, &data32->value.enumerated.item)) 97 - goto error; 96 + return -EFAULT; 98 97 99 98 err = snd_ctl_elem_info(ctl, data); 100 99 if (err < 0) 101 - goto error; 100 + return err; 102 101 /* restore info to 32bit */ 103 - err = -EFAULT; 104 102 /* id, type, access, count */ 105 103 if (copy_to_user(&data32->id, &data->id, sizeof(data->id)) || 106 104 copy_to_user(&data32->type, &data->type, 3 * sizeof(u32))) 107 - goto error; 105 + return -EFAULT; 108 106 if (put_user(data->owner, &data32->owner)) 109 - goto error; 107 + return -EFAULT; 110 108 switch (data->type) { 111 109 case SNDRV_CTL_ELEM_TYPE_BOOLEAN: 112 110 case SNDRV_CTL_ELEM_TYPE_INTEGER: 113 111 if (put_user(data->value.integer.min, &data32->value.integer.min) || 114 112 put_user(data->value.integer.max, &data32->value.integer.max) || 115 113 put_user(data->value.integer.step, &data32->value.integer.step)) 116 - goto error; 114 + return -EFAULT; 117 115 break; 118 116 case SNDRV_CTL_ELEM_TYPE_INTEGER64: 119 117 if (copy_to_user(&data32->value.integer64, 120 118 &data->value.integer64, 121 119 sizeof(data->value.integer64))) 122 - goto error; 120 + return -EFAULT; 123 121 break; 124 122 case SNDRV_CTL_ELEM_TYPE_ENUMERATED: 125 123 if (copy_to_user(&data32->value.enumerated, 126 124 &data->value.enumerated, 127 125 sizeof(data->value.enumerated))) 128 - goto error; 126 + return -EFAULT; 129 127 break; 130 128 default: 131 129 break; 132 130 } 133 - err = 0; 134 - error: 135 - kfree(data); 136 - return err; 131 + return 0; 137 132 } 138 133 139 134 /* read / write */ ··· 164 169 int *countp) 165 170 { 166 171 struct snd_kcontrol *kctl; 167 - struct snd_ctl_elem_info *info; 172 + struct snd_ctl_elem_info *info __free(kfree) = NULL; 168 173 int err; 169 174 170 175 down_read(&card->controls_rwsem); ··· 188 193 err = info->type; 189 194 *countp = info->count; 190 195 } 191 - kfree(info); 192 196 return err; 193 197 } 194 198 ··· 283 289 static int ctl_elem_read_user(struct snd_card *card, 284 290 void __user *userdata, void __user *valuep) 285 291 { 286 - struct snd_ctl_elem_value *data; 292 + struct snd_ctl_elem_value *data __free(kfree) = NULL; 287 293 int err, type, count; 288 294 289 295 data = kzalloc(sizeof(*data), GFP_KERNEL); ··· 293 299 err = copy_ctl_value_from_user(card, data, userdata, valuep, 294 300 &type, &count); 295 301 if (err < 0) 296 - goto error; 302 + return err; 297 303 298 304 err = snd_ctl_elem_read(card, data); 299 305 if (err < 0) 300 - goto error; 301 - err = copy_ctl_value_to_user(userdata, valuep, data, type, count); 302 - error: 303 - kfree(data); 304 - return err; 306 + return err; 307 + return copy_ctl_value_to_user(userdata, valuep, data, type, count); 305 308 } 306 309 307 310 static int ctl_elem_write_user(struct snd_ctl_file *file, 308 311 void __user *userdata, void __user *valuep) 309 312 { 310 - struct snd_ctl_elem_value *data; 313 + struct snd_ctl_elem_value *data __free(kfree) = NULL; 311 314 struct snd_card *card = file->card; 312 315 int err, type, count; 313 316 ··· 315 324 err = copy_ctl_value_from_user(card, data, userdata, valuep, 316 325 &type, &count); 317 326 if (err < 0) 318 - goto error; 327 + return err; 319 328 320 329 err = snd_ctl_elem_write(card, file, data); 321 330 if (err < 0) 322 - goto error; 323 - err = copy_ctl_value_to_user(userdata, valuep, data, type, count); 324 - error: 325 - kfree(data); 326 - return err; 331 + return err; 332 + return copy_ctl_value_to_user(userdata, valuep, data, type, count); 327 333 } 328 334 329 335 static int snd_ctl_elem_read_user_compat(struct snd_card *card, ··· 354 366 struct snd_ctl_elem_info32 __user *data32, 355 367 int replace) 356 368 { 357 - struct snd_ctl_elem_info *data; 358 - int err; 369 + struct snd_ctl_elem_info *data __free(kfree) = NULL; 359 370 360 371 data = kzalloc(sizeof(*data), GFP_KERNEL); 361 372 if (! data) 362 373 return -ENOMEM; 363 374 364 - err = -EFAULT; 365 375 /* id, type, access, count */ \ 366 376 if (copy_from_user(&data->id, &data32->id, sizeof(data->id)) || 367 377 copy_from_user(&data->type, &data32->type, 3 * sizeof(u32))) 368 - goto error; 378 + return -EFAULT; 369 379 if (get_user(data->owner, &data32->owner)) 370 - goto error; 380 + return -EFAULT; 371 381 switch (data->type) { 372 382 case SNDRV_CTL_ELEM_TYPE_BOOLEAN: 373 383 case SNDRV_CTL_ELEM_TYPE_INTEGER: 374 384 if (get_user(data->value.integer.min, &data32->value.integer.min) || 375 385 get_user(data->value.integer.max, &data32->value.integer.max) || 376 386 get_user(data->value.integer.step, &data32->value.integer.step)) 377 - goto error; 387 + return -EFAULT; 378 388 break; 379 389 case SNDRV_CTL_ELEM_TYPE_INTEGER64: 380 390 if (copy_from_user(&data->value.integer64, 381 391 &data32->value.integer64, 382 392 sizeof(data->value.integer64))) 383 - goto error; 393 + return -EFAULT; 384 394 break; 385 395 case SNDRV_CTL_ELEM_TYPE_ENUMERATED: 386 396 if (copy_from_user(&data->value.enumerated, 387 397 &data32->value.enumerated, 388 398 sizeof(data->value.enumerated))) 389 - goto error; 399 + return -EFAULT; 390 400 data->value.enumerated.names_ptr = 391 401 (uintptr_t)compat_ptr(data->value.enumerated.names_ptr); 392 402 break; 393 403 default: 394 404 break; 395 405 } 396 - err = snd_ctl_elem_add(file, data, replace); 397 - error: 398 - kfree(data); 399 - return err; 406 + return snd_ctl_elem_add(file, data, replace); 400 407 } 401 408 402 409 enum {