Skip to content

Commit 23ec785

Browse files
committed
Handle Link_download errors in cache
If Link_download fails and returns a negative value, the background download thread (Cache_bgdl) and the segment reader (Cache_read_segment) should immediately clean up their allocated resources (specifically freeing recv_buf), unlock cf->w_lock, and exit/return appropriately. This prevents the download path from proceeding with a negative length value, avoiding potential crashes or undefined behaviors when writing to the file or using memcpy. Additionally, propagate segment download errors from Cache_read to its callers, and log w_lock unlocking in Cache_bgdl and Cache_read_segment error paths for consistent lock tracing.
1 parent 61ef581 commit 23ec785

1 file changed

Lines changed: 17 additions & 2 deletions

File tree

src/cache.c

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -988,6 +988,12 @@ static void *Cache_bgdl(void *arg)
988988
"thread %lx received %ld bytes, "
989989
"which doesn't make sense\n",
990990
(unsigned long)pthread_self(), recv);
991+
FREE(recv_buf);
992+
lprintf(cache_lock_debug, "thread %lx: unlocking w_lock;\n",
993+
(unsigned long)pthread_self());
994+
PTHREAD_MUTEX_UNLOCK(&cf->w_lock);
995+
SEM_POST(&cf->bgt_sem);
996+
pthread_exit(NULL);
991997
}
992998

993999
if ((recv == cf->blksz)
@@ -1089,6 +1095,11 @@ static long Cache_read_segment(Cache *cf, char *const output_buf,
10891095
"thread %lx received %ld bytes, "
10901096
"which doesn't make sense\n",
10911097
(unsigned long)pthread_self(), recv);
1098+
FREE(recv_buf);
1099+
lprintf(cache_lock_debug, "thread %lx: unlocking w_lock;\n",
1100+
(unsigned long)pthread_self());
1101+
PTHREAD_MUTEX_UNLOCK(&cf->w_lock);
1102+
return recv;
10921103
}
10931104
/*
10941105
* check if we have received enough data, write it to the disk
@@ -1157,8 +1168,12 @@ long Cache_read(Cache *cf, char *const output_buf, off_t len,
11571168
if (end > start + len) {
11581169
end = start + len;
11591170
}
1160-
send += Cache_read_segment(cf, output_buf + (start - offset_start),
1161-
end - start, start);
1171+
long seg_send = Cache_read_segment(
1172+
cf, output_buf + (start - offset_start), end - start, start);
1173+
if (seg_send < 0) {
1174+
return seg_send;
1175+
}
1176+
send += seg_send;
11621177
}
11631178
return send;
11641179
}

0 commit comments

Comments
 (0)