Skip to content

Commit 4caf077

Browse files
committed
initrd-put: Use strlcpy instead of less secure alternatives
Signed-off-by: Alexey Gladkov <gladkov.alexey@gmail.com>
1 parent af16934 commit 4caf077

2 files changed

Lines changed: 28 additions & 9 deletions

File tree

utils/initrd-put/initrd-put.c

Lines changed: 17 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -118,11 +118,11 @@ int mksock(const char *path)
118118
int ret = -1;
119119

120120
errno = EINVAL;
121-
if (strlen(path) < sizeof(sun)) {
121+
if (strlen(path) < sizeof(sun.sun_path)) {
122122
int fd = -1;
123123

124124
sun.sun_family = AF_UNIX;
125-
strcpy(sun.sun_path, path);
125+
strlcpy(sun.sun_path, path, sizeof(sun.sun_path));
126126

127127
if ((fd = socket(PF_UNIX, SOCK_STREAM, 0)) >= 0 &&
128128
!bind(fd, (struct sockaddr *) &sun, sizeof(sun))) {
@@ -498,7 +498,10 @@ void install_file(struct file *p)
498498
break;
499499
}
500500

501-
strncpy(install_path + destdir_len, p->dst, sizeof(install_path) - destdir_len - 1);
501+
size_t avail = sizeof(install_path) - destdir_len;
502+
503+
if (strlcpy(install_path + destdir_len, p->dst, avail) >= avail)
504+
errx(EXIT_FAILURE, "destination path too long: %s", p->dst);
502505

503506
errno = 0;
504507
if (force && (S_IFDIR != (p->stat.st_mode & S_IFMT)) &&
@@ -691,7 +694,10 @@ void install_file(struct file *p)
691694

692695
void apply_permissions(struct file *p)
693696
{
694-
strncpy(install_path + destdir_len, p->dst, sizeof(install_path) - destdir_len - 1);
697+
size_t avail = sizeof(install_path) - destdir_len;
698+
699+
if (strlcpy(install_path + destdir_len, p->dst, avail) >= avail)
700+
errx(EXIT_FAILURE, "destination path too long: %s", p->dst);
695701

696702
errno = 0;
697703
if (lchown(install_path, p->stat.st_uid, p->stat.st_gid) < 0) {
@@ -833,8 +839,10 @@ int main(int argc, char **argv)
833839
enqueue_canonicalized_path(argv[i], true);
834840
}
835841

836-
strncpy(install_path, destdir, sizeof(install_path) - 1);
837-
install_path[destdir_len] = 0;
842+
size_t avail = sizeof(install_path);
843+
844+
if (strlcpy(install_path, destdir, avail) >= avail)
845+
errx(EXIT_FAILURE, "destination path too long: %s", destdir);
838846

839847
for (struct file *queue = get_queue(NULL); queue; queue = get_queue(NULL)) {
840848
while (queue != NULL) {
@@ -853,8 +861,10 @@ int main(int argc, char **argv)
853861

854862
if (!force) {
855863
struct stat st;
864+
avail = sizeof(install_path) - destdir_len;
856865

857-
strncpy(install_path + destdir_len, queue->dst, sizeof(install_path) - destdir_len - 1);
866+
if (strlcpy(install_path + destdir_len, queue->dst, avail) >= avail)
867+
errx(EXIT_FAILURE, "destination path too long: %s", queue->dst);
858868

859869
errno = 0;
860870
if (lstat(install_path, &st) < 0) {

utils/initrd-put/queue.c

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -37,8 +37,17 @@ struct file *enqueue_item(const char *str, ssize_t len)
3737
if (exclude_match_nr) {
3838
char buf[PATH_MAX + 1];
3939

40-
strncpy(buf, str, (len <= 0 ? PATH_MAX : (size_t) len));
41-
buf[(len <= 0 ? PATH_MAX : len) + 1] = 0;
40+
if (len > 0) {
41+
size_t n = (size_t) len;
42+
43+
if (n > PATH_MAX)
44+
n = PATH_MAX;
45+
46+
memcpy(buf, str, n);
47+
buf[n] = '\0';
48+
} else {
49+
strlcpy(buf, str, sizeof(buf));
50+
}
4251

4352
for (size_t i = 0; i < exclude_match_nr; i++) {
4453
if (!regexec(&exclude_match[i], buf, 0, NULL, 0)) {

0 commit comments

Comments
 (0)