mirror of
https://github.com/torvalds/linux.git
synced 2025-11-30 23:16:01 +07:00
Merge tag 'ceph-for-6.18-rc8' of https://github.com/ceph/ceph-client
Pull ceph fixes from Ilya Dryomov: "A patch to make sparse read handling work in msgr2 secure mode from Slava and a couple of fixes from Ziming and myself to avoid operating on potentially invalid memory, all marked for stable" * tag 'ceph-for-6.18-rc8' of https://github.com/ceph/ceph-client: libceph: prevent potential out-of-bounds writes in handle_auth_session_key() libceph: replace BUG_ON with bounds check for map->max_osd ceph: fix crash in process_v2_sparse_read() for encrypted directories libceph: drop started parameter of __ceph_open_session() libceph: fix potential use-after-free in have_mon_and_osd_map()
This commit is contained in:
@@ -1149,7 +1149,7 @@ static struct dentry *ceph_real_mount(struct ceph_fs_client *fsc,
|
||||
const char *path = fsc->mount_options->server_path ?
|
||||
fsc->mount_options->server_path + 1 : "";
|
||||
|
||||
err = __ceph_open_session(fsc->client, started);
|
||||
err = __ceph_open_session(fsc->client);
|
||||
if (err < 0)
|
||||
goto out;
|
||||
|
||||
|
||||
@@ -306,8 +306,7 @@ struct ceph_entity_addr *ceph_client_addr(struct ceph_client *client);
|
||||
u64 ceph_client_gid(struct ceph_client *client);
|
||||
extern void ceph_destroy_client(struct ceph_client *client);
|
||||
extern void ceph_reset_client_addr(struct ceph_client *client);
|
||||
extern int __ceph_open_session(struct ceph_client *client,
|
||||
unsigned long started);
|
||||
extern int __ceph_open_session(struct ceph_client *client);
|
||||
extern int ceph_open_session(struct ceph_client *client);
|
||||
int ceph_wait_for_latest_osdmap(struct ceph_client *client,
|
||||
unsigned long timeout);
|
||||
|
||||
@@ -631,6 +631,7 @@ static int handle_auth_session_key(struct ceph_auth_client *ac, u64 global_id,
|
||||
|
||||
/* connection secret */
|
||||
ceph_decode_32_safe(p, end, len, e_inval);
|
||||
ceph_decode_need(p, end, len, e_inval);
|
||||
dout("%s connection secret blob len %d\n", __func__, len);
|
||||
if (len > 0) {
|
||||
dp = *p + ceph_x_encrypt_offset();
|
||||
@@ -648,6 +649,7 @@ static int handle_auth_session_key(struct ceph_auth_client *ac, u64 global_id,
|
||||
|
||||
/* service tickets */
|
||||
ceph_decode_32_safe(p, end, len, e_inval);
|
||||
ceph_decode_need(p, end, len, e_inval);
|
||||
dout("%s service tickets blob len %d\n", __func__, len);
|
||||
if (len > 0) {
|
||||
ret = ceph_x_proc_ticket_reply(ac, &th->session_key,
|
||||
|
||||
@@ -785,42 +785,53 @@ void ceph_reset_client_addr(struct ceph_client *client)
|
||||
}
|
||||
EXPORT_SYMBOL(ceph_reset_client_addr);
|
||||
|
||||
/*
|
||||
* true if we have the mon map (and have thus joined the cluster)
|
||||
*/
|
||||
static bool have_mon_and_osd_map(struct ceph_client *client)
|
||||
{
|
||||
return client->monc.monmap && client->monc.monmap->epoch &&
|
||||
client->osdc.osdmap && client->osdc.osdmap->epoch;
|
||||
}
|
||||
|
||||
/*
|
||||
* mount: join the ceph cluster, and open root directory.
|
||||
*/
|
||||
int __ceph_open_session(struct ceph_client *client, unsigned long started)
|
||||
int __ceph_open_session(struct ceph_client *client)
|
||||
{
|
||||
unsigned long timeout = client->options->mount_timeout;
|
||||
long err;
|
||||
DEFINE_WAIT_FUNC(wait, woken_wake_function);
|
||||
long timeout = ceph_timeout_jiffies(client->options->mount_timeout);
|
||||
bool have_monmap, have_osdmap;
|
||||
int err;
|
||||
|
||||
/* open session, and wait for mon and osd maps */
|
||||
err = ceph_monc_open_session(&client->monc);
|
||||
if (err < 0)
|
||||
return err;
|
||||
|
||||
while (!have_mon_and_osd_map(client)) {
|
||||
if (timeout && time_after_eq(jiffies, started + timeout))
|
||||
return -ETIMEDOUT;
|
||||
add_wait_queue(&client->auth_wq, &wait);
|
||||
for (;;) {
|
||||
mutex_lock(&client->monc.mutex);
|
||||
err = client->auth_err;
|
||||
have_monmap = client->monc.monmap && client->monc.monmap->epoch;
|
||||
mutex_unlock(&client->monc.mutex);
|
||||
|
||||
down_read(&client->osdc.lock);
|
||||
have_osdmap = client->osdc.osdmap && client->osdc.osdmap->epoch;
|
||||
up_read(&client->osdc.lock);
|
||||
|
||||
if (err || (have_monmap && have_osdmap))
|
||||
break;
|
||||
|
||||
if (signal_pending(current)) {
|
||||
err = -ERESTARTSYS;
|
||||
break;
|
||||
}
|
||||
|
||||
if (!timeout) {
|
||||
err = -ETIMEDOUT;
|
||||
break;
|
||||
}
|
||||
|
||||
/* wait */
|
||||
dout("mount waiting for mon_map\n");
|
||||
err = wait_event_interruptible_timeout(client->auth_wq,
|
||||
have_mon_and_osd_map(client) || (client->auth_err < 0),
|
||||
ceph_timeout_jiffies(timeout));
|
||||
if (err < 0)
|
||||
return err;
|
||||
if (client->auth_err < 0)
|
||||
return client->auth_err;
|
||||
timeout = wait_woken(&wait, TASK_INTERRUPTIBLE, timeout);
|
||||
}
|
||||
remove_wait_queue(&client->auth_wq, &wait);
|
||||
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
pr_info("client%llu fsid %pU\n", ceph_client_gid(client),
|
||||
&client->fsid);
|
||||
@@ -833,12 +844,11 @@ EXPORT_SYMBOL(__ceph_open_session);
|
||||
int ceph_open_session(struct ceph_client *client)
|
||||
{
|
||||
int ret;
|
||||
unsigned long started = jiffies; /* note the start time */
|
||||
|
||||
dout("open_session start\n");
|
||||
mutex_lock(&client->mount_mutex);
|
||||
|
||||
ret = __ceph_open_session(client, started);
|
||||
ret = __ceph_open_session(client);
|
||||
|
||||
mutex_unlock(&client->mount_mutex);
|
||||
return ret;
|
||||
|
||||
@@ -36,8 +36,9 @@ static int monmap_show(struct seq_file *s, void *p)
|
||||
int i;
|
||||
struct ceph_client *client = s->private;
|
||||
|
||||
mutex_lock(&client->monc.mutex);
|
||||
if (client->monc.monmap == NULL)
|
||||
return 0;
|
||||
goto out_unlock;
|
||||
|
||||
seq_printf(s, "epoch %d\n", client->monc.monmap->epoch);
|
||||
for (i = 0; i < client->monc.monmap->num_mon; i++) {
|
||||
@@ -48,6 +49,9 @@ static int monmap_show(struct seq_file *s, void *p)
|
||||
ENTITY_NAME(inst->name),
|
||||
ceph_pr_addr(&inst->addr));
|
||||
}
|
||||
|
||||
out_unlock:
|
||||
mutex_unlock(&client->monc.mutex);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -56,13 +60,14 @@ static int osdmap_show(struct seq_file *s, void *p)
|
||||
int i;
|
||||
struct ceph_client *client = s->private;
|
||||
struct ceph_osd_client *osdc = &client->osdc;
|
||||
struct ceph_osdmap *map = osdc->osdmap;
|
||||
struct ceph_osdmap *map;
|
||||
struct rb_node *n;
|
||||
|
||||
if (map == NULL)
|
||||
return 0;
|
||||
|
||||
down_read(&osdc->lock);
|
||||
map = osdc->osdmap;
|
||||
if (map == NULL)
|
||||
goto out_unlock;
|
||||
|
||||
seq_printf(s, "epoch %u barrier %u flags 0x%x\n", map->epoch,
|
||||
osdc->epoch_barrier, map->flags);
|
||||
|
||||
@@ -131,6 +136,7 @@ static int osdmap_show(struct seq_file *s, void *p)
|
||||
seq_printf(s, "]\n");
|
||||
}
|
||||
|
||||
out_unlock:
|
||||
up_read(&osdc->lock);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -1061,13 +1061,16 @@ static int decrypt_control_remainder(struct ceph_connection *con)
|
||||
static int process_v2_sparse_read(struct ceph_connection *con,
|
||||
struct page **pages, int spos)
|
||||
{
|
||||
struct ceph_msg_data_cursor *cursor = &con->v2.in_cursor;
|
||||
struct ceph_msg_data_cursor cursor;
|
||||
int ret;
|
||||
|
||||
ceph_msg_data_cursor_init(&cursor, con->in_msg,
|
||||
con->in_msg->sparse_read_total);
|
||||
|
||||
for (;;) {
|
||||
char *buf = NULL;
|
||||
|
||||
ret = con->ops->sparse_read(con, cursor, &buf);
|
||||
ret = con->ops->sparse_read(con, &cursor, &buf);
|
||||
if (ret <= 0)
|
||||
return ret;
|
||||
|
||||
@@ -1085,11 +1088,11 @@ static int process_v2_sparse_read(struct ceph_connection *con,
|
||||
} else {
|
||||
struct bio_vec bv;
|
||||
|
||||
get_bvec_at(cursor, &bv);
|
||||
get_bvec_at(&cursor, &bv);
|
||||
len = min_t(int, len, bv.bv_len);
|
||||
memcpy_page(bv.bv_page, bv.bv_offset,
|
||||
spage, soff, len);
|
||||
ceph_msg_data_advance(cursor, len);
|
||||
ceph_msg_data_advance(&cursor, len);
|
||||
}
|
||||
spos += len;
|
||||
ret -= len;
|
||||
|
||||
@@ -1504,8 +1504,6 @@ static int decode_new_primary_temp(void **p, void *end,
|
||||
|
||||
u32 ceph_get_primary_affinity(struct ceph_osdmap *map, int osd)
|
||||
{
|
||||
BUG_ON(osd >= map->max_osd);
|
||||
|
||||
if (!map->osd_primary_affinity)
|
||||
return CEPH_OSD_DEFAULT_PRIMARY_AFFINITY;
|
||||
|
||||
@@ -1514,8 +1512,6 @@ u32 ceph_get_primary_affinity(struct ceph_osdmap *map, int osd)
|
||||
|
||||
static int set_primary_affinity(struct ceph_osdmap *map, int osd, u32 aff)
|
||||
{
|
||||
BUG_ON(osd >= map->max_osd);
|
||||
|
||||
if (!map->osd_primary_affinity) {
|
||||
int i;
|
||||
|
||||
@@ -1577,6 +1573,8 @@ static int decode_new_primary_affinity(void **p, void *end,
|
||||
|
||||
ceph_decode_32_safe(p, end, osd, e_inval);
|
||||
ceph_decode_32_safe(p, end, aff, e_inval);
|
||||
if (osd >= map->max_osd)
|
||||
goto e_inval;
|
||||
|
||||
ret = set_primary_affinity(map, osd, aff);
|
||||
if (ret)
|
||||
@@ -1879,7 +1877,9 @@ static int decode_new_up_state_weight(void **p, void *end, u8 struct_v,
|
||||
ceph_decode_need(p, end, 2*sizeof(u32), e_inval);
|
||||
osd = ceph_decode_32(p);
|
||||
w = ceph_decode_32(p);
|
||||
BUG_ON(osd >= map->max_osd);
|
||||
if (osd >= map->max_osd)
|
||||
goto e_inval;
|
||||
|
||||
osdmap_info(map, "osd%d weight 0x%x %s\n", osd, w,
|
||||
w == CEPH_OSD_IN ? "(in)" :
|
||||
(w == CEPH_OSD_OUT ? "(out)" : ""));
|
||||
@@ -1905,13 +1905,15 @@ static int decode_new_up_state_weight(void **p, void *end, u8 struct_v,
|
||||
u32 xorstate;
|
||||
|
||||
osd = ceph_decode_32(p);
|
||||
if (osd >= map->max_osd)
|
||||
goto e_inval;
|
||||
|
||||
if (struct_v >= 5)
|
||||
xorstate = ceph_decode_32(p);
|
||||
else
|
||||
xorstate = ceph_decode_8(p);
|
||||
if (xorstate == 0)
|
||||
xorstate = CEPH_OSD_UP;
|
||||
BUG_ON(osd >= map->max_osd);
|
||||
if ((map->osd_state[osd] & CEPH_OSD_UP) &&
|
||||
(xorstate & CEPH_OSD_UP))
|
||||
osdmap_info(map, "osd%d down\n", osd);
|
||||
@@ -1937,7 +1939,9 @@ static int decode_new_up_state_weight(void **p, void *end, u8 struct_v,
|
||||
struct ceph_entity_addr addr;
|
||||
|
||||
osd = ceph_decode_32(p);
|
||||
BUG_ON(osd >= map->max_osd);
|
||||
if (osd >= map->max_osd)
|
||||
goto e_inval;
|
||||
|
||||
if (struct_v >= 7)
|
||||
ret = ceph_decode_entity_addrvec(p, end, msgr2, &addr);
|
||||
else
|
||||
|
||||
Reference in New Issue
Block a user