diff options
author | Dmitry V. Levin <ldv@altlinux.org> | 2020-04-24 03:27:12 +0000 |
---|---|---|
committer | Dmitry V. Levin <ldv@altlinux.org> | 2020-04-24 03:27:12 +0000 |
commit | 924a93a39b61d3699926136713add09db2976fce (patch) | |
tree | 3839cbe230ff3a4eaae8d4799e46d7f365e0a851 /modules | |
parent | 76916913fc3802ccb5348a69a56fa2bc3946439d (diff) |
pam_filter: fix potential off-by-one heap buffer overflow
Reported by gcc-10 -Wstringop-overflow:
In file included from /usr/include/string.h:494,
from modules/pam_filter/pam_filter.c:14:
In function 'strcpy',
inlined from 'process_args' at modules/pam_filter/pam_filter.c:137:2,
inlined from 'need_a_filter.isra' at modules/pam_filter/pam_filter.c:618:12:
/usr/include/x86_64-linux-gnu/bits/string_fortified.h:90:10: warning: '__builtin_memcpy' writing 6 bytes into a region of size 5 [-Wstringop-overflow=]
90 | return __builtin___strcpy_chk (__dest, __src, __bos (__dest));
| ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
modules/pam_filter/pam_filter.c: In function 'need_a_filter.isra':
modules/pam_filter/pam_filter.c:128:21: note: at offset 0 to an object with size 5 allocated by 'malloc' here
128 | levp[0] = (char *) malloc(size);
| ^~~~~~~~~~~~
* modules/pam_filter/pam_filter.c (process_args): Fix off-by-one heap
buffer overflow in case of a filter without arguments (argc == 0).
Diffstat (limited to 'modules')
-rw-r--r-- | modules/pam_filter/pam_filter.c | 23 |
1 files changed, 11 insertions, 12 deletions
diff --git a/modules/pam_filter/pam_filter.c b/modules/pam_filter/pam_filter.c index b9274e83..4f75486d 100644 --- a/modules/pam_filter/pam_filter.c +++ b/modules/pam_filter/pam_filter.c @@ -114,33 +114,32 @@ static int process_args(pam_handle_t *pamh return -1; } - for (size=i=0; i<argc; ++i) { - size += strlen(argv[i])+1; - } - /* the "ARGS" variable */ #define ARGS_NAME "ARGS=" #define ARGS_OFFSET (sizeof(ARGS_NAME) - 1) - size += ARGS_OFFSET; + size = sizeof(ARGS_NAME); + + for (i=0; i<argc; ++i) { + size += strlen(argv[i]) + (i != 0); + } - levp[0] = (char *) malloc(size); + levp[0] = malloc(size); if (levp[0] == NULL) { pam_syslog(pamh, LOG_CRIT, "no memory for filter arguments"); - if (levp) { - free(levp); - } + free(levp); return -1; } strcpy(levp[0], ARGS_NAME); - for (i=0,size=ARGS_OFFSET; i<argc; ++i) { + size = ARGS_OFFSET; + for (i=0; i<argc; ++i) { + if (i) + levp[0][size++] = ' '; strcpy(levp[0]+size, argv[i]); size += strlen(argv[i]); - levp[0][size++] = ' '; } - levp[0][--size] = '\0'; /* <NUL> terminate */ /* the "SERVICE" variable */ |