Fix the issue that VTOY_LINUX_REMOUNT=1 does not work on some distros (e.g. Pop OS/openSUSE/Ubuntu 23.04) (#2475 #2551)

This commit is contained in:
longpanda
2023-10-06 21:12:34 +08:00
parent d617985093
commit 7f63a1c327
12 changed files with 152 additions and 25 deletions

View File

@@ -164,6 +164,13 @@ struct modversion_info {
char name[64 - sizeof(unsigned long)];
};
struct modversion_info2 {
/* Offset of the next modversion entry in relation to this one. */
uint32_t next;
uint32_t crc;
char name[0];
};
typedef struct ko_param
{
@@ -294,14 +301,15 @@ static int vtoykmod_find_section32(char *buf, char *section, int *offset, int *l
return 1;
}
static int vtoykmod_update_modcrc(char *oldmodver, int oldcnt, char *newmodver, int newcnt)
static int vtoykmod_update_modcrc1(char *oldmodver, int oldcnt, char *newmodver, int newcnt)
{
int i, j;
struct modversion_info *pold, *pnew;
pold = (struct modversion_info *)oldmodver;
pnew = (struct modversion_info *)newmodver;
debug("module update modver format 1\n");
for (i = 0; i < oldcnt; i++)
{
for (j = 0; j < newcnt; j++)
@@ -318,6 +326,51 @@ static int vtoykmod_update_modcrc(char *oldmodver, int oldcnt, char *newmodver,
return 0;
}
static int vtoykmod_update_modcrc2(char *oldmodver, int oldlen, char *newmodver, int newlen)
{
struct modversion_info2 *pold, *pnew, *pnewend;
pold = (struct modversion_info2 *)oldmodver;
pnew = (struct modversion_info2 *)newmodver;
pnewend = (struct modversion_info2 *)(newmodver + newlen);
debug("module update modver format 2\n");
/* here we think that there is only module_layout in oldmodver */
for (; pnew < pnewend && pnew->next; pnew = (struct modversion_info2 *)((char *)pnew + pnew->next))
{
if (strcmp(pnew->name, "module_layout") == 0)
{
debug("CRC 0x%08x --> 0x%08x %s\n", pold->crc, pnew->crc, pnew->name);
memset(pold, 0, oldlen);
pold->next = 0x18; /* 8 + module_layout align 8 */
pold->crc = pnew->crc;
strcpy(pold->name, pnew->name);
break;
}
}
return 0;
}
static int vtoykmod_update_modcrc(char *oldmodver, int oldlen, char *newmodver, int newlen)
{
uint32_t uiCrc = 0;
memcpy(&uiCrc, newmodver + 4, 4);
if (uiCrc > 0)
{
return vtoykmod_update_modcrc2(oldmodver, oldlen, newmodver, newlen);
}
else
{
return vtoykmod_update_modcrc1(oldmodver, oldlen / 64, newmodver, newlen / 64);
}
}
static int vtoykmod_update_vermagic(char *oldbuf, int oldsize, char *newbuf, int newsize, int *modver)
{
int i = 0;
@@ -393,7 +446,7 @@ int vtoykmod_update(char *oldko, char *newko)
if (rc == 0)
{
vtoykmod_update_modcrc(oldbuf + oldoff, oldlen / 64, newbuf + newoff, newlen / 64);
vtoykmod_update_modcrc(oldbuf + oldoff, oldlen, newbuf + newoff, newlen);
}
}
else