The following code compiles successfully and returns the correct results when called the first time. Making the same call a second time, I get a segmentation fault error.
//% function TF = InWindow(Date,WindowStartDates,WindowEndDates,EndHint)
//% INWINDOW returns true for window that contains Date. All inputs must be
//% uint32 and WindowEndDates must be sorted.
//% EndHint is an optional input that specifies the row number to start
//% searching from.
#include "mex.h"
#include "matrix.h"
#include "math.h"
void CalculationRoutine(mxLogical *ismember, uint32_T *Date, uint32_T *WindowStartDates, uint32_T *WindowEndDates, unsigned int *StartIndex, int NumObs) {
mwIndex Counter;
// Find the first window that ends on or after the date.
for (Counter = (mwIndex) *StartIndex; Counter < NumObs; Counter++) {
if (*Date <= *(WindowEndDates+Counter)) {
break;
}
}
*StartIndex = (unsigned int) Counter;
// Now flag every observation within the window. Remember that WindowStartDates
// is not necessarily sorted (but WindowEndDates is).
for (Counter = (mwIndex) *StartIndex; Counter < NumObs; Counter++) {
if (*Date >= *(WindowStartDates+Counter)) {
*(ismember+Counter) = true;
}
}
}
void mexFunction( int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[] ) {
mxArray *ismember;
unsigned int *StartIndex;
//Input Checking.
if (nrhs == 3) {
// Default Hint to first entry.
mexPrintf("SI Starts OK.\n");
*StartIndex = 1;
mexPrintf("SI Ends OK.\n");
} else if (nrhs == 4) {
if (!mxIsUint32(prhs[3])) {
mexErrMsgTxt("EndHint must be uint32.");
}
StartIndex = mxGetData(prhs[3]);
} else {
mexErrMsgTxt("Must provide three or four input arguments.");
}
// Convert the hint to base-zero indexing.
*StartIndex = *StartIndex - 1;
// Check the inputs for the window range.
if (!mxIsUint32(prhs[0])) {
mexErrMsgTxt("DatesList must be uint32.");
}
if (!mxIsUint32(prhs[1])) {
mexErrMsgTxt("WindowStartsDates must be uint32.");
}
if (!mxIsUint32(prhs[2])) {
mexErrMsgTxt("WindowEndsDates must be uint32.");
}
if (mxGetM(prhs[1]) != mxGetM(prhs[2])) {
mexErrMsgTxt("WindowStartDates must be the same length as WindowEndDates.");
}
// Prepare the output array.
ismember = mxCreateLogicalArray(mxGetNumberOfDimensions(prhs[1]), mxGetDimensions(prhs[1]));
CalculationRoutine(mxGetLogicals(ismember),mxGetData(prhs[0]),
mxGetData(prhs[1]), mxGetData(prhs[2]), StartIndex, (int) mxGetM(prhs[1]));
plhs[0] = ismember;
}
I call it with:
>>InWindow(uint32(5),uint32((1:6)'),uint32((3:8)'))
The code reaches the line between the two mexPrintf calls before the segmentation fault (ie the first call prints, but not the second).
I am on Matlab 2007a (yes, I know), Win7 64bit and VS 2008.
You need to initialize the pointer StartIndex - you're "lucky" that it works the first time, since it is not pointing to a defined memory location. Why not do something more like:
unsigned int StartIndex;
// and either:
StartIndex = 1;
// or:
StartIndex = * (static_cast< unsigned int * >( mxGetData(prhs[3]) ) );
Related
Program execute result:
zsh: segmentation fault ./test.out
Coverity analyse output:
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
// uaf
void test_1(void *p) {
free(p);
CID 358676: Read from pointer after free (USE_AFTER_FREE) [select issue]
printf("%x\n", *((int *)p));
}
// loop write
void test_2(int total, char *p) {
char a[100];
for(int i=0;i < total; i++) {
a[i] = *(p + i);
}
}
typedef struct {
char name[100];
}Person;
// uint8 *p
void test_3(Person *p) {
unsigned char *ptr = (unsigned char *)p;
for(int i=0; i < sizeof(Person) + 100; i++) {
*ptr = 'a';
}
free(p);
CID 358686: Read from pointer after free (USE_AFTER_FREE) [select issue]
printf("%x\n", *((int *)p));
}
// state machine
enum {
S_START,
S_IDLE,
S_BUSY,
S_UNKNOWN
};
int gState = S_START;
void *gPtr = NULL;
void handle_start() {
int size;
printf("input malloc size:\n");
CID 358721: Unchecked return value from library (CHECKED_RETURN) [select issue]
scanf("%d", &size);
CID 134591: Untrusted allocation size (TAINTED_SCALAR) [select issue]
gPtr = malloc(size);
gState = S_BUSY;
printf("S_START -> S_BUSY\n");
}
void handle_busy() {
char buff[100];
printf("input string:\n");
CID 358720: Unchecked return value from library (CHECKED_RETURN) [select issue]
CID 358719: Calling risky function (DC.STREAM_BUFFER) [select issue]
scanf("%s", buff);
strcpy(gPtr, buff);
puts(gPtr);
gState = S_IDLE;
printf("S_BUSY -> S_IDLE\n");
}
void handle_idle(void *p) {
char cmd;
printf("continue or exit(C/E)?");
CID 358718: Unchecked return value from library (CHECKED_RETURN) [select issue]
scanf("%c", &cmd);
if (cmd == 'c' || cmd == 'C') {
gState = S_BUSY;
printf("S_IDLE -> S_BUSY\n");
} else {
free(p);
printf("S_IDLE -> S_START\n");
printf("exit\n");
exit(0);
}
}
void process(void *p) {
switch (gState) {
case S_START:
handle_idle(p);
handle_start();
break;
case S_BUSY:
handle_busy();
break;
case S_IDLE:
handle_idle(p);
break;
default:
break;
}
}
void test_4(void *p) {
while (1)
{
process(p);
}
}
void test_5(void *pData) {
int kind = 0;
void *ptr = NULL;
printf("input kind:\n");
CID 358724: Unchecked return value from library (CHECKED_RETURN) [select issue]
scanf("%d", &kind);
1. Switch case default.
switch (kind) {
case 1:
ptr = malloc(100);
break;
case 2:
ptr = malloc(200);
break;
default:
2. alloc_fn: Storage is returned from allocation function malloc.
3. var_assign: Assigning: ptr = storage returned from malloc(64UL).
ptr = malloc(64);
4. Breaking from switch.
break;
}
5. Switch case default.
switch(kind) {
case 1:
memcpy(ptr, pData, 1000);
break;
case 2:
memcpy(ptr, pData, 2000);
break;
default:
6. noescape: Resource ptr is not freed or pointed-to in memcpy.
memcpy(ptr, pData, 64);
7. Breaking from switch.
break;
}
8. noescape: Resource (char *)ptr is not freed or pointed-to in printf.
printf("result: %s\n", (char *)ptr);
CID 358723 (#1-3 of 3): Resource leak (RESOURCE_LEAK)
9. leaked_storage: Variable ptr going out of scope leaks the storage it points to.
}
void test_6_sub(void *p) {
if (p == NULL) {
return;
}
free(p);
}
void test_6(void *p) {
test_6_sub(p);
}
int *n() {
return 0;
}
int main(void)
{
// int a;
// printf("input copy length: ");
// scanf("%d",&a);
// printf("copy %d bytes\n",a);
// void *p = malloc(100);
// memcpy(p, (char *)&a, a);
// printf("%s", (char *)&a);
gPtr = malloc(100);
char *p = gPtr;
free(gPtr);
char *name = "adfsasdfasdfasdfasdfasdf";
// test_4(p);
// test_6(p);
return *(n());
}
After analyse by coverity, I just do not get the vulnerability infomation what I want.
According to the introduction of Coverity
should be find the free of Null pointer vulnerability.
should be find the dead code
should be find the function call chains
But I got nothing
Is something wrong?
I got this test result at https://scan.coverity.com
Is the online service has some restrict?
The answer to the question in the title, "Does Coverity support Interprocedural-Analysis", is yes. The Coverity analysis indeed examines how functions call one another in an attempt to discover inconsistencies.
However, there are limitations to the precision of that interprocedural analysis. In particular, although it tries to keep track of relationships involving (at least) parameters, return values, and things pointed to by those, in most cases it cannot track relationships between global variables across function calls. (The reason for that is there are simply too many such variables and too many potential relationships, so trying to track them all would result in the analysis never terminating.)
In your example, there is an intended invariant that gPtr is a valid pointer if and only if gState == S_IDLE. Consequently, the handle_idle() function can only be called when gState == S_IDLE. The process() function violates that requirement by calling handle_idle() while gState == S_START, which (based on the clarification in the comments) is the bug you want to find. That deduction is unfortunately beyond the capabilities of the tool, so it does not report it.
This my cpp code and I am confused because cnt returns x = 0 !
#include <iostream>
using namespace std;
int i;
int cnt () {
for (i = 0; i<15; i++) {
return i;
}
}
int main () {
int x;
x = cnt();
cout << x << endl;
}```
The return function stops every other instruction in the function from being executed and returns the chosen value to the function which called it. Your loop is executed just once.
could please someone code me an example of a "callback inside
callback" or give me some reference about ?
For example to have a sine and an input at the same time.
I tried to use a function inside a callback but there something wrong...
Here is the code:
#include <stdio.h>
#include <math.h>
#include "portaudio.h"
#define NUM_SECONDS (1)
#define SAMPLE_RATE (192000)
#define FRAMES_PER_BUFFER (2048)
#ifndef M_PI
#define M_PI (3.14159265)
#endif
#define TWOPI (2.0 * M_PI)
float freq = 220.0;
float curphase = 0.0;
float FUNZIONE (float a) // CUSTOM FUNCTION
{
return tan(a);
}
typedef struct
{
float (*F)(float); // DECLARATION OF POINTER (TO CUSTOM FUNCTION)
}
paTestData;
F = FUNZIONE; // ASSIGN CUSTOM FUNCTION TO POINTER
// GENERATION OF A SINE
static int patestCallback(const void *inputBuffer,
void *outputBuffer,
unsigned long framesPerBuffer,
const PaStreamCallbackTimeInfo* timeInfo,
PaStreamCallbackFlags statusFlags,
void *userData )
{
paTestData *data = (paTestData*)userData;
float *out = (float*)outputBuffer;
unsigned long i;
(void) timeInfo; /* Prevent unused variable warnings. */
(void) statusFlags;
(void) inputBuffer;
float incr = freq * TWOPI / SAMPLE_RATE;
for( i=0; i<framesPerBuffer; i++ )
{
*out++ = data->F( sin(curphase) ); // USE OF CUSTOM FUNCTION (BY POINTER)
// ON LEFT OUTPUT
*out++ = sin(curphase);
curphase += incr;
if (curphase >= TWOPI){
curphase -= TWOPI;
}
if (curphase < 0.0){
curphase += TWOPI;
}
}
return paContinue;
}
/*******************************************************************/
int main(void)
{
PaStreamParameters outputParameters;
PaStream *stream;
paTestData data;
Pa_Initialize();
outputParameters.device = Pa_GetDefaultOutputDevice();
outputParameters.channelCount = 2;
outputParameters.sampleFormat = paFloat32;
outputParameters.suggestedLatency =
Pa_GetDeviceInfo( outputParameters.device )->defaultLowOutputLatency;
outputParameters.hostApiSpecificStreamInfo = NULL;
Pa_OpenStream(
&stream,
NULL, /* no input */
&outputParameters,
SAMPLE_RATE,
FRAMES_PER_BUFFER,
paClipOff,
patestCallback,
&data );
Pa_StartStream( stream );
Pa_Sleep( NUM_SECONDS * 1000 );
Pa_StopStream( stream );
Pa_CloseStream( stream );
Pa_Terminate();
Pa_Terminate();
return 0;
}
ERROR MESSAGE FROM COMPILER:
||=== Build: Debug in 1 (compiler: GNU GCC Compiler) ===|
C:\Users\1\Desktop\NEW\SINE.c|29|warning: data definition has no type
or storage class|
C:\Users\1\Desktop\NEW\SINE.c|29|warning: type defaults to 'int' in
declaration of 'F' [-Wimplicit-int]|
C:\Users\1\Desktop\NEW\SINE.c|29|warning: initialization makes integer
from pointer without a cast|
C:\Users\1\Desktop\NEW\SINE.c||In function 'patestCallback':|
C:\Users\1\Desktop\NEW\SINE.c|52|error: expected identifier before '*' token|
C:\Users\1\Desktop\NEW\SINE.c|37|warning: variable 'data' set but not
used [-Wunused-but-set-variable]|
||=== Build failed: 1 error(s), 4 warning(s) (0 minute(s), 0 second(s)) ===|
Thanks a lot.
I have a very basic mex file example here:
#include "mex.h"
#include "matrix.h"
void createStructureArray(mxArray* main_array)
{
const char* Title[] = { "first", "second" };
main_array = mxCreateStructMatrix(1,1, 2, Title);
}
void mexFunction(mwSize nlhs, mxArray *plhs[], mwSize nrhs,
const mxArray *prhs[])
{
double* x = mxGetPr(prhs[0]);
if (*x < 1.0)
{
//This works
const char* Title[] = { "first", "second" };
plhs[0] = mxCreateStructMatrix(1,1, 2, Title);
}
else
{
//This does not
createStructureArray(plhs[0]);
}
}
This function should always return a struct with the elements first and second. No matter the input, I expect the same output. However with an input parameter < 1, everything works as expected, but > 1 I get an error message:
>> a = easy_example(0.0)
a =
first: []
second: []
>> a = easy_example(2.0)
One or more output arguments not assigned during call to "easy_example".
Thus, can I not call the mxCreateStructMatrix function outside mexFunction, or did I do something wrong when passing the pointers?
You don't have a problem with mex but with pointers!
Try to change your function to:
void createStructureArray(mxArray** main_array)
{
const char* Title[] = { "first", "second" };
*main_array = mxCreateStructMatrix(1,1, 2, Title);
}
and the function call to
createStructureArray(&plhs[0]);
Your problem is that plhs[0] is a mxArray, but in order to return it, you need to pass the pointer to that mxArray!
I am trying to create a mex function whose entry is an integer and whose output is an array of integer.
So the function looks like: int *myFunction(unsigned int N).
In the mexFunction, I declare a variable *variab of type int and then
N = mxGetScalar(prhs[0]);
/* assign a pointer to the output */
siz= 2*ceil(log(1.0*N)/log(2.0)-0.5)+1;
plhs[0] = mxCreateDoubleMatrix(1,siz, mxREAL);
vari = (int*) mxGetPr(plhs[0]); */
/* Call the subroutine. */
vari = myFunction(N);
mexPrintf("The first value is %d\n", vari[0]);
The thing is the first value is the correct one (and the other ones were checked and were correct as well) but when I call the routine mxFunction(16), I get only 0's as output.
I guess it is because my output is an array of int but I don't know how to solve the problem. Any hint?
Cheers.
Matlab deals with doubles by default. You can easily cast them in your mex function like the following example based on your code snippet. I have made a myFunction that performs a demo algorithm. Rather than return a data type, I make it a void function and pass it a pointer to the output so that it can populate it . . .
/*************************************************************************/
/* Header(s) */
/*************************************************************************/
#include "mex.h"
#include "math.h"
/*************************************************************************/
/*the fabled myFunction */
/*************************************************************************/
void myFunction(unsigned int N, unsigned int siz, double* output)
{
int sign = 1;
for(int ii=0; ii<siz; ++ii)
{
output[ii] = (double)(ii * sign + N);
sign *= -1;
}
}
/*************************************************************************/
/* Gateway function and error checking */
/*************************************************************************/
void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[])
{
/* variable declarations */
unsigned int siz;
double N;
/* check the number of input and output parameters */
if(nrhs!=1)
mexErrMsgTxt("One input arg expected");
if(nlhs > 1)
mexErrMsgTxt("Too many outputs");
N = mxGetScalar(prhs[0]);
/* assign a pointer to the output */
siz= 2*ceil(log(1.0*N)/log(2.0)-0.5)+1;
plhs[0] = mxCreateDoubleMatrix(1,siz, mxREAL);
myFunction(N, siz, mxGetPr( plhs[0]) );
}