Skip to content

Commit d43b823

Browse files
linux/spl: base proc_dohostid() on proc_dostring()
This fixes /proc/sys/kernel/spl/hostid on kernels with mainline commit 32927393dc1ccd60fb2bdc05b9e8e88753761469 ("sysctl: pass kernel pointers to ->proc_handler") ‒ 5.7-rc1 and up The access_ok() check in copy_to_user() in proc_copyout_string() would always fail, so all userspace reads and writes would fail with EINVAL This strictens write parsing by disallowing writes with extraneous whitespace at the end, i.e. "012345678\n" is still fine, but "012345678 \n" isn't anymore This also alters what happens when an invalid value is written ‒ previously it'd get set to what-ever simple_strtoul() returned (probably 0, thereby resetting it to default), now it does nothing Signed-off-by: Ahelenia Ziemiańska <[email protected]> Closes #11878
1 parent 07c43a6 commit d43b823

File tree

1 file changed

+18
-76
lines changed

1 file changed

+18
-76
lines changed

module/os/linux/spl/spl-proc.c

Lines changed: 18 additions & 76 deletions
Original file line numberDiff line numberDiff line change
@@ -53,60 +53,6 @@ static struct proc_dir_entry *proc_spl_taskq_all = NULL;
5353
static struct proc_dir_entry *proc_spl_taskq = NULL;
5454
struct proc_dir_entry *proc_spl_kstat = NULL;
5555

56-
static int
57-
proc_copyin_string(char *kbuffer, int kbuffer_size, const char *ubuffer,
58-
int ubuffer_size)
59-
{
60-
int size;
61-
62-
if (ubuffer_size > kbuffer_size)
63-
return (-EOVERFLOW);
64-
65-
if (copy_from_user((void *)kbuffer, (void *)ubuffer, ubuffer_size))
66-
return (-EFAULT);
67-
68-
/* strip trailing whitespace */
69-
size = strnlen(kbuffer, ubuffer_size);
70-
while (size-- >= 0)
71-
if (!isspace(kbuffer[size]))
72-
break;
73-
74-
/* empty string */
75-
if (size < 0)
76-
return (-EINVAL);
77-
78-
/* no space to terminate */
79-
if (size == kbuffer_size)
80-
return (-EOVERFLOW);
81-
82-
kbuffer[size + 1] = 0;
83-
return (0);
84-
}
85-
86-
static int
87-
proc_copyout_string(char *ubuffer, int ubuffer_size, const char *kbuffer,
88-
char *append)
89-
{
90-
/*
91-
* NB if 'append' != NULL, it's a single character to append to the
92-
* copied out string - usually "\n", for /proc entries and
93-
* (i.e. a terminating zero byte) for sysctl entries
94-
*/
95-
int size = MIN(strlen(kbuffer), ubuffer_size);
96-
97-
if (copy_to_user(ubuffer, kbuffer, size))
98-
return (-EFAULT);
99-
100-
if (append != NULL && size < ubuffer_size) {
101-
if (copy_to_user(ubuffer + size, append, 1))
102-
return (-EFAULT);
103-
104-
size++;
105-
}
106-
107-
return (size);
108-
}
109-
11056
#ifdef DEBUG_KMEM
11157
static int
11258
proc_domemused(struct ctl_table *table, int write,
@@ -187,39 +133,35 @@ static int
187133
proc_dohostid(struct ctl_table *table, int write,
188134
void __user *buffer, size_t *lenp, loff_t *ppos)
189135
{
190-
int len, rc = 0;
191136
char *end, str[32];
137+
unsigned long hid;
138+
spl_ctl_table dummy = *table;
139+
140+
dummy.data = str;
141+
dummy.maxlen = sizeof (str) - 1;
142+
143+
if (!write)
144+
snprintf(str, sizeof (str), "%lx",
145+
(unsigned long) zone_get_hostid(NULL));
146+
147+
/* always returns 0 */
148+
proc_dostring(&dummy, write, buffer, lenp, ppos);
192149

193150
if (write) {
194151
/*
195152
* We can't use proc_doulongvec_minmax() in the write
196-
* case here because hostid while a hex value has no
197-
* leading 0x which confuses the helper function.
153+
* case here because hostid, while a hex value, has no
154+
* leading 0x, which confuses the helper function.
198155
*/
199-
rc = proc_copyin_string(str, sizeof (str), buffer, *lenp);
200-
if (rc < 0)
201-
return (rc);
202156

203-
spl_hostid = simple_strtoul(str, &end, 16);
157+
/* proc_dostring() already stripped the final newline */
158+
hid = simple_strtoul(str, &end, 16);
204159
if (str == end)
205160
return (-EINVAL);
206-
207-
} else {
208-
len = snprintf(str, sizeof (str), "%lx",
209-
(unsigned long) zone_get_hostid(NULL));
210-
if (*ppos >= len)
211-
rc = 0;
212-
else
213-
rc = proc_copyout_string(buffer,
214-
*lenp, str + *ppos, "\n");
215-
216-
if (rc >= 0) {
217-
*lenp = rc;
218-
*ppos += rc;
219-
}
161+
spl_hostid = hid;
220162
}
221163

222-
return (rc);
164+
return (0);
223165
}
224166

225167
static void

0 commit comments

Comments
 (0)