mirror of
https://github.com/norandom/OpenUltraSAST.git
synced 2026-10-20 21:49:28 +00:00
feat(real-world-vfc-slice): add labeled OpenSSL/Firefox/Chromium/curl pair corpus
Harvest 176 isolated vuln-vs-fix functions (109 CVEs, 352 training rows) into benchmarks/pairs/vfc with provenance and a JSONL training manifest. Score the slice as an honesty dashboard (ousast pairs --slice vfc); keep the pair gate on the local fixtures only.
This commit is contained in:
@@ -0,0 +1,207 @@
|
||||
/* Provenance: openssl/openssl ASN1_mbstring_ncopy (fixed).
|
||||
* repo: openssl/openssl
|
||||
* commit: 97f6b621f7af2c4c4e162c75045a6e12a8fdf8d9
|
||||
* parent: cb005ceaaf1fb50722e0101762a3e266338c5bf9
|
||||
* commit_url: https://github.com/openssl/openssl/commit/97f6b621f7af2c4c4e162c75045a6e12a8fdf8d9
|
||||
* cve: CVE-2026-7383
|
||||
* license: Apache-2.0
|
||||
* function: ASN1_mbstring_ncopy
|
||||
* relpath: crypto/asn1/a_mbstr.c
|
||||
*/
|
||||
|
||||
int ASN1_mbstring_ncopy(ASN1_STRING **out, const unsigned char *in, int len,
|
||||
int inform, unsigned long mask_in,
|
||||
long minsize, long maxsize)
|
||||
{
|
||||
int str_type;
|
||||
int ret;
|
||||
char free_out;
|
||||
int outform, outlen = 0;
|
||||
ASN1_STRING *dest;
|
||||
unsigned char *p;
|
||||
int nchar;
|
||||
uint32_t mask = (uint32_t)mask_in;
|
||||
int (*cpyfunc)(uint32_t, void *) = NULL;
|
||||
if (len == -1) {
|
||||
size_t len_s = strlen((const char *)in);
|
||||
|
||||
if (len_s >= INT_MAX) {
|
||||
ERR_raise(ERR_LIB_ASN1, ASN1_R_STRING_TOO_LONG);
|
||||
return -1;
|
||||
}
|
||||
len = (int)len_s;
|
||||
}
|
||||
if (!mask)
|
||||
mask = DIRSTRING_TYPE;
|
||||
if (len < 0) {
|
||||
ERR_raise(ERR_LIB_ASN1, ERR_R_PASSED_INVALID_ARGUMENT);
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* First do a string check and work out the number of characters */
|
||||
switch (inform) {
|
||||
|
||||
case MBSTRING_BMP:
|
||||
if (len & 1) {
|
||||
ERR_raise(ERR_LIB_ASN1, ASN1_R_INVALID_BMPSTRING_LENGTH);
|
||||
return -1;
|
||||
}
|
||||
nchar = len >> 1;
|
||||
break;
|
||||
|
||||
case MBSTRING_UNIV:
|
||||
if (len & 3) {
|
||||
ERR_raise(ERR_LIB_ASN1, ASN1_R_INVALID_UNIVERSALSTRING_LENGTH);
|
||||
return -1;
|
||||
}
|
||||
nchar = len >> 2;
|
||||
break;
|
||||
|
||||
case MBSTRING_UTF8:
|
||||
nchar = 0;
|
||||
/* This counts the characters and does utf8 syntax checking */
|
||||
ret = traverse_string(in, len, MBSTRING_UTF8, in_utf8, &nchar);
|
||||
if (ret < 0) {
|
||||
ERR_raise(ERR_LIB_ASN1, ASN1_R_INVALID_UTF8STRING);
|
||||
return -1;
|
||||
}
|
||||
break;
|
||||
|
||||
case MBSTRING_ASC:
|
||||
nchar = len;
|
||||
break;
|
||||
|
||||
default:
|
||||
ERR_raise(ERR_LIB_ASN1, ASN1_R_UNKNOWN_FORMAT);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if ((minsize > 0) && (nchar < minsize)) {
|
||||
ERR_raise_data(ERR_LIB_ASN1, ASN1_R_STRING_TOO_SHORT,
|
||||
"minsize=%ld", minsize);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if ((maxsize > 0) && (nchar > maxsize)) {
|
||||
ERR_raise_data(ERR_LIB_ASN1, ASN1_R_STRING_TOO_LONG,
|
||||
"maxsize=%ld", maxsize);
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Now work out minimal type (if any) */
|
||||
if (traverse_string(in, len, inform, type_str, &mask) < 0) {
|
||||
ERR_raise(ERR_LIB_ASN1, ASN1_R_ILLEGAL_CHARACTERS);
|
||||
return -1;
|
||||
}
|
||||
|
||||
/*
|
||||
* Now work out output format and string type.
|
||||
* These checks should be in sync with the checks in type_str.
|
||||
*/
|
||||
outform = MBSTRING_ASC;
|
||||
if (mask & B_ASN1_NUMERICSTRING)
|
||||
str_type = V_ASN1_NUMERICSTRING;
|
||||
else if (mask & B_ASN1_PRINTABLESTRING)
|
||||
str_type = V_ASN1_PRINTABLESTRING;
|
||||
else if (mask & B_ASN1_IA5STRING)
|
||||
str_type = V_ASN1_IA5STRING;
|
||||
else if (mask & B_ASN1_T61STRING)
|
||||
str_type = V_ASN1_T61STRING;
|
||||
else if (mask & B_ASN1_BMPSTRING) {
|
||||
str_type = V_ASN1_BMPSTRING;
|
||||
outform = MBSTRING_BMP;
|
||||
} else if (mask & B_ASN1_UNIVERSALSTRING) {
|
||||
str_type = V_ASN1_UNIVERSALSTRING;
|
||||
outform = MBSTRING_UNIV;
|
||||
} else {
|
||||
str_type = V_ASN1_UTF8STRING;
|
||||
outform = MBSTRING_UTF8;
|
||||
}
|
||||
if (!out)
|
||||
return str_type;
|
||||
if (*out) {
|
||||
free_out = 0;
|
||||
dest = *out;
|
||||
ASN1_STRING_set0(dest, NULL, 0);
|
||||
dest->type = str_type;
|
||||
} else {
|
||||
free_out = 1;
|
||||
dest = ASN1_STRING_type_new(str_type);
|
||||
if (dest == NULL) {
|
||||
ERR_raise(ERR_LIB_ASN1, ERR_R_ASN1_LIB);
|
||||
return -1;
|
||||
}
|
||||
*out = dest;
|
||||
}
|
||||
/* If both the same type just copy across */
|
||||
if (inform == outform) {
|
||||
if (!ASN1_STRING_set(dest, in, len)) {
|
||||
if (free_out) {
|
||||
ASN1_STRING_free(dest);
|
||||
*out = NULL;
|
||||
}
|
||||
ERR_raise(ERR_LIB_ASN1, ERR_R_ASN1_LIB);
|
||||
return -1;
|
||||
}
|
||||
return str_type;
|
||||
}
|
||||
|
||||
/* Work out how much space the destination will need */
|
||||
switch (outform) {
|
||||
case MBSTRING_ASC:
|
||||
outlen = nchar;
|
||||
cpyfunc = cpy_asc;
|
||||
break;
|
||||
|
||||
case MBSTRING_BMP:
|
||||
if (nchar > INT_MAX / 2) {
|
||||
ERR_raise(ERR_LIB_ASN1, ASN1_R_STRING_TOO_LONG);
|
||||
if (free_out) {
|
||||
ASN1_STRING_free(dest);
|
||||
*out = NULL;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
outlen = nchar << 1;
|
||||
cpyfunc = cpy_bmp;
|
||||
break;
|
||||
|
||||
case MBSTRING_UNIV:
|
||||
if (nchar > INT_MAX / 4) {
|
||||
ERR_raise(ERR_LIB_ASN1, ASN1_R_STRING_TOO_LONG);
|
||||
if (free_out) {
|
||||
ASN1_STRING_free(dest);
|
||||
*out = NULL;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
outlen = nchar << 2;
|
||||
cpyfunc = cpy_univ;
|
||||
break;
|
||||
|
||||
case MBSTRING_UTF8:
|
||||
outlen = 0;
|
||||
ret = traverse_string(in, len, inform, out_utf8, &outlen);
|
||||
if (ret < 0) { /* error already raised in out_utf8() */
|
||||
if (free_out) {
|
||||
ASN1_STRING_free(dest);
|
||||
*out = NULL;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
cpyfunc = cpy_utf8;
|
||||
break;
|
||||
}
|
||||
if ((p = OPENSSL_malloc(outlen + 1)) == NULL) {
|
||||
if (free_out) {
|
||||
ASN1_STRING_free(dest);
|
||||
*out = NULL;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
dest->length = outlen;
|
||||
dest->data = p;
|
||||
p[outlen] = 0;
|
||||
traverse_string(in, len, inform, cpyfunc, &p);
|
||||
return str_type;
|
||||
}
|
||||
Reference in New Issue
Block a user