Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
L
linux
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
nexedi
linux
Commits
8d42fda9
Commit
8d42fda9
authored
Jun 18, 2014
by
Takashi Iwai
Browse files
Options
Browse Files
Download
Plain Diff
Merge branch 'topic/core-vuln-fixes' into for-linus
parents
6c0c9a3d
883a1d49
Changes
3
Show whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
54 additions
and
27 deletions
+54
-27
include/sound/core.h
include/sound/core.h
+2
-0
sound/core/control.c
sound/core/control.c
+51
-27
sound/core/init.c
sound/core/init.c
+1
-0
No files found.
include/sound/core.h
View file @
8d42fda9
...
...
@@ -116,6 +116,8 @@ struct snd_card {
int
user_ctl_count
;
/* count of all user controls */
struct
list_head
controls
;
/* all controls for this card */
struct
list_head
ctl_files
;
/* active control files */
struct
mutex
user_ctl_lock
;
/* protects user controls against
concurrent access */
struct
snd_info_entry
*
proc_root
;
/* root for soundcard specific files */
struct
snd_info_entry
*
proc_id
;
/* the card id */
...
...
sound/core/control.c
View file @
8d42fda9
...
...
@@ -288,6 +288,10 @@ static bool snd_ctl_remove_numid_conflict(struct snd_card *card,
{
struct
snd_kcontrol
*
kctl
;
/* Make sure that the ids assigned to the control do not wrap around */
if
(
card
->
last_numid
>=
UINT_MAX
-
count
)
card
->
last_numid
=
0
;
list_for_each_entry
(
kctl
,
&
card
->
controls
,
list
)
{
if
(
kctl
->
id
.
numid
<
card
->
last_numid
+
1
+
count
&&
kctl
->
id
.
numid
+
kctl
->
count
>
card
->
last_numid
+
1
)
{
...
...
@@ -330,6 +334,7 @@ int snd_ctl_add(struct snd_card *card, struct snd_kcontrol *kcontrol)
{
struct
snd_ctl_elem_id
id
;
unsigned
int
idx
;
unsigned
int
count
;
int
err
=
-
EINVAL
;
if
(
!
kcontrol
)
...
...
@@ -337,6 +342,9 @@ int snd_ctl_add(struct snd_card *card, struct snd_kcontrol *kcontrol)
if
(
snd_BUG_ON
(
!
card
||
!
kcontrol
->
info
))
goto
error
;
id
=
kcontrol
->
id
;
if
(
id
.
index
>
UINT_MAX
-
kcontrol
->
count
)
goto
error
;
down_write
(
&
card
->
controls_rwsem
);
if
(
snd_ctl_find_id
(
card
,
&
id
))
{
up_write
(
&
card
->
controls_rwsem
);
...
...
@@ -358,8 +366,9 @@ int snd_ctl_add(struct snd_card *card, struct snd_kcontrol *kcontrol)
card
->
controls_count
+=
kcontrol
->
count
;
kcontrol
->
id
.
numid
=
card
->
last_numid
+
1
;
card
->
last_numid
+=
kcontrol
->
count
;
count
=
kcontrol
->
count
;
up_write
(
&
card
->
controls_rwsem
);
for
(
idx
=
0
;
idx
<
kcontrol
->
count
;
idx
++
,
id
.
index
++
,
id
.
numid
++
)
for
(
idx
=
0
;
idx
<
count
;
idx
++
,
id
.
index
++
,
id
.
numid
++
)
snd_ctl_notify
(
card
,
SNDRV_CTL_EVENT_MASK_ADD
,
&
id
);
return
0
;
...
...
@@ -388,6 +397,7 @@ int snd_ctl_replace(struct snd_card *card, struct snd_kcontrol *kcontrol,
bool
add_on_replace
)
{
struct
snd_ctl_elem_id
id
;
unsigned
int
count
;
unsigned
int
idx
;
struct
snd_kcontrol
*
old
;
int
ret
;
...
...
@@ -423,8 +433,9 @@ int snd_ctl_replace(struct snd_card *card, struct snd_kcontrol *kcontrol,
card
->
controls_count
+=
kcontrol
->
count
;
kcontrol
->
id
.
numid
=
card
->
last_numid
+
1
;
card
->
last_numid
+=
kcontrol
->
count
;
count
=
kcontrol
->
count
;
up_write
(
&
card
->
controls_rwsem
);
for
(
idx
=
0
;
idx
<
kcontrol
->
count
;
idx
++
,
id
.
index
++
,
id
.
numid
++
)
for
(
idx
=
0
;
idx
<
count
;
idx
++
,
id
.
index
++
,
id
.
numid
++
)
snd_ctl_notify
(
card
,
SNDRV_CTL_EVENT_MASK_ADD
,
&
id
);
return
0
;
...
...
@@ -897,9 +908,9 @@ static int snd_ctl_elem_write(struct snd_card *card, struct snd_ctl_file *file,
result
=
kctl
->
put
(
kctl
,
control
);
}
if
(
result
>
0
)
{
struct
snd_ctl_elem_id
id
=
control
->
id
;
up_read
(
&
card
->
controls_rwsem
);
snd_ctl_notify
(
card
,
SNDRV_CTL_EVENT_MASK_VALUE
,
&
control
->
id
);
snd_ctl_notify
(
card
,
SNDRV_CTL_EVENT_MASK_VALUE
,
&
id
);
return
0
;
}
}
...
...
@@ -991,6 +1002,7 @@ static int snd_ctl_elem_unlock(struct snd_ctl_file *file,
struct
user_element
{
struct
snd_ctl_elem_info
info
;
struct
snd_card
*
card
;
void
*
elem_data
;
/* element data */
unsigned
long
elem_data_size
;
/* size of element data in bytes */
void
*
tlv_data
;
/* TLV data */
...
...
@@ -1034,7 +1046,9 @@ static int snd_ctl_elem_user_get(struct snd_kcontrol *kcontrol,
{
struct
user_element
*
ue
=
kcontrol
->
private_data
;
mutex_lock
(
&
ue
->
card
->
user_ctl_lock
);
memcpy
(
&
ucontrol
->
value
,
ue
->
elem_data
,
ue
->
elem_data_size
);
mutex_unlock
(
&
ue
->
card
->
user_ctl_lock
);
return
0
;
}
...
...
@@ -1044,9 +1058,11 @@ static int snd_ctl_elem_user_put(struct snd_kcontrol *kcontrol,
int
change
;
struct
user_element
*
ue
=
kcontrol
->
private_data
;
mutex_lock
(
&
ue
->
card
->
user_ctl_lock
);
change
=
memcmp
(
&
ucontrol
->
value
,
ue
->
elem_data
,
ue
->
elem_data_size
)
!=
0
;
if
(
change
)
memcpy
(
ue
->
elem_data
,
&
ucontrol
->
value
,
ue
->
elem_data_size
);
mutex_unlock
(
&
ue
->
card
->
user_ctl_lock
);
return
change
;
}
...
...
@@ -1066,19 +1082,32 @@ static int snd_ctl_elem_user_tlv(struct snd_kcontrol *kcontrol,
new_data
=
memdup_user
(
tlv
,
size
);
if
(
IS_ERR
(
new_data
))
return
PTR_ERR
(
new_data
);
mutex_lock
(
&
ue
->
card
->
user_ctl_lock
);
change
=
ue
->
tlv_data_size
!=
size
;
if
(
!
change
)
change
=
memcmp
(
ue
->
tlv_data
,
new_data
,
size
);
kfree
(
ue
->
tlv_data
);
ue
->
tlv_data
=
new_data
;
ue
->
tlv_data_size
=
size
;
mutex_unlock
(
&
ue
->
card
->
user_ctl_lock
);
}
else
{
if
(
!
ue
->
tlv_data_size
||
!
ue
->
tlv_data
)
return
-
ENXIO
;
if
(
size
<
ue
->
tlv_data_size
)
return
-
ENOSPC
;
int
ret
=
0
;
mutex_lock
(
&
ue
->
card
->
user_ctl_lock
);
if
(
!
ue
->
tlv_data_size
||
!
ue
->
tlv_data
)
{
ret
=
-
ENXIO
;
goto
err_unlock
;
}
if
(
size
<
ue
->
tlv_data_size
)
{
ret
=
-
ENOSPC
;
goto
err_unlock
;
}
if
(
copy_to_user
(
tlv
,
ue
->
tlv_data
,
ue
->
tlv_data_size
))
return
-
EFAULT
;
ret
=
-
EFAULT
;
err_unlock:
mutex_unlock
(
&
ue
->
card
->
user_ctl_lock
);
if
(
ret
)
return
ret
;
}
return
change
;
}
...
...
@@ -1136,8 +1165,6 @@ static int snd_ctl_elem_add(struct snd_ctl_file *file,
struct
user_element
*
ue
;
int
idx
,
err
;
if
(
!
replace
&&
card
->
user_ctl_count
>=
MAX_USER_CONTROLS
)
return
-
ENOMEM
;
if
(
info
->
count
<
1
)
return
-
EINVAL
;
access
=
info
->
access
==
0
?
SNDRV_CTL_ELEM_ACCESS_READWRITE
:
...
...
@@ -1146,21 +1173,16 @@ static int snd_ctl_elem_add(struct snd_ctl_file *file,
SNDRV_CTL_ELEM_ACCESS_TLV_READWRITE
));
info
->
id
.
numid
=
0
;
memset
(
&
kctl
,
0
,
sizeof
(
kctl
));
down_write
(
&
card
->
controls_rwsem
);
_kctl
=
snd_ctl_find_id
(
card
,
&
info
->
id
);
err
=
0
;
if
(
_kctl
)
{
if
(
replace
)
err
=
snd_ctl_remove
(
card
,
_kctl
);
else
err
=
-
EBUSY
;
}
else
{
if
(
replace
)
err
=
-
ENOENT
;
}
up_write
(
&
card
->
controls_rwsem
);
if
(
err
<
0
)
if
(
replace
)
{
err
=
snd_ctl_remove_user_ctl
(
file
,
&
info
->
id
);
if
(
err
)
return
err
;
}
if
(
card
->
user_ctl_count
>=
MAX_USER_CONTROLS
)
return
-
ENOMEM
;
memcpy
(
&
kctl
.
id
,
&
info
->
id
,
sizeof
(
info
->
id
));
kctl
.
count
=
info
->
owner
?
info
->
owner
:
1
;
access
|=
SNDRV_CTL_ELEM_ACCESS_USER
;
...
...
@@ -1210,6 +1232,7 @@ static int snd_ctl_elem_add(struct snd_ctl_file *file,
ue
=
kzalloc
(
sizeof
(
struct
user_element
)
+
private_size
,
GFP_KERNEL
);
if
(
ue
==
NULL
)
return
-
ENOMEM
;
ue
->
card
=
card
;
ue
->
info
=
*
info
;
ue
->
info
.
access
=
0
;
ue
->
elem_data
=
(
char
*
)
ue
+
sizeof
(
*
ue
);
...
...
@@ -1321,8 +1344,9 @@ static int snd_ctl_tlv_ioctl(struct snd_ctl_file *file,
}
err
=
kctl
->
tlv
.
c
(
kctl
,
op_flag
,
tlv
.
length
,
_tlv
->
tlv
);
if
(
err
>
0
)
{
struct
snd_ctl_elem_id
id
=
kctl
->
id
;
up_read
(
&
card
->
controls_rwsem
);
snd_ctl_notify
(
card
,
SNDRV_CTL_EVENT_MASK_TLV
,
&
kctl
->
id
);
snd_ctl_notify
(
card
,
SNDRV_CTL_EVENT_MASK_TLV
,
&
id
);
return
0
;
}
}
else
{
...
...
sound/core/init.c
View file @
8d42fda9
...
...
@@ -232,6 +232,7 @@ int snd_card_new(struct device *parent, int idx, const char *xid,
INIT_LIST_HEAD
(
&
card
->
devices
);
init_rwsem
(
&
card
->
controls_rwsem
);
rwlock_init
(
&
card
->
ctl_files_rwlock
);
mutex_init
(
&
card
->
user_ctl_lock
);
INIT_LIST_HEAD
(
&
card
->
controls
);
INIT_LIST_HEAD
(
&
card
->
ctl_files
);
spin_lock_init
(
&
card
->
files_lock
);
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment