Closed Bug 1894572 Opened 1 year ago Closed 1 year ago

Use after free in sftk_getParameters()

Categories

(NSS :: Libraries, defect, P5)

Tracking

(firefox128 fixed)

RESOLVED FIXED
Tracking Status
firefox128 --- fixed

People

(Reporter: mozillabugs, Assigned: fkrenzel)

Details

(Keywords: reporter-external, sec-other, Whiteboard: [some sec risk for apps that user sftkn separately][post-critsmash-triage][adv-main128-])

Attachments

(1 file)

sftk_getParameters() (nss/lib/softoken/pkcs11.c) uses the freed variable libParams if the call to PR_Read() fails.

Using the following code from FIREFOX_124_0_2_RELEASE, imagine that control reaches line 3384, then PR_Read() returns an error. That causes line 3385 to execute, freeing libParams [1]. Control then falls through to line 3392, then line 3397 (whose condition is false), then line 3405, which uses the freed variable:

3352: static CK_RV
3353: sftk_getParameters(CK_C_INITIALIZE_ARGS *init_args, PRBool isFIPS,
3354:                    sftk_parameters *paramStrings)
3355: {
...
3360:     PRBool free_mem = PR_FALSE;
3361: 
3362:     if (!init_args || !init_args->LibraryParameters) {
3363:         /* Library parameters were not provided via C_Initialize_args*/
3364: 
3365:         /* Enviromental value has precedence to configuration filename */
3366:         libParams = PR_GetEnvSecure("NSS_LIB_PARAMS");
3367: 
3368:         if (!libParams) {
3369:             /* Load from config filename or use default */
3370:             filename = PR_GetEnvSecure("NSS_LIB_PARAMS_FILE");
...
3376:             if (filename) {
3377:                 file_dc = PR_OpenFile(filename, PR_RDONLY, 444);
3378:                 if (file_dc) {
3379:                     /* file opened */
3380:                     PRInt32 len = PR_Available(file_dc);
3381:                     libParams = PORT_NewArray(char, len + 1);
3382:                     if (libParams) {
3383:                         /* memory allocated */
3384:                         if (PR_Read(file_dc, libParams, len) == -1) {
3385:                             PR_Free(libParams);
3386:                         } else {
3387:                             free_mem = PR_TRUE;
3388:                             libParams[len] = '\0';
3389:                         }
3390:                     }
3391: 
3392:                     PR_Close(file_dc);
3393:                 }
3394:             }
3395:         }
3396: 
3397:         if (!libParams)
3398:             libParams = LIB_PARAM_DEFAULT;
3399: 
3400:     } else {
...
3403:     }
3404: 
3405:     crv = sftk_parseParameters(libParams, paramStrings, isFIPS);
...
3414:         PR_Free(libParams);
...
3417: }

[1] Also, line 3385 should be using PORT_Free(), not PR_Free(), as should line 3414.

Flags: sec-bounty?

John, is this possibly related to the softoken crash you were looking at?

Flags: needinfo?(jschanck)

No, Firefox initializes softoken with a non-null value in init_args->LibraryParameters. To hit this bug you have to omit library parameters and you have to set the NSS_LIB_PARAMS_FILE environment variable.

This function was added in Bug 1837987 so that softoken could be loaded by other applications. I'm not sure if RedHat is using this, or if it was just added for testing. fkrenzel, can you take a look?

Flags: needinfo?(jschanck) → needinfo?(fkrenzel)
Severity: -- → S4
Priority: -- → P5

Hey, thanks for catching the PORT_Free(),

As to the libParams on the line 3398. This shouldn't be a problem as libParams is a pointer (char* if I recall correctly) and the operation just assigns the static address of LIB_PARAM_DEFAULT to it.

This is what happens:
libParams → PR_GetEnvSecure("NSS_LIB_PARAMS"); //Points to the Environmental variable
libParams → Array[len + 1] //Point to newly allocated memory
libParams → NULL // freed the array
libParams → LIB_PARAM_DEFAULT // Point tho the statically allocated memory

Flags: needinfo?(fkrenzel)

(In reply to fkrenzel from comment #3)

Hey, thanks for catching the PORT_Free(),

As to the libParams on the line 3398. This shouldn't be a problem as libParams is a pointer (char* if I recall correctly) and the operation just assigns the static address of LIB_PARAM_DEFAULT to it.

This is what happens:
libParams → PR_GetEnvSecure("NSS_LIB_PARAMS"); //Points to the Environmental variable
libParams → Array[len + 1] //Point to newly allocated memory
libParams → NULL // freed the array
libParams → LIB_PARAM_DEFAULT // Point tho the statically allocated memory

I don't see where libParams gets assigned NULL. Line 3385 just frees the memory, so the condition on line 3397 is false and line 3398 never gets executed. Then line 3405 uses the freed memory. PR_Free() does not null its argument, and in fact cannot, because the argument isa void * and not a void ** or void *&. https://searchfox.org/mozilla-central/source/nsprpub/pr/src/malloc/prmem.c#470 .

(In reply to mozillabugs from comment #4)

(In reply to fkrenzel from comment #3)

Hey, thanks for catching the PORT_Free(),

As to the libParams on the line 3398. This shouldn't be a problem as libParams is a pointer (char* if I recall correctly) and the operation just assigns the static address of LIB_PARAM_DEFAULT to it.

This is what happens:
libParams → PR_GetEnvSecure("NSS_LIB_PARAMS"); //Points to the Environmental variable
libParams → Array[len + 1] //Point to newly allocated memory
libParams → NULL // freed the array
libParams → LIB_PARAM_DEFAULT // Point tho the statically allocated memory

I don't see where libParams gets assigned NULL. Line 3385 just frees the memory, so the condition on line 3397 is false and line 3398 never gets executed. Then line 3405 uses the freed memory. PR_Free() does not null its argument, and in fact cannot, because the argument isa void * and not a void ** or void *&. https://searchfox.org/mozilla-central/source/nsprpub/pr/src/malloc/prmem.c#470 .

I see, you are correct, will propose a patch for this.

Patch proposed, thanks! For reporting and for your follow-up explanation of the problem.

(In reply to fkrenzel from comment #7)

Patch proposed, thanks! For reporting and for your follow-up explanation of the problem.

Thanks for fixing the bugs.

Keywords: sec-other
Whiteboard: [some sec risk for apps that user sftkn separately]
Status: NEW → RESOLVED
Closed: 1 year ago
Resolution: --- → FIXED
Assignee: nobody → fkrenzel
Group: crypto-core-security → core-security-release
Flags: sec-bounty? → sec-bounty-
Flags: qe-verify-
Whiteboard: [some sec risk for apps that user sftkn separately] → [some sec risk for apps that user sftkn separately][post-critsmash-triage]
Whiteboard: [some sec risk for apps that user sftkn separately][post-critsmash-triage] → [some sec risk for apps that user sftkn separately][post-critsmash-triage][adv-main128-]
Group: core-security-release
You need to log in before you can comment on or make changes to this bug.

Attachment

General

Creator:
Created:
Updated:
Size: