autofs-5.1.7 - add buffer length checks to autofs mount_mount() From: Ian Kent --- CHANGELOG | 1 modules/mount_autofs.c | 59 +++++++++++++++++++++++++++++++++---------------- 2 files changed, 41 insertions(+), 19 deletions(-) --- autofs-5.1.4.orig/CHANGELOG +++ autofs-5.1.4/CHANGELOG @@ -131,6 +131,7 @@ - fix amd selector function matching. - get rid entry thid field. - continue expire immediately after submount check. +- add buffer length checks to autofs mount_mount(). xx/xx/2018 autofs-5.1.5 - fix flag file permission. --- autofs-5.1.4.orig/modules/mount_autofs.c +++ autofs-5.1.4/modules/mount_autofs.c @@ -50,8 +50,8 @@ int mount_mount(struct autofs_point *ap, { struct startup_cond suc; pthread_t thid; - char realpath[PATH_MAX]; - char mountpoint[PATH_MAX]; + char realpath[PATH_MAX + 1]; + char mountpoint[PATH_MAX + 1]; const char **argv; int argc, status; int nobind = ap->flags & MOUNT_FLAG_NOBIND; @@ -68,32 +68,53 @@ int mount_mount(struct autofs_point *ap, struct mnt_list *mnt; char buf[MAX_ERR_BUF]; char *options, *p; - int len, ret; + int err, ret; int hosts = 0; /* Root offset of multi-mount */ - len = strlen(root); - if (root[len - 1] == '/') { - strcpy(realpath, ap->path); - strcat(realpath, "/"); - strcat(realpath, name); - len--; - strncpy(mountpoint, root, len); - mountpoint[len] = '\0'; + if (root[strlen(root) - 1] == '/') { + err = snprintf(realpath, PATH_MAX + 1, "%s/%s", ap->path, name); + if (err > PATH_MAX) { + error(ap->logopt, MODPREFIX "string too long for realpath"); + return 1; + } + err = snprintf(mountpoint, PATH_MAX + 1, "%s", root); + if (err > PATH_MAX) { + error(ap->logopt, MODPREFIX "string too long for mountpoint"); + return 1; + } + mountpoint[err - 1] = 0; } else if (*name == '/') { if (ap->flags & MOUNT_FLAG_REMOUNT) { - strcpy(mountpoint, name); - strcpy(realpath, name); + err = snprintf(mountpoint, PATH_MAX + 1, "%s", name); + if (err > PATH_MAX) { + error(ap->logopt, MODPREFIX "string too long for mountpoint"); + return 1; + } + err = snprintf(realpath, PATH_MAX + 1, "%s", name); + if (err > PATH_MAX) { + error(ap->logopt, MODPREFIX "string too long for realpath"); + return 1; + } } else { - strcpy(mountpoint, root); - strcpy(realpath, name); + err = snprintf(mountpoint, PATH_MAX + 1, "%s", root); + if (err > PATH_MAX) { + error(ap->logopt, MODPREFIX "string too long for mountpoint"); + return 1; + } + err = snprintf(realpath, PATH_MAX + 1, "%s", name); + if (err > PATH_MAX) { + error(ap->logopt, MODPREFIX "string too long for realpath"); + return 1; + } } } else { - strcpy(mountpoint, root); - strcat(mountpoint, "/"); + err = snprintf(mountpoint, PATH_MAX + 1, "%s/%s", root, name); + if (err > PATH_MAX) { + error(ap->logopt, MODPREFIX "string too long for mountpoint"); + return 1; + } strcpy(realpath, mountpoint); - strcat(mountpoint, name); - strcat(realpath, name); } options = NULL;