According to C99 Section 7.19.9.3 it is undefined behavior when:
The fsetpos function is called to set a position that was not returned by a previous successful call to the fgetpos function on a stream associated with the same file.
Non-Compliant Code Example
By using an integer j instead of fpos_t returned from a call to fgetpos(), fgetpos()}}will go to the jth character in the stream. However, on other implementations or systems this call may crash or move the next read to a random location within the file. Also, files from other implementations that have stored {{fpos_t in the file may no longer be accurate in the current system.
#include <stdio.h>
int main(void) {
FILE *info = fopen( "widget.txt", "r");
int a,b,c;
if(info == NULL){
perror("Could not open file");
return 0;
}
if (fscanf(info,"%i %i %i", &a, &b, &c)!=3) {
fprintf(stderr, "Expected but did not find three integers \n");
fclose(info);
return 0;
}
else {
printf("abc is %i%i%i\n", a, b, c);
}
int j=0;
if (fsetpos(info, &j)!=0) {
perror("fsetpos failed");
fclose(info);
return 0;
}
if (fscanf(info,"%i %i %i", &a, &b, &c)!=3) {
fprintf(stderr, "Expected but did not find %i %i %i \n");
}
else {
printf("abc is %i%i%i \n",a,b,c);
}
fclose(info);
return 0;
}
}
Compliant Solution
int main(void) {
FILE *info = fopen("widget.txt", "r");
fpos_t pos;
int a,b,c;
if (info == NULL) {
perror("Could not open file");
return 0;
}
if (fgetpos(info, &pos)\!=0) {
perror("fgetpos failed");
fclose(info);
return 0;
}
if (fscanf(info,"%i %i %i", &a, &b, &c) != 3) {
fprintf(stderr, "Expected but did not find three integers \n");
fclose(info);
return 0;
}
else {
printf("abc is %i%i%i\n", a, b, c);
}
if (fsetpos(info, &pos) != 0) {
perror("fsetpos failed");
fclose(info);
return 0;
}
if (fscanf(info,"%i %i %i", &a, &b, &c) != 3) {
fprintf(stderr, "Expected but did not find %i %i %i \n");
}
else {
printf("abc is %i%i%i \n",a,b,c);
}
fclose(info);
return 0;
}
Risk Assessment
The misuse of fsetpos() could move a file stream read to a undesired location in the file. If this location held input from user the user would then gain control of the variables being read from the file. (7.19.9.3).
Rule |
Severity |
Likelihood |
Remediation Cost |
Priority |
Level |
|---|---|---|---|---|---|
DRAFT |
2 (medium) |
1(low) |
1(low) |
P2 |
L3 |
References
ISO/IEC 9899 (7.19.9.3)