Lines Matching +full:write +full:- +full:0

1 // SPDX-License-Identifier: GPL-2.0-only
9 * Added kernel/java-{interpreter,appletviewer}, 96/5/10, Mike Shaver.
11 * Added kswapd-interval, ctrl-alt-del, printk stuff, 1/8/97, Chris Horn.
85 const int sysctl_vals[] = { 0, 1, 2, 3, 4, 100, 200, 1000, 3000, INT_MAX, 65535, -1 };
88 const unsigned long sysctl_long_vals[] = { 0, 1, LONG_MAX };
106 * enum sysctl_writes_mode - supported sysctl write modes
108 * @SYSCTL_WRITES_LEGACY: each write syscall must fully contain the sysctl value
111 * is issued when the initial position is not 0.
113 * not 0.
115 * file position 0 and the value must be fully contained in the buffer
116 * sent to the write syscall. If dealing with strings respect the file
121 * These write modes control how current file position affects the behavior of
122 * updating sysctl values through the proc interface on each write.
125 SYSCTL_WRITES_LEGACY = -1,
126 SYSCTL_WRITES_WARN = 0,
146 static int _proc_do_string(char *data, int maxlen, int write,
153 *lenp = 0;
154 return 0;
157 if (write) {
161 if (len > maxlen - 1)
162 len = maxlen - 1;
165 return 0;
169 len = 0;
174 while ((p - buffer) < *lenp && len < maxlen - 1) {
176 if (c == 0 || c == '\n')
180 data[len] = 0;
187 *lenp = 0;
188 return 0;
192 len -= *ppos;
205 return 0;
210 pr_warn_once("%s wrote to %s when file position was not 0!\n"
212 "warning, set kernel.sysctl_writes_strict = -1\n",
213 current->comm, table->procname);
217 * proc_first_pos_non_zero_ignore - check if first position is allowed
221 * Returns true if the first position is non-zero and the sysctl_writes_strict
243 * proc_dostring - read a string sysctl
245 * @write: %TRUE if this is a write to the sysctl file
252 * string is truncated. The copied string is %NULL-terminated.
257 * Returns 0 on success.
259 int proc_dostring(const struct ctl_table *table, int write,
262 if (write)
265 return _proc_do_string(table->data, table->maxlen, write, buffer, lenp,
274 (*size)--;
284 (*size)--;
290 * strtoul_lenient - parse an ASCII formatted integer from a buffer and only
298 * In case of success 0 is returned and @res will contain the parsed integer,
313 return -ERANGE;
321 return 0;
326 * proc_get_long - reads an ASCII formatted integer from a user buffer
336 * In case of success %0 is returned and @buf and @size are updated with
337 * the amount of bytes read. If @tr is non-NULL and a trailing
338 * character exists (size is non-zero after returning from this
348 if (len <= 0)
349 return -EINVAL;
351 if (len > TMPBUFLEN - 1)
352 len = TMPBUFLEN - 1;
356 tmp[len] = 0;
358 if (*p == '-' && *size > 1) {
364 return -EINVAL;
366 if (strtoul_lenient(p, &p, 0, val))
367 return -EINVAL;
369 len = p - tmp;
374 if (len == TMPBUFLEN - 1)
375 return -EINVAL;
378 return -EINVAL;
384 *size -= len;
386 return 0;
390 * proc_put_long - converts an integer to a decimal ASCII formatted string
405 sprintf(p, "%s%lu", neg ? "-" : "", val);
410 *size -= len;
421 (*size)--;
429 int write, void *data)
431 if (write) {
434 return -EINVAL;
435 WRITE_ONCE(*valp, -*lvalp);
438 return -EINVAL;
443 if (val < 0) {
445 *lvalp = -(unsigned long)val;
451 return 0;
456 int write, void *data)
458 if (write) {
460 return -EINVAL;
466 return 0;
472 int write, void *buffer,
475 int write, void *data),
478 int *i, vleft, first = 1, err = 0;
482 if (!tbl_data || !table->maxlen || !*lenp || (*ppos && !write)) {
483 *lenp = 0;
484 return 0;
488 vleft = table->maxlen / sizeof(*i);
494 if (write) {
498 if (left > PAGE_SIZE - 1)
499 left = PAGE_SIZE - 1;
503 for (; left && vleft--; i++, first=0) {
507 if (write) {
518 err = -EINVAL;
522 if (conv(&neg, &lval, i, 0, data)) {
523 err = -EINVAL;
532 if (!write && !first && left && !err)
534 if (write && !err && left)
536 if (write && first)
537 return err ? : -EINVAL;
538 *lenp -= left;
544 static int do_proc_dointvec(const struct ctl_table *table, int write,
547 int write, void *data),
550 return __do_proc_dointvec(table->data, table, write,
560 int write, void *data),
564 int err = 0;
574 if (left > PAGE_SIZE - 1)
575 left = PAGE_SIZE - 1;
579 err = -EINVAL;
587 err = -EINVAL;
592 err = -EINVAL;
601 return -EINVAL;
603 return 0;
615 int write, void *data),
619 int err = 0;
624 if (conv(&lval, tbl_data, 0, data)) {
625 err = -EINVAL;
636 *lenp -= left;
643 int write, void *buffer,
647 int write, void *data),
652 if (!tbl_data || !table->maxlen || !*lenp || (*ppos && !write)) {
653 *lenp = 0;
654 return 0;
658 vleft = table->maxlen / sizeof(*i);
665 *lenp = 0;
666 return -EINVAL;
672 if (write)
678 int do_proc_douintvec(const struct ctl_table *table, int write,
682 int write, void *data),
685 return __do_proc_douintvec(table->data, table, write,
690 * proc_dobool - read/write a bool
692 * @write: %TRUE if this is a write to the sysctl file
700 * table->data must point to a bool variable and table->maxlen must
703 * Returns 0 on success.
705 int proc_dobool(const struct ctl_table *table, int write, void *buffer,
709 bool *data = table->data;
713 if (table->maxlen != sizeof(bool))
714 return -EINVAL;
721 res = proc_dointvec(&tmp, write, buffer, lenp, ppos);
724 if (write)
726 return 0;
730 * proc_dointvec - read a vector of integers
732 * @write: %TRUE if this is a write to the sysctl file
737 * Reads/writes up to table->maxlen/sizeof(unsigned int) integer
740 * Returns 0 on success.
742 int proc_dointvec(const struct ctl_table *table, int write, void *buffer,
745 return do_proc_dointvec(table, write, buffer, lenp, ppos, NULL, NULL);
749 * proc_douintvec - read a vector of unsigned integers
751 * @write: %TRUE if this is a write to the sysctl file
756 * Reads/writes up to table->maxlen/sizeof(unsigned int) unsigned integer
759 * Returns 0 on success.
761 int proc_douintvec(const struct ctl_table *table, int write, void *buffer,
764 return do_proc_douintvec(table, write, buffer, lenp, ppos,
772 static int proc_taint(const struct ctl_table *table, int write,
779 if (write && !capable(CAP_SYS_ADMIN))
780 return -EPERM;
784 err = proc_doulongvec_minmax(&t, write, buffer, lenp, ppos);
785 if (err < 0)
788 if (write) {
797 return -EINVAL;
803 for (i = 0; i < TAINT_FLAGS_COUNT; i++)
812 * struct do_proc_dointvec_minmax_conv_param - proc_dointvec_minmax() range checking structure
827 int write, void *data)
833 * bounds-check it before touching *valp.
835 int *ip = write ? &tmp : valp;
837 ret = do_proc_dointvec_conv(negp, lvalp, ip, write, data);
841 if (write) {
842 if ((param->min && *param->min > tmp) ||
843 (param->max && *param->max < tmp))
844 return -EINVAL;
848 return 0;
852 * proc_dointvec_minmax - read a vector of integers with min/max values
854 * @write: %TRUE if this is a write to the sysctl file
859 * Reads/writes up to table->maxlen/sizeof(unsigned int) integer
863 * table->extra1 (min) and table->extra2 (max).
865 * Returns 0 on success or -EINVAL on write when the range check fails.
867 int proc_dointvec_minmax(const struct ctl_table *table, int write,
871 .min = (int *) table->extra1,
872 .max = (int *) table->extra2,
874 return do_proc_dointvec(table, write, buffer, lenp, ppos,
879 * struct do_proc_douintvec_minmax_conv_param - proc_douintvec_minmax() range checking structure
894 int write, void *data)
899 /* write via temporary local uint for bounds-checking */
900 unsigned int *up = write ? &tmp : valp;
902 ret = do_proc_douintvec_conv(lvalp, up, write, data);
906 if (write) {
907 if ((param->min && *param->min > tmp) ||
908 (param->max && *param->max < tmp))
909 return -ERANGE;
914 return 0;
918 * proc_douintvec_minmax - read a vector of unsigned ints with min/max values
920 * @write: %TRUE if this is a write to the sysctl file
925 * Reads/writes up to table->maxlen/sizeof(unsigned int) unsigned integer
930 * table->extra1 (min) and table->extra2 (max). There is a final sanity
934 * Returns 0 on success or -ERANGE on write when the range check fails.
936 int proc_douintvec_minmax(const struct ctl_table *table, int write,
940 .min = (unsigned int *) table->extra1,
941 .max = (unsigned int *) table->extra2,
943 return do_proc_douintvec(table, write, buffer, lenp, ppos,
948 * proc_dou8vec_minmax - read a vector of unsigned chars with min/max values
950 * @write: %TRUE if this is a write to the sysctl file
955 * Reads/writes up to table->maxlen/sizeof(u8) unsigned chars
960 * table->extra1 (min) and table->extra2 (max).
962 * Returns 0 on success or an error on write when the range check fails.
964 int proc_dou8vec_minmax(const struct ctl_table *table, int write,
968 unsigned int min = 0, max = 255U, val;
969 u8 *data = table->data;
977 if (table->maxlen != sizeof(u8))
978 return -EINVAL;
980 if (table->extra1)
981 min = *(unsigned int *) table->extra1;
982 if (table->extra2)
983 max = *(unsigned int *) table->extra2;
990 res = do_proc_douintvec(&tmp, write, buffer, lenp, ppos,
994 if (write)
996 return 0;
1001 static int sysrq_sysctl_handler(const struct ctl_table *table, int write,
1008 ret = __do_proc_dointvec(&tmp, table, write, buffer,
1010 if (ret || !write)
1013 if (write)
1016 return 0;
1021 const struct ctl_table *table, int write,
1026 int vleft, first = 1, err = 0;
1030 if (!data || !table->maxlen || !*lenp || (*ppos && !write)) {
1031 *lenp = 0;
1032 return 0;
1036 min = table->extra1;
1037 max = table->extra2;
1038 vleft = table->maxlen / sizeof(unsigned long);
1041 if (write) {
1045 if (left > PAGE_SIZE - 1)
1046 left = PAGE_SIZE - 1;
1050 for (; left && vleft--; i++, first = 0) {
1053 if (write) {
1064 err = -EINVAL;
1070 err = -EINVAL;
1082 if (!write && !first && left && !err)
1084 if (write && !err)
1086 if (write && first)
1087 return err ? : -EINVAL;
1088 *lenp -= left;
1094 static int do_proc_doulongvec_minmax(const struct ctl_table *table, int write,
1098 return __do_proc_doulongvec_minmax(table->data, table, write,
1103 * proc_doulongvec_minmax - read a vector of long integers with min/max values
1105 * @write: %TRUE if this is a write to the sysctl file
1110 * Reads/writes up to table->maxlen/sizeof(unsigned long) unsigned long
1114 * table->extra1 (min) and table->extra2 (max).
1116 * Returns 0 on success.
1118 int proc_doulongvec_minmax(const struct ctl_table *table, int write,
1121 return do_proc_doulongvec_minmax(table, write, buffer, lenp, ppos, 1l, 1l);
1125 * proc_doulongvec_ms_jiffies_minmax - read a vector of millisecond values with min/max values
1127 * @write: %TRUE if this is a write to the sysctl file
1132 * Reads/writes up to table->maxlen/sizeof(unsigned long) unsigned long
1137 * table->extra1 (min) and table->extra2 (max).
1139 * Returns 0 on success.
1141 int proc_doulongvec_ms_jiffies_minmax(const struct ctl_table *table, int write,
1144 return do_proc_doulongvec_minmax(table, write, buffer,
1151 int write, void *data)
1153 if (write) {
1157 WRITE_ONCE(*valp, -*lvalp * HZ);
1163 if (val < 0) {
1165 lval = -(unsigned long)val;
1172 return 0;
1177 int write, void *data)
1179 if (write) {
1182 *valp = clock_t_to_jiffies(*negp ? -*lvalp : *lvalp);
1186 if (val < 0) {
1188 lval = -(unsigned long)val;
1195 return 0;
1200 int write, void *data)
1202 if (write) {
1203 unsigned long jif = msecs_to_jiffies(*negp ? -*lvalp : *lvalp);
1211 if (val < 0) {
1213 lval = -(unsigned long)val;
1220 return 0;
1224 int *valp, int write, void *data)
1230 * bounds-check it before touching *valp.
1232 int *ip = write ? &tmp : valp;
1234 ret = do_proc_dointvec_ms_jiffies_conv(negp, lvalp, ip, write, data);
1238 if (write) {
1239 if ((param->min && *param->min > tmp) ||
1240 (param->max && *param->max < tmp))
1241 return -EINVAL;
1244 return 0;
1248 * proc_dointvec_jiffies - read a vector of integers as seconds
1250 * @write: %TRUE if this is a write to the sysctl file
1255 * Reads/writes up to table->maxlen/sizeof(unsigned int) integer
1260 * Returns 0 on success.
1262 int proc_dointvec_jiffies(const struct ctl_table *table, int write,
1265 return do_proc_dointvec(table,write,buffer,lenp,ppos,
1269 int proc_dointvec_ms_jiffies_minmax(const struct ctl_table *table, int write,
1273 .min = (int *) table->extra1,
1274 .max = (int *) table->extra2,
1276 return do_proc_dointvec(table, write, buffer, lenp, ppos,
1281 * proc_dointvec_userhz_jiffies - read a vector of integers as 1/USER_HZ seconds
1283 * @write: %TRUE if this is a write to the sysctl file
1288 * Reads/writes up to table->maxlen/sizeof(unsigned int) integer
1293 * Returns 0 on success.
1295 int proc_dointvec_userhz_jiffies(const struct ctl_table *table, int write,
1298 return do_proc_dointvec(table, write, buffer, lenp, ppos,
1303 * proc_dointvec_ms_jiffies - read a vector of integers as 1 milliseconds
1305 * @write: %TRUE if this is a write to the sysctl file
1310 * Reads/writes up to table->maxlen/sizeof(unsigned int) integer
1315 * Returns 0 on success.
1317 int proc_dointvec_ms_jiffies(const struct ctl_table *table, int write, void *buffer,
1320 return do_proc_dointvec(table, write, buffer, lenp, ppos,
1324 static int proc_do_cad_pid(const struct ctl_table *table, int write, void *buffer,
1333 r = __do_proc_dointvec(&tmp, table, write, buffer,
1335 if (r || !write)
1340 return -ESRCH;
1343 return 0;
1347 * proc_do_large_bitmap - read/write from/to a large bitmap
1349 * @write: %TRUE if this is a write to the sysctl file
1354 * The bitmap is stored at table->data and the bitmap length (in bits)
1355 * in table->maxlen.
1357 * We use a range comma separated format (e.g. 1,3-4,10-10) so that
1361 * Returns 0 on success.
1363 int proc_do_large_bitmap(const struct ctl_table *table, int write,
1366 int err = 0;
1368 unsigned long bitmap_len = table->maxlen;
1369 unsigned long *bitmap = *(unsigned long **) table->data;
1371 char tr_a[] = { '-', ',', '\n' }, tr_b[] = { ',', '\n', 0 }, c;
1373 if (!bitmap || !bitmap_len || !left || (*ppos && !write)) {
1374 *lenp = 0;
1375 return 0;
1378 if (write) {
1380 size_t skipped = 0;
1382 if (left > PAGE_SIZE - 1) {
1383 left = PAGE_SIZE - 1;
1385 skipped = *lenp - left;
1390 return -ENOMEM;
1397 /* In case we stop parsing mid-number, we can reset */
1403 * only one char is left (may be a "-"), then stop here,
1414 err = -EINVAL;
1421 left--;
1424 if (c == '-') {
1441 err = -EINVAL;
1446 left--;
1450 bitmap_set(tmp_bitmap, val_a, val_b - val_a + 1);
1455 unsigned long bit_a, bit_b = 0;
1463 bit_a + 1) - 1;
1469 proc_put_char(&buffer, &left, '-');
1473 first = 0; bit_b++;
1479 if (write) {
1485 *lenp -= left;
1495 int proc_dostring(const struct ctl_table *table, int write,
1498 return -ENOSYS;
1501 int proc_dobool(const struct ctl_table *table, int write,
1504 return -ENOSYS;
1507 int proc_dointvec(const struct ctl_table *table, int write,
1510 return -ENOSYS;
1513 int proc_douintvec(const struct ctl_table *table, int write,
1516 return -ENOSYS;
1519 int proc_dointvec_minmax(const struct ctl_table *table, int write,
1522 return -ENOSYS;
1525 int proc_douintvec_minmax(const struct ctl_table *table, int write,
1528 return -ENOSYS;
1531 int proc_dou8vec_minmax(const struct ctl_table *table, int write,
1534 return -ENOSYS;
1537 int proc_dointvec_jiffies(const struct ctl_table *table, int write,
1540 return -ENOSYS;
1543 int proc_dointvec_ms_jiffies_minmax(const struct ctl_table *table, int write,
1546 return -ENOSYS;
1549 int proc_dointvec_userhz_jiffies(const struct ctl_table *table, int write,
1552 return -ENOSYS;
1555 int proc_dointvec_ms_jiffies(const struct ctl_table *table, int write,
1558 return -ENOSYS;
1561 int proc_doulongvec_minmax(const struct ctl_table *table, int write,
1564 return -ENOSYS;
1567 int proc_doulongvec_ms_jiffies_minmax(const struct ctl_table *table, int write,
1570 return -ENOSYS;
1573 int proc_do_large_bitmap(const struct ctl_table *table, int write,
1576 return -ENOSYS;
1582 int proc_do_static_key(const struct ctl_table *table, int write,
1585 struct static_key *key = (struct static_key *)table->data;
1591 .mode = table->mode,
1596 if (write && !capable(CAP_SYS_ADMIN))
1597 return -EPERM;
1601 ret = proc_dointvec_minmax(&tmp, write, buffer, lenp, ppos);
1602 if (write && !ret) {
1638 .procname = "print-fatal-signals",
1646 .procname = "reboot-cmd",
1653 .procname = "stop-a",
1660 .procname = "scons-poweroff",
1669 .procname = "tsb-ratio",
1678 .procname = "soft-power",
1687 .procname = "unaligned-trap",
1739 /* only handle a transition from default "0" to "1" */
1773 .procname = "threads-max",
1929 .procname = "ignore-unaligned-usertrap",
1947 * User-space scripts rely on the existence of this file
2058 .procname = "page-cluster",
2170 .maxlen = 0,
2243 return 0;
2248 * exception granted :-)