* [PATCH 1/3] vt: keyboard, reorder user buffer handling in vt_do_kdgkb_ioctl
@ 2020-10-16 12:24 Jiri Slaby
2020-10-16 12:24 ` [PATCH 2/3] vt: keyboard, simplify vt_kdgkbsent Jiri Slaby
2020-10-16 12:24 ` [PATCH 3/3] vt: keyboard, extend func_buf_lock to readers Jiri Slaby
0 siblings, 2 replies; 6+ messages in thread
From: Jiri Slaby @ 2020-10-16 12:24 UTC (permalink / raw)
To: gregkh; +Cc: linux-serial, linux-kernel, Minh Yuan, Jiri Slaby
KDGKBSENT (the getter) needs only user_kdgkb->kb_func from the
userspace, i.e. the index. So do the complete copy only in KDSKBSENT
(the setter). That means, we obtain the index before the switch-case
and use it in both paths and copy the string only in the setter case.
And we do it by strndup_user helper now which was not available when
this function was written.
Given we copy the two members of struct kbsentry separately, we no
longer need a local definition. Hence we need to change all the sizeofs
here too.
And also the getter now returns in all fail paths, not freeing the
setter's string.
Signed-off-by: Jiri Slaby <jslaby@suse.cz>
---
drivers/tty/vt/keyboard.c | 51 ++++++++++++++++-----------------------
1 file changed, 21 insertions(+), 30 deletions(-)
diff --git a/drivers/tty/vt/keyboard.c b/drivers/tty/vt/keyboard.c
index 0db53b5b3acf..d8e2452da1bd 100644
--- a/drivers/tty/vt/keyboard.c
+++ b/drivers/tty/vt/keyboard.c
@@ -1994,7 +1994,7 @@ int vt_do_kdsk_ioctl(int cmd, struct kbentry __user *user_kbe, int perm,
/* FIXME: This one needs untangling and locking */
int vt_do_kdgkb_ioctl(int cmd, struct kbsentry __user *user_kdgkb, int perm)
{
- struct kbsentry *kbs;
+ char *kbs;
char *p;
u_char *q;
u_char __user *up;
@@ -2008,43 +2008,34 @@ int vt_do_kdgkb_ioctl(int cmd, struct kbsentry __user *user_kdgkb, int perm)
if (!capable(CAP_SYS_TTY_CONFIG))
perm = 0;
- kbs = kmalloc(sizeof(*kbs), GFP_KERNEL);
- if (!kbs) {
- ret = -ENOMEM;
- goto reterr;
- }
+ if (get_user(i, &user_kdgkb->kb_func))
+ return -EFAULT;
- /* we mostly copy too much here (512bytes), but who cares ;) */
- if (copy_from_user(kbs, user_kdgkb, sizeof(struct kbsentry))) {
- ret = -EFAULT;
- goto reterr;
- }
- kbs->kb_string[sizeof(kbs->kb_string)-1] = '\0';
- i = array_index_nospec(kbs->kb_func, MAX_NR_FUNC);
+ i = array_index_nospec(i, MAX_NR_FUNC);
switch (cmd) {
case KDGKBSENT:
- sz = sizeof(kbs->kb_string) - 1; /* sz should have been
- a struct member */
+ /* sz should have been a struct member */
+ sz = sizeof_field(struct kbsentry, kb_string) - 1;
up = user_kdgkb->kb_string;
p = func_table[i];
if(p)
for ( ; *p && sz; p++, sz--)
- if (put_user(*p, up++)) {
- ret = -EFAULT;
- goto reterr;
- }
- if (put_user('\0', up)) {
- ret = -EFAULT;
- goto reterr;
- }
- kfree(kbs);
+ if (put_user(*p, up++))
+ return -EFAULT;
+
+ if (put_user('\0', up))
+ return -EFAULT;
+
return ((p && *p) ? -EOVERFLOW : 0);
case KDSKBSENT:
- if (!perm) {
- ret = -EPERM;
- goto reterr;
- }
+ if (!perm)
+ return -EPERM;
+
+ kbs = strndup_user(user_kdgkb->kb_string,
+ sizeof(user_kdgkb->kb_string));
+ if (IS_ERR(kbs))
+ return PTR_ERR(kbs);
fnw = NULL;
fnw_sz = 0;
@@ -2062,7 +2053,7 @@ int vt_do_kdgkb_ioctl(int cmd, struct kbsentry __user *user_kdgkb, int perm)
else
fj = first_free;
/* buffer usage increase by new entry */
- delta = (q ? -strlen(q) : 1) + strlen(kbs->kb_string);
+ delta = (q ? -strlen(q) : 1) + strlen(kbs);
if (delta <= funcbufleft) { /* it fits in current buf */
if (j < MAX_NR_FUNC) {
@@ -2114,7 +2105,7 @@ int vt_do_kdgkb_ioctl(int cmd, struct kbsentry __user *user_kdgkb, int perm)
funcbufsize = sz;
}
/* finally insert item itself */
- strcpy(func_table[i], kbs->kb_string);
+ strcpy(func_table[i], kbs);
spin_unlock_irqrestore(&func_buf_lock, flags);
break;
}
--
2.28.0
^ permalink raw reply related [flat|nested] 6+ messages in thread
* [PATCH 2/3] vt: keyboard, simplify vt_kdgkbsent
2020-10-16 12:24 [PATCH 1/3] vt: keyboard, reorder user buffer handling in vt_do_kdgkb_ioctl Jiri Slaby
@ 2020-10-16 12:24 ` Jiri Slaby
2020-10-16 12:24 ` [PATCH 3/3] vt: keyboard, extend func_buf_lock to readers Jiri Slaby
1 sibling, 0 replies; 6+ messages in thread
From: Jiri Slaby @ 2020-10-16 12:24 UTC (permalink / raw)
To: gregkh; +Cc: linux-serial, linux-kernel, Minh Yuan, Jiri Slaby
Use 'strlen' of the string, add one for NUL and simply do 'copy_to_user'
instead of the explicit 'for' loop. This makes the KDGKBSENT case more
compact.
The only thing we need to take care about is NULL 'from'.
The original check for overflow could never trigger as the func_buf
(called 'from' here) strings are always shorter or equal to struct
kbsentry's.
Signed-off-by: Jiri Slaby <jslaby@suse.cz>
---
drivers/tty/vt/keyboard.c | 21 +++++++--------------
1 file changed, 7 insertions(+), 14 deletions(-)
diff --git a/drivers/tty/vt/keyboard.c b/drivers/tty/vt/keyboard.c
index d8e2452da1bd..68f9f6a62d02 100644
--- a/drivers/tty/vt/keyboard.c
+++ b/drivers/tty/vt/keyboard.c
@@ -1995,9 +1995,7 @@ int vt_do_kdsk_ioctl(int cmd, struct kbentry __user *user_kbe, int perm,
int vt_do_kdgkb_ioctl(int cmd, struct kbsentry __user *user_kdgkb, int perm)
{
char *kbs;
- char *p;
u_char *q;
- u_char __user *up;
int sz, fnw_sz;
int delta;
char *first_free, *fj, *fnw;
@@ -2014,20 +2012,15 @@ int vt_do_kdgkb_ioctl(int cmd, struct kbsentry __user *user_kdgkb, int perm)
i = array_index_nospec(i, MAX_NR_FUNC);
switch (cmd) {
- case KDGKBSENT:
- /* sz should have been a struct member */
- sz = sizeof_field(struct kbsentry, kb_string) - 1;
- up = user_kdgkb->kb_string;
- p = func_table[i];
- if(p)
- for ( ; *p && sz; p++, sz--)
- if (put_user(*p, up++))
- return -EFAULT;
-
- if (put_user('\0', up))
+ case KDGKBSENT: {
+ /* size should have been a struct member */
+ unsigned char *from = func_table[i] ? : "";
+
+ if (copy_to_user(user_kdgkb->kb_string, from, strlen(from) + 1))
return -EFAULT;
- return ((p && *p) ? -EOVERFLOW : 0);
+ return 0;
+ }
case KDSKBSENT:
if (!perm)
return -EPERM;
--
2.28.0
^ permalink raw reply related [flat|nested] 6+ messages in thread
* [PATCH 3/3] vt: keyboard, extend func_buf_lock to readers
2020-10-16 12:24 [PATCH 1/3] vt: keyboard, reorder user buffer handling in vt_do_kdgkb_ioctl Jiri Slaby
2020-10-16 12:24 ` [PATCH 2/3] vt: keyboard, simplify vt_kdgkbsent Jiri Slaby
@ 2020-10-16 12:24 ` Jiri Slaby
2020-10-16 13:20 ` Greg KH
1 sibling, 1 reply; 6+ messages in thread
From: Jiri Slaby @ 2020-10-16 12:24 UTC (permalink / raw)
To: gregkh; +Cc: linux-serial, linux-kernel, Minh Yuan, Jiri Slaby
Both read-side users of func_table/func_buf need locking. Without that,
one can easily confuse the code by repeatedly setting altering strings
like:
while (1)
for (a = 0; a < 2; a++) {
struct kbsentry kbs = {};
strcpy((char *)kbs.kb_string, a ? ".\n" : "88888\n");
ioctl(fd, KDSKBSENT, &kbs);
}
When that program runs, one can get unexpected output by holding F1
(note the unxpected period on the last line):
.
88888
.8888
So protect all accesses to 'func_table' (and func_buf) by preexisting
'func_buf_lock'.
It is easy in 'k_fn' handler as 'puts_queue' is expected not to sleep.
On the other hand, KDGKBSENT needs a local (atomic) copy of the string
because copy_to_user can sleep.
Likely fixes CVE-2020-25656.
Signed-off-by: Jiri Slaby <jslaby@suse.cz>
Reported-by: Minh Yuan <yuanmingbuaa@gmail.com>
---
drivers/tty/vt/keyboard.c | 26 +++++++++++++++++++++-----
1 file changed, 21 insertions(+), 5 deletions(-)
diff --git a/drivers/tty/vt/keyboard.c b/drivers/tty/vt/keyboard.c
index 68f9f6a62d02..68b1acc0074c 100644
--- a/drivers/tty/vt/keyboard.c
+++ b/drivers/tty/vt/keyboard.c
@@ -743,8 +743,13 @@ static void k_fn(struct vc_data *vc, unsigned char value, char up_flag)
return;
if ((unsigned)value < ARRAY_SIZE(func_table)) {
+ unsigned long flags;
+
+ spin_lock_irqsave(&func_buf_lock, flags);
if (func_table[value])
puts_queue(vc, func_table[value]);
+ spin_unlock_irqrestore(&func_buf_lock, flags);
+
} else
pr_err("k_fn called with value=%d\n", value);
}
@@ -1991,7 +1996,7 @@ int vt_do_kdsk_ioctl(int cmd, struct kbentry __user *user_kbe, int perm,
#undef s
#undef v
-/* FIXME: This one needs untangling and locking */
+/* FIXME: This one needs untangling */
int vt_do_kdgkb_ioctl(int cmd, struct kbsentry __user *user_kdgkb, int perm)
{
char *kbs;
@@ -2014,12 +2019,23 @@ int vt_do_kdgkb_ioctl(int cmd, struct kbsentry __user *user_kdgkb, int perm)
switch (cmd) {
case KDGKBSENT: {
/* size should have been a struct member */
- unsigned char *from = func_table[i] ? : "";
+ char *func_copy;
+ ssize_t len = sizeof(user_kdgkb->kb_string);
- if (copy_to_user(user_kdgkb->kb_string, from, strlen(from) + 1))
- return -EFAULT;
+ func_copy = kmalloc(len, GFP_KERNEL);
+ if (!func_copy)
+ return -ENOMEM;
- return 0;
+ spin_lock_irqsave(&func_buf_lock, flags);
+ len = strlcpy(func_copy, func_table[i] ? : "", len);
+ spin_unlock_irqrestore(&func_buf_lock, flags);
+
+ ret = copy_to_user(user_kdgkb->kb_string, func_copy, len + 1) ?
+ -EFAULT : 0;
+
+ kfree(func_copy);
+
+ return ret;
}
case KDSKBSENT:
if (!perm)
--
2.28.0
^ permalink raw reply related [flat|nested] 6+ messages in thread
* Re: [PATCH 3/3] vt: keyboard, extend func_buf_lock to readers
2020-10-16 12:24 ` [PATCH 3/3] vt: keyboard, extend func_buf_lock to readers Jiri Slaby
@ 2020-10-16 13:20 ` Greg KH
2020-10-19 8:00 ` Jiri Slaby
0 siblings, 1 reply; 6+ messages in thread
From: Greg KH @ 2020-10-16 13:20 UTC (permalink / raw)
To: Jiri Slaby; +Cc: linux-serial, linux-kernel, Minh Yuan
On Fri, Oct 16, 2020 at 02:24:12PM +0200, Jiri Slaby wrote:
> Both read-side users of func_table/func_buf need locking. Without that,
> one can easily confuse the code by repeatedly setting altering strings
> like:
> while (1)
> for (a = 0; a < 2; a++) {
> struct kbsentry kbs = {};
> strcpy((char *)kbs.kb_string, a ? ".\n" : "88888\n");
> ioctl(fd, KDSKBSENT, &kbs);
> }
>
> When that program runs, one can get unexpected output by holding F1
> (note the unxpected period on the last line):
> .
> 88888
> .8888
>
> So protect all accesses to 'func_table' (and func_buf) by preexisting
> 'func_buf_lock'.
>
> It is easy in 'k_fn' handler as 'puts_queue' is expected not to sleep.
> On the other hand, KDGKBSENT needs a local (atomic) copy of the string
> because copy_to_user can sleep.
>
> Likely fixes CVE-2020-25656.
>
> Signed-off-by: Jiri Slaby <jslaby@suse.cz>
> Reported-by: Minh Yuan <yuanmingbuaa@gmail.com>
> ---
> drivers/tty/vt/keyboard.c | 26 +++++++++++++++++++++-----
> 1 file changed, 21 insertions(+), 5 deletions(-)
So all 3 of these should go to 5.10-final?
thanks,
greg k-h
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [PATCH 3/3] vt: keyboard, extend func_buf_lock to readers
2020-10-16 13:20 ` Greg KH
@ 2020-10-19 8:00 ` Jiri Slaby
0 siblings, 0 replies; 6+ messages in thread
From: Jiri Slaby @ 2020-10-19 8:00 UTC (permalink / raw)
To: Greg KH; +Cc: linux-serial, linux-kernel, Minh Yuan
On 16. 10. 20, 15:20, Greg KH wrote:
> On Fri, Oct 16, 2020 at 02:24:12PM +0200, Jiri Slaby wrote:
>> Both read-side users of func_table/func_buf need locking. Without that,
>> one can easily confuse the code by repeatedly setting altering strings
>> like:
>> while (1)
>> for (a = 0; a < 2; a++) {
>> struct kbsentry kbs = {};
>> strcpy((char *)kbs.kb_string, a ? ".\n" : "88888\n");
>> ioctl(fd, KDSKBSENT, &kbs);
>> }
>>
>> When that program runs, one can get unexpected output by holding F1
>> (note the unxpected period on the last line):
>> .
>> 88888
>> .8888
>>
>> So protect all accesses to 'func_table' (and func_buf) by preexisting
>> 'func_buf_lock'.
>>
>> It is easy in 'k_fn' handler as 'puts_queue' is expected not to sleep.
>> On the other hand, KDGKBSENT needs a local (atomic) copy of the string
>> because copy_to_user can sleep.
>>
>> Likely fixes CVE-2020-25656.
>>
>> Signed-off-by: Jiri Slaby <jslaby@suse.cz>
>> Reported-by: Minh Yuan <yuanmingbuaa@gmail.com>
>> ---
>> drivers/tty/vt/keyboard.c | 26 +++++++++++++++++++++-----
>> 1 file changed, 21 insertions(+), 5 deletions(-)
>
> So all 3 of these should go to 5.10-final?
Let me try to eliminate also patch 1/3 which I now think is possible.
--
js
suse labs
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [PATCH 1/3] vt: keyboard, reorder user buffer handling in vt_do_kdgkb_ioctl
@ 2020-10-16 14:13 kernel test robot
0 siblings, 0 replies; 6+ messages in thread
From: kernel test robot @ 2020-10-16 14:13 UTC (permalink / raw)
To: kbuild
[-- Attachment #1: Type: text/plain, Size: 11804 bytes --]
CC: kbuild-all(a)lists.01.org
In-Reply-To: <20201016122412.31767-1-jslaby@suse.cz>
References: <20201016122412.31767-1-jslaby@suse.cz>
TO: Jiri Slaby <jslaby@suse.cz>
Hi Jiri,
I love your patch! Perhaps something to improve:
[auto build test WARNING on tty/tty-testing]
[also build test WARNING on v5.9 next-20201016]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch]
url: https://github.com/0day-ci/linux/commits/Jiri-Slaby/vt-keyboard-reorder-user-buffer-handling-in-vt_do_kdgkb_ioctl/20201016-202459
base: https://git.kernel.org/pub/scm/linux/kernel/git/gregkh/tty.git tty-testing
:::::: branch date: 2 hours ago
:::::: commit date: 2 hours ago
config: i386-randconfig-m021-20201016 (attached as .config)
compiler: gcc-9 (Debian 9.3.0-15) 9.3.0
If you fix the issue, kindly add following tag as appropriate
Reported-by: kernel test robot <lkp@intel.com>
Reported-by: Dan Carpenter <dan.carpenter@oracle.com>
New smatch warnings:
drivers/tty/vt/keyboard.c:2114 vt_do_kdgkb_ioctl() error: uninitialized symbol 'kbs'.
Old smatch warnings:
drivers/tty/vt/keyboard.c:1909 vt_do_kdsk_ioctl() warn: potential spectre issue 'key_map' [r]
drivers/tty/vt/keyboard.c:2052 vt_do_kdgkb_ioctl() warn: potential spectre issue 'func_table' [r] (local cap)
drivers/tty/vt/keyboard.c:2061 vt_do_kdgkb_ioctl() warn: possible spectre second half. 'fj'
drivers/tty/vt/keyboard.c:2067 vt_do_kdgkb_ioctl() warn: possible spectre second half. 'fj'
drivers/tty/vt/keyboard.c:2086 vt_do_kdgkb_ioctl() warn: possible spectre second half. 'fj'
drivers/tty/vt/keyboard.c:2088 vt_do_kdgkb_ioctl() warn: possible spectre second half. 'fj'
vim +/kbs +2114 drivers/tty/vt/keyboard.c
079c9534a96da9a Alan Cox 2012-02-28 1993
079c9534a96da9a Alan Cox 2012-02-28 1994 /* FIXME: This one needs untangling and locking */
079c9534a96da9a Alan Cox 2012-02-28 1995 int vt_do_kdgkb_ioctl(int cmd, struct kbsentry __user *user_kdgkb, int perm)
079c9534a96da9a Alan Cox 2012-02-28 1996 {
987bbe4f15e721c Jiri Slaby 2020-10-16 1997 char *kbs;
079c9534a96da9a Alan Cox 2012-02-28 1998 char *p;
079c9534a96da9a Alan Cox 2012-02-28 1999 u_char *q;
079c9534a96da9a Alan Cox 2012-02-28 2000 u_char __user *up;
46ca3f735f345c9 Sergei Trofimovich 2019-03-10 2001 int sz, fnw_sz;
079c9534a96da9a Alan Cox 2012-02-28 2002 int delta;
079c9534a96da9a Alan Cox 2012-02-28 2003 char *first_free, *fj, *fnw;
079c9534a96da9a Alan Cox 2012-02-28 2004 int i, j, k;
079c9534a96da9a Alan Cox 2012-02-28 2005 int ret;
46ca3f735f345c9 Sergei Trofimovich 2019-03-10 2006 unsigned long flags;
079c9534a96da9a Alan Cox 2012-02-28 2007
079c9534a96da9a Alan Cox 2012-02-28 2008 if (!capable(CAP_SYS_TTY_CONFIG))
079c9534a96da9a Alan Cox 2012-02-28 2009 perm = 0;
079c9534a96da9a Alan Cox 2012-02-28 2010
987bbe4f15e721c Jiri Slaby 2020-10-16 2011 if (get_user(i, &user_kdgkb->kb_func))
987bbe4f15e721c Jiri Slaby 2020-10-16 2012 return -EFAULT;
079c9534a96da9a Alan Cox 2012-02-28 2013
987bbe4f15e721c Jiri Slaby 2020-10-16 2014 i = array_index_nospec(i, MAX_NR_FUNC);
079c9534a96da9a Alan Cox 2012-02-28 2015
079c9534a96da9a Alan Cox 2012-02-28 2016 switch (cmd) {
079c9534a96da9a Alan Cox 2012-02-28 2017 case KDGKBSENT:
987bbe4f15e721c Jiri Slaby 2020-10-16 2018 /* sz should have been a struct member */
987bbe4f15e721c Jiri Slaby 2020-10-16 2019 sz = sizeof_field(struct kbsentry, kb_string) - 1;
079c9534a96da9a Alan Cox 2012-02-28 2020 up = user_kdgkb->kb_string;
079c9534a96da9a Alan Cox 2012-02-28 2021 p = func_table[i];
079c9534a96da9a Alan Cox 2012-02-28 2022 if(p)
079c9534a96da9a Alan Cox 2012-02-28 2023 for ( ; *p && sz; p++, sz--)
987bbe4f15e721c Jiri Slaby 2020-10-16 2024 if (put_user(*p, up++))
987bbe4f15e721c Jiri Slaby 2020-10-16 2025 return -EFAULT;
987bbe4f15e721c Jiri Slaby 2020-10-16 2026
987bbe4f15e721c Jiri Slaby 2020-10-16 2027 if (put_user('\0', up))
987bbe4f15e721c Jiri Slaby 2020-10-16 2028 return -EFAULT;
987bbe4f15e721c Jiri Slaby 2020-10-16 2029
079c9534a96da9a Alan Cox 2012-02-28 2030 return ((p && *p) ? -EOVERFLOW : 0);
079c9534a96da9a Alan Cox 2012-02-28 2031 case KDSKBSENT:
987bbe4f15e721c Jiri Slaby 2020-10-16 2032 if (!perm)
987bbe4f15e721c Jiri Slaby 2020-10-16 2033 return -EPERM;
987bbe4f15e721c Jiri Slaby 2020-10-16 2034
987bbe4f15e721c Jiri Slaby 2020-10-16 2035 kbs = strndup_user(user_kdgkb->kb_string,
987bbe4f15e721c Jiri Slaby 2020-10-16 2036 sizeof(user_kdgkb->kb_string));
987bbe4f15e721c Jiri Slaby 2020-10-16 2037 if (IS_ERR(kbs))
987bbe4f15e721c Jiri Slaby 2020-10-16 2038 return PTR_ERR(kbs);
079c9534a96da9a Alan Cox 2012-02-28 2039
46ca3f735f345c9 Sergei Trofimovich 2019-03-10 2040 fnw = NULL;
46ca3f735f345c9 Sergei Trofimovich 2019-03-10 2041 fnw_sz = 0;
46ca3f735f345c9 Sergei Trofimovich 2019-03-10 2042 /* race aginst other writers */
46ca3f735f345c9 Sergei Trofimovich 2019-03-10 2043 again:
46ca3f735f345c9 Sergei Trofimovich 2019-03-10 2044 spin_lock_irqsave(&func_buf_lock, flags);
079c9534a96da9a Alan Cox 2012-02-28 2045 q = func_table[i];
46ca3f735f345c9 Sergei Trofimovich 2019-03-10 2046
46ca3f735f345c9 Sergei Trofimovich 2019-03-10 2047 /* fj pointer to next entry after 'q' */
079c9534a96da9a Alan Cox 2012-02-28 2048 first_free = funcbufptr + (funcbufsize - funcbufleft);
079c9534a96da9a Alan Cox 2012-02-28 2049 for (j = i+1; j < MAX_NR_FUNC && !func_table[j]; j++)
079c9534a96da9a Alan Cox 2012-02-28 2050 ;
079c9534a96da9a Alan Cox 2012-02-28 2051 if (j < MAX_NR_FUNC)
079c9534a96da9a Alan Cox 2012-02-28 2052 fj = func_table[j];
079c9534a96da9a Alan Cox 2012-02-28 2053 else
079c9534a96da9a Alan Cox 2012-02-28 2054 fj = first_free;
46ca3f735f345c9 Sergei Trofimovich 2019-03-10 2055 /* buffer usage increase by new entry */
987bbe4f15e721c Jiri Slaby 2020-10-16 2056 delta = (q ? -strlen(q) : 1) + strlen(kbs);
46ca3f735f345c9 Sergei Trofimovich 2019-03-10 2057
079c9534a96da9a Alan Cox 2012-02-28 2058 if (delta <= funcbufleft) { /* it fits in current buf */
079c9534a96da9a Alan Cox 2012-02-28 2059 if (j < MAX_NR_FUNC) {
46ca3f735f345c9 Sergei Trofimovich 2019-03-10 2060 /* make enough space for new entry@'fj' */
079c9534a96da9a Alan Cox 2012-02-28 2061 memmove(fj + delta, fj, first_free - fj);
079c9534a96da9a Alan Cox 2012-02-28 2062 for (k = j; k < MAX_NR_FUNC; k++)
079c9534a96da9a Alan Cox 2012-02-28 2063 if (func_table[k])
079c9534a96da9a Alan Cox 2012-02-28 2064 func_table[k] += delta;
079c9534a96da9a Alan Cox 2012-02-28 2065 }
079c9534a96da9a Alan Cox 2012-02-28 2066 if (!q)
079c9534a96da9a Alan Cox 2012-02-28 2067 func_table[i] = fj;
079c9534a96da9a Alan Cox 2012-02-28 2068 funcbufleft -= delta;
079c9534a96da9a Alan Cox 2012-02-28 2069 } else { /* allocate a larger buffer */
079c9534a96da9a Alan Cox 2012-02-28 2070 sz = 256;
079c9534a96da9a Alan Cox 2012-02-28 2071 while (sz < funcbufsize - funcbufleft + delta)
079c9534a96da9a Alan Cox 2012-02-28 2072 sz <<= 1;
46ca3f735f345c9 Sergei Trofimovich 2019-03-10 2073 if (fnw_sz != sz) {
46ca3f735f345c9 Sergei Trofimovich 2019-03-10 2074 spin_unlock_irqrestore(&func_buf_lock, flags);
46ca3f735f345c9 Sergei Trofimovich 2019-03-10 2075 kfree(fnw);
079c9534a96da9a Alan Cox 2012-02-28 2076 fnw = kmalloc(sz, GFP_KERNEL);
46ca3f735f345c9 Sergei Trofimovich 2019-03-10 2077 fnw_sz = sz;
079c9534a96da9a Alan Cox 2012-02-28 2078 if (!fnw) {
079c9534a96da9a Alan Cox 2012-02-28 2079 ret = -ENOMEM;
079c9534a96da9a Alan Cox 2012-02-28 2080 goto reterr;
079c9534a96da9a Alan Cox 2012-02-28 2081 }
46ca3f735f345c9 Sergei Trofimovich 2019-03-10 2082 goto again;
46ca3f735f345c9 Sergei Trofimovich 2019-03-10 2083 }
079c9534a96da9a Alan Cox 2012-02-28 2084
079c9534a96da9a Alan Cox 2012-02-28 2085 if (!q)
079c9534a96da9a Alan Cox 2012-02-28 2086 func_table[i] = fj;
46ca3f735f345c9 Sergei Trofimovich 2019-03-10 2087 /* copy data before insertion point to new location */
079c9534a96da9a Alan Cox 2012-02-28 2088 if (fj > funcbufptr)
079c9534a96da9a Alan Cox 2012-02-28 2089 memmove(fnw, funcbufptr, fj - funcbufptr);
079c9534a96da9a Alan Cox 2012-02-28 2090 for (k = 0; k < j; k++)
079c9534a96da9a Alan Cox 2012-02-28 2091 if (func_table[k])
079c9534a96da9a Alan Cox 2012-02-28 2092 func_table[k] = fnw + (func_table[k] - funcbufptr);
079c9534a96da9a Alan Cox 2012-02-28 2093
46ca3f735f345c9 Sergei Trofimovich 2019-03-10 2094 /* copy data after insertion point to new location */
079c9534a96da9a Alan Cox 2012-02-28 2095 if (first_free > fj) {
079c9534a96da9a Alan Cox 2012-02-28 2096 memmove(fnw + (fj - funcbufptr) + delta, fj, first_free - fj);
079c9534a96da9a Alan Cox 2012-02-28 2097 for (k = j; k < MAX_NR_FUNC; k++)
079c9534a96da9a Alan Cox 2012-02-28 2098 if (func_table[k])
079c9534a96da9a Alan Cox 2012-02-28 2099 func_table[k] = fnw + (func_table[k] - funcbufptr) + delta;
079c9534a96da9a Alan Cox 2012-02-28 2100 }
079c9534a96da9a Alan Cox 2012-02-28 2101 if (funcbufptr != func_buf)
079c9534a96da9a Alan Cox 2012-02-28 2102 kfree(funcbufptr);
079c9534a96da9a Alan Cox 2012-02-28 2103 funcbufptr = fnw;
079c9534a96da9a Alan Cox 2012-02-28 2104 funcbufleft = funcbufleft - delta + sz - funcbufsize;
079c9534a96da9a Alan Cox 2012-02-28 2105 funcbufsize = sz;
079c9534a96da9a Alan Cox 2012-02-28 2106 }
46ca3f735f345c9 Sergei Trofimovich 2019-03-10 2107 /* finally insert item itself */
987bbe4f15e721c Jiri Slaby 2020-10-16 2108 strcpy(func_table[i], kbs);
46ca3f735f345c9 Sergei Trofimovich 2019-03-10 2109 spin_unlock_irqrestore(&func_buf_lock, flags);
079c9534a96da9a Alan Cox 2012-02-28 2110 break;
079c9534a96da9a Alan Cox 2012-02-28 2111 }
079c9534a96da9a Alan Cox 2012-02-28 2112 ret = 0;
079c9534a96da9a Alan Cox 2012-02-28 2113 reterr:
079c9534a96da9a Alan Cox 2012-02-28 @2114 kfree(kbs);
079c9534a96da9a Alan Cox 2012-02-28 2115 return ret;
079c9534a96da9a Alan Cox 2012-02-28 2116 }
079c9534a96da9a Alan Cox 2012-02-28 2117
---
0-DAY CI Kernel Test Service, Intel Corporation
https://lists.01.org/hyperkitty/list/kbuild-all@lists.01.org
[-- Attachment #2: config.gz --]
[-- Type: application/gzip, Size: 31955 bytes --]
^ permalink raw reply [flat|nested] 6+ messages in thread
end of thread, other threads:[~2020-10-19 8:00 UTC | newest]
Thread overview: 6+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-10-16 12:24 [PATCH 1/3] vt: keyboard, reorder user buffer handling in vt_do_kdgkb_ioctl Jiri Slaby
2020-10-16 12:24 ` [PATCH 2/3] vt: keyboard, simplify vt_kdgkbsent Jiri Slaby
2020-10-16 12:24 ` [PATCH 3/3] vt: keyboard, extend func_buf_lock to readers Jiri Slaby
2020-10-16 13:20 ` Greg KH
2020-10-19 8:00 ` Jiri Slaby
2020-10-16 14:13 [PATCH 1/3] vt: keyboard, reorder user buffer handling in vt_do_kdgkb_ioctl kernel test robot
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.